mirror of
https://abf.rosa.ru/djam/pcre2.git
synced 2025-02-23 19:12:55 +00:00
Security fixed CVE-2022-1586 CVE-2022-1587
This commit is contained in:
parent
ce68663163
commit
04ecbb8ba1
3 changed files with 652 additions and 2 deletions
|
@ -9,14 +9,16 @@
|
||||||
Summary: Perl-compatible regular expression library
|
Summary: Perl-compatible regular expression library
|
||||||
Name: pcre2
|
Name: pcre2
|
||||||
Version: 10.36
|
Version: 10.36
|
||||||
Release: 2
|
Release: 3
|
||||||
License: BSD
|
License: BSD
|
||||||
Group: System/Libraries
|
Group: System/Libraries
|
||||||
Url: http://www.pcre.org/
|
Url: http://www.pcre.org/
|
||||||
Source0: https://github.com/PhilipHazel/pcre2/releases/download/%{name}-%{version}/%{name}-%{version}.tar.bz2
|
Source0: https://github.com/PhilipHazel/pcre2/releases/download/%{name}-%{version}/%{name}-%{version}.tar.bz2
|
||||||
# Do no set RPATH if libdir is not /usr/lib
|
# Do no set RPATH if libdir is not /usr/lib
|
||||||
Patch0: pcre2-10.10-Fix-multilib.patch
|
Patch0: pcre2-10.10-Fix-multilib.patch
|
||||||
|
# CVE-2022-1586 CVE-2022-1587
|
||||||
|
Patch1: pcre2_jit_compile.c.diff
|
||||||
|
Patch2: pcre2_jit_test.c.diff
|
||||||
BuildRequires: readline-devel
|
BuildRequires: readline-devel
|
||||||
|
|
||||||
%description
|
%description
|
||||||
|
@ -168,3 +170,6 @@ rm -rf %{buildroot}%{_docdir}/pcre2
|
||||||
|
|
||||||
%check
|
%check
|
||||||
make check VERBOSE=yes
|
make check VERBOSE=yes
|
||||||
|
|
||||||
|
|
||||||
|
# CVE-2016-3191 CVE-2017-8399 CVE-2017-8786
|
||||||
|
|
625
pcre2_jit_compile.c.diff
Normal file
625
pcre2_jit_compile.c.diff
Normal file
|
@ -0,0 +1,625 @@
|
||||||
|
--- pcre2-10.36.orig/src/pcre2_jit_compile.c
|
||||||
|
+++ pcre2-10.36/src/pcre2_jit_compile.c
|
||||||
|
@@ -413,6 +413,9 @@
|
||||||
|
/* Locals used by fast fail optimization. */
|
||||||
|
sljit_s32 early_fail_start_ptr;
|
||||||
|
sljit_s32 early_fail_end_ptr;
|
||||||
|
+ /* Variables used by recursive call generator. */
|
||||||
|
+ sljit_s32 recurse_bitset_size;
|
||||||
|
+ uint8_t *recurse_bitset;
|
||||||
|
|
||||||
|
/* Flipped and lower case tables. */
|
||||||
|
const sljit_u8 *fcc;
|
||||||
|
@@ -2316,19 +2319,39 @@
|
||||||
|
|
||||||
|
#undef RECURSE_TMP_REG_COUNT
|
||||||
|
|
||||||
|
+static BOOL recurse_check_bit(compiler_common *common, sljit_sw bit_index)
|
||||||
|
+{
|
||||||
|
+uint8_t *byte;
|
||||||
|
+uint8_t mask;
|
||||||
|
+
|
||||||
|
+SLJIT_ASSERT((bit_index & (sizeof(sljit_sw) - 1)) == 0);
|
||||||
|
+
|
||||||
|
+bit_index >>= SLJIT_WORD_SHIFT;
|
||||||
|
+
|
||||||
|
+mask = 1 << (bit_index & 0x7);
|
||||||
|
+byte = common->recurse_bitset + (bit_index >> 3);
|
||||||
|
+
|
||||||
|
+if (*byte & mask)
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
+*byte |= mask;
|
||||||
|
+return TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int get_recurse_data_length(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend,
|
||||||
|
BOOL *needs_control_head, BOOL *has_quit, BOOL *has_accept)
|
||||||
|
{
|
||||||
|
int length = 1;
|
||||||
|
-int size;
|
||||||
|
+int size, offset;
|
||||||
|
PCRE2_SPTR alternative;
|
||||||
|
BOOL quit_found = FALSE;
|
||||||
|
BOOL accept_found = FALSE;
|
||||||
|
BOOL setsom_found = FALSE;
|
||||||
|
BOOL setmark_found = FALSE;
|
||||||
|
-BOOL capture_last_found = FALSE;
|
||||||
|
BOOL control_head_found = FALSE;
|
||||||
|
|
||||||
|
+memset(common->recurse_bitset, 0, common->recurse_bitset_size);
|
||||||
|
+
|
||||||
|
#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
|
||||||
|
SLJIT_ASSERT(common->control_head_ptr != 0);
|
||||||
|
control_head_found = TRUE;
|
||||||
|
@@ -2351,15 +2374,17 @@
|
||||||
|
setsom_found = TRUE;
|
||||||
|
if (common->mark_ptr != 0)
|
||||||
|
setmark_found = TRUE;
|
||||||
|
- if (common->capture_last_ptr != 0)
|
||||||
|
- capture_last_found = TRUE;
|
||||||
|
+ if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
|
||||||
|
+ length++;
|
||||||
|
cc += 1 + LINK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_KET:
|
||||||
|
- if (PRIVATE_DATA(cc) != 0)
|
||||||
|
+ offset = PRIVATE_DATA(cc);
|
||||||
|
+ if (offset != 0)
|
||||||
|
{
|
||||||
|
- length++;
|
||||||
|
+ if (recurse_check_bit(common, offset))
|
||||||
|
+ length++;
|
||||||
|
SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
|
||||||
|
cc += PRIVATE_DATA(cc + 1);
|
||||||
|
}
|
||||||
|
@@ -2378,39 +2403,55 @@
|
||||||
|
case OP_SBRA:
|
||||||
|
case OP_SBRAPOS:
|
||||||
|
case OP_SCOND:
|
||||||
|
- length++;
|
||||||
|
SLJIT_ASSERT(PRIVATE_DATA(cc) != 0);
|
||||||
|
+ if (recurse_check_bit(common, PRIVATE_DATA(cc)))
|
||||||
|
+ length++;
|
||||||
|
cc += 1 + LINK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_CBRA:
|
||||||
|
case OP_SCBRA:
|
||||||
|
- length += 2;
|
||||||
|
- if (common->capture_last_ptr != 0)
|
||||||
|
- capture_last_found = TRUE;
|
||||||
|
- if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
|
||||||
|
+ offset = GET2(cc, 1 + LINK_SIZE);
|
||||||
|
+ if (recurse_check_bit(common, OVECTOR(offset << 1)))
|
||||||
|
+ {
|
||||||
|
+ SLJIT_ASSERT(recurse_check_bit(common, OVECTOR((offset << 1) + 1)));
|
||||||
|
+ length += 2;
|
||||||
|
+ }
|
||||||
|
+ if (common->optimized_cbracket[offset] == 0 && recurse_check_bit(common, OVECTOR_PRIV(offset)))
|
||||||
|
+ length++;
|
||||||
|
+ if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
|
||||||
|
length++;
|
||||||
|
cc += 1 + LINK_SIZE + IMM2_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_CBRAPOS:
|
||||||
|
case OP_SCBRAPOS:
|
||||||
|
- length += 2 + 2;
|
||||||
|
- if (common->capture_last_ptr != 0)
|
||||||
|
- capture_last_found = TRUE;
|
||||||
|
+ offset = GET2(cc, 1 + LINK_SIZE);
|
||||||
|
+ if (recurse_check_bit(common, OVECTOR(offset << 1)))
|
||||||
|
+ {
|
||||||
|
+ SLJIT_ASSERT(recurse_check_bit(common, OVECTOR((offset << 1) + 1)));
|
||||||
|
+ length += 2;
|
||||||
|
+ }
|
||||||
|
+ if (recurse_check_bit(common, OVECTOR_PRIV(offset)))
|
||||||
|
+ length++;
|
||||||
|
+ if (recurse_check_bit(common, PRIVATE_DATA(cc)))
|
||||||
|
+ length++;
|
||||||
|
+ if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
|
||||||
|
+ length++;
|
||||||
|
cc += 1 + LINK_SIZE + IMM2_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COND:
|
||||||
|
/* Might be a hidden SCOND. */
|
||||||
|
alternative = cc + GET(cc, 1);
|
||||||
|
- if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
|
||||||
|
+ if ((*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) && recurse_check_bit(common, PRIVATE_DATA(cc)))
|
||||||
|
length++;
|
||||||
|
cc += 1 + LINK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE_ITERATOR_PRIVATE_DATA_1
|
||||||
|
- if (PRIVATE_DATA(cc) != 0)
|
||||||
|
+ offset = PRIVATE_DATA(cc);
|
||||||
|
+ if (offset != 0 && recurse_check_bit(common, offset))
|
||||||
|
length++;
|
||||||
|
cc += 2;
|
||||||
|
#ifdef SUPPORT_UNICODE
|
||||||
|
@@ -2419,8 +2460,12 @@
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE_ITERATOR_PRIVATE_DATA_2A
|
||||||
|
- if (PRIVATE_DATA(cc) != 0)
|
||||||
|
+ offset = PRIVATE_DATA(cc);
|
||||||
|
+ if (offset != 0 && recurse_check_bit(common, offset))
|
||||||
|
+ {
|
||||||
|
+ SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));
|
||||||
|
length += 2;
|
||||||
|
+ }
|
||||||
|
cc += 2;
|
||||||
|
#ifdef SUPPORT_UNICODE
|
||||||
|
if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
|
||||||
|
@@ -2428,8 +2473,12 @@
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE_ITERATOR_PRIVATE_DATA_2B
|
||||||
|
- if (PRIVATE_DATA(cc) != 0)
|
||||||
|
+ offset = PRIVATE_DATA(cc);
|
||||||
|
+ if (offset != 0 && recurse_check_bit(common, offset))
|
||||||
|
+ {
|
||||||
|
+ SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));
|
||||||
|
length += 2;
|
||||||
|
+ }
|
||||||
|
cc += 2 + IMM2_SIZE;
|
||||||
|
#ifdef SUPPORT_UNICODE
|
||||||
|
if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
|
||||||
|
@@ -2437,20 +2486,29 @@
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE_ITERATOR_TYPE_PRIVATE_DATA_1
|
||||||
|
- if (PRIVATE_DATA(cc) != 0)
|
||||||
|
+ offset = PRIVATE_DATA(cc);
|
||||||
|
+ if (offset != 0 && recurse_check_bit(common, offset))
|
||||||
|
length++;
|
||||||
|
cc += 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
|
||||||
|
- if (PRIVATE_DATA(cc) != 0)
|
||||||
|
+ offset = PRIVATE_DATA(cc);
|
||||||
|
+ if (offset != 0 && recurse_check_bit(common, offset))
|
||||||
|
+ {
|
||||||
|
+ SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));
|
||||||
|
length += 2;
|
||||||
|
+ }
|
||||||
|
cc += 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
|
||||||
|
- if (PRIVATE_DATA(cc) != 0)
|
||||||
|
+ offset = PRIVATE_DATA(cc);
|
||||||
|
+ if (offset != 0 && recurse_check_bit(common, offset))
|
||||||
|
+ {
|
||||||
|
+ SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));
|
||||||
|
length += 2;
|
||||||
|
+ }
|
||||||
|
cc += 1 + IMM2_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -2462,7 +2520,9 @@
|
||||||
|
#else
|
||||||
|
size = 1 + 32 / (int)sizeof(PCRE2_UCHAR);
|
||||||
|
#endif
|
||||||
|
- if (PRIVATE_DATA(cc) != 0)
|
||||||
|
+
|
||||||
|
+ offset = PRIVATE_DATA(cc);
|
||||||
|
+ if (offset != 0 && recurse_check_bit(common, offset))
|
||||||
|
length += get_class_iterator_size(cc + size);
|
||||||
|
cc += size;
|
||||||
|
break;
|
||||||
|
@@ -2497,8 +2557,7 @@
|
||||||
|
case OP_THEN:
|
||||||
|
SLJIT_ASSERT(common->control_head_ptr != 0);
|
||||||
|
quit_found = TRUE;
|
||||||
|
- if (!control_head_found)
|
||||||
|
- control_head_found = TRUE;
|
||||||
|
+ control_head_found = TRUE;
|
||||||
|
cc++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -2518,8 +2577,6 @@
|
||||||
|
|
||||||
|
if (control_head_found)
|
||||||
|
length++;
|
||||||
|
-if (capture_last_found)
|
||||||
|
- length++;
|
||||||
|
if (quit_found)
|
||||||
|
{
|
||||||
|
if (setsom_found)
|
||||||
|
@@ -2552,14 +2609,12 @@
|
||||||
|
sljit_sw kept_shared_srcw[2];
|
||||||
|
int private_count, shared_count, kept_shared_count;
|
||||||
|
int from_sp, base_reg, offset, i;
|
||||||
|
-BOOL setsom_found = FALSE;
|
||||||
|
-BOOL setmark_found = FALSE;
|
||||||
|
-BOOL capture_last_found = FALSE;
|
||||||
|
-BOOL control_head_found = FALSE;
|
||||||
|
+
|
||||||
|
+memset(common->recurse_bitset, 0, common->recurse_bitset_size);
|
||||||
|
|
||||||
|
#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
|
||||||
|
SLJIT_ASSERT(common->control_head_ptr != 0);
|
||||||
|
-control_head_found = TRUE;
|
||||||
|
+recurse_check_bit(common, common->control_head_ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
@@ -2647,11 +2702,10 @@
|
||||||
|
{
|
||||||
|
case OP_SET_SOM:
|
||||||
|
SLJIT_ASSERT(common->has_set_som);
|
||||||
|
- if (has_quit && !setsom_found)
|
||||||
|
+ if (has_quit && recurse_check_bit(common, OVECTOR(0)))
|
||||||
|
{
|
||||||
|
kept_shared_srcw[0] = OVECTOR(0);
|
||||||
|
kept_shared_count = 1;
|
||||||
|
- setsom_found = TRUE;
|
||||||
|
}
|
||||||
|
cc += 1;
|
||||||
|
break;
|
||||||
|
@@ -2659,33 +2713,31 @@
|
||||||
|
case OP_RECURSE:
|
||||||
|
if (has_quit)
|
||||||
|
{
|
||||||
|
- if (common->has_set_som && !setsom_found)
|
||||||
|
+ if (common->has_set_som && recurse_check_bit(common, OVECTOR(0)))
|
||||||
|
{
|
||||||
|
kept_shared_srcw[0] = OVECTOR(0);
|
||||||
|
kept_shared_count = 1;
|
||||||
|
- setsom_found = TRUE;
|
||||||
|
}
|
||||||
|
- if (common->mark_ptr != 0 && !setmark_found)
|
||||||
|
+ if (common->mark_ptr != 0 && recurse_check_bit(common, common->mark_ptr))
|
||||||
|
{
|
||||||
|
kept_shared_srcw[kept_shared_count] = common->mark_ptr;
|
||||||
|
kept_shared_count++;
|
||||||
|
- setmark_found = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- if (common->capture_last_ptr != 0 && !capture_last_found)
|
||||||
|
+ if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
|
||||||
|
{
|
||||||
|
shared_srcw[0] = common->capture_last_ptr;
|
||||||
|
shared_count = 1;
|
||||||
|
- capture_last_found = TRUE;
|
||||||
|
}
|
||||||
|
cc += 1 + LINK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_KET:
|
||||||
|
- if (PRIVATE_DATA(cc) != 0)
|
||||||
|
+ private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
+ if (private_srcw[0] != 0)
|
||||||
|
{
|
||||||
|
- private_count = 1;
|
||||||
|
- private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
+ if (recurse_check_bit(common, private_srcw[0]))
|
||||||
|
+ private_count = 1;
|
||||||
|
SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
|
||||||
|
cc += PRIVATE_DATA(cc + 1);
|
||||||
|
}
|
||||||
|
@@ -2704,50 +2756,66 @@
|
||||||
|
case OP_SBRA:
|
||||||
|
case OP_SBRAPOS:
|
||||||
|
case OP_SCOND:
|
||||||
|
- private_count = 1;
|
||||||
|
private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
+ if (recurse_check_bit(common, private_srcw[0]))
|
||||||
|
+ private_count = 1;
|
||||||
|
cc += 1 + LINK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_CBRA:
|
||||||
|
case OP_SCBRA:
|
||||||
|
- offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
|
||||||
|
- shared_srcw[0] = OVECTOR(offset);
|
||||||
|
- shared_srcw[1] = OVECTOR(offset + 1);
|
||||||
|
- shared_count = 2;
|
||||||
|
+ offset = GET2(cc, 1 + LINK_SIZE);
|
||||||
|
+ shared_srcw[0] = OVECTOR(offset << 1);
|
||||||
|
+ if (recurse_check_bit(common, shared_srcw[0]))
|
||||||
|
+ {
|
||||||
|
+ shared_srcw[1] = shared_srcw[0] + sizeof(sljit_sw);
|
||||||
|
+ SLJIT_ASSERT(recurse_check_bit(common, shared_srcw[1]));
|
||||||
|
+ shared_count = 2;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (common->capture_last_ptr != 0 && !capture_last_found)
|
||||||
|
+ if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
|
||||||
|
{
|
||||||
|
- shared_srcw[2] = common->capture_last_ptr;
|
||||||
|
- shared_count = 3;
|
||||||
|
- capture_last_found = TRUE;
|
||||||
|
+ shared_srcw[shared_count] = common->capture_last_ptr;
|
||||||
|
+ shared_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
|
||||||
|
+ if (common->optimized_cbracket[offset] == 0)
|
||||||
|
{
|
||||||
|
- private_count = 1;
|
||||||
|
- private_srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
|
||||||
|
+ private_srcw[0] = OVECTOR_PRIV(offset);
|
||||||
|
+ if (recurse_check_bit(common, private_srcw[0]))
|
||||||
|
+ private_count = 1;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
cc += 1 + LINK_SIZE + IMM2_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_CBRAPOS:
|
||||||
|
case OP_SCBRAPOS:
|
||||||
|
- offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
|
||||||
|
- shared_srcw[0] = OVECTOR(offset);
|
||||||
|
- shared_srcw[1] = OVECTOR(offset + 1);
|
||||||
|
- shared_count = 2;
|
||||||
|
+ offset = GET2(cc, 1 + LINK_SIZE);
|
||||||
|
+ shared_srcw[0] = OVECTOR(offset << 1);
|
||||||
|
+ if (recurse_check_bit(common, shared_srcw[0]))
|
||||||
|
+ {
|
||||||
|
+ shared_srcw[1] = shared_srcw[0] + sizeof(sljit_sw);
|
||||||
|
+ SLJIT_ASSERT(recurse_check_bit(common, shared_srcw[1]));
|
||||||
|
+ shared_count = 2;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (common->capture_last_ptr != 0 && !capture_last_found)
|
||||||
|
+ if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
|
||||||
|
{
|
||||||
|
- shared_srcw[2] = common->capture_last_ptr;
|
||||||
|
- shared_count = 3;
|
||||||
|
- capture_last_found = TRUE;
|
||||||
|
+ shared_srcw[shared_count] = common->capture_last_ptr;
|
||||||
|
+ shared_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
- private_count = 2;
|
||||||
|
private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
- private_srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
|
||||||
|
+ if (recurse_check_bit(common, private_srcw[0]))
|
||||||
|
+ private_count = 1;
|
||||||
|
+
|
||||||
|
+ offset = OVECTOR_PRIV(offset);
|
||||||
|
+ if (recurse_check_bit(common, offset))
|
||||||
|
+ {
|
||||||
|
+ private_srcw[private_count] = offset;
|
||||||
|
+ private_count++;
|
||||||
|
+ }
|
||||||
|
cc += 1 + LINK_SIZE + IMM2_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -2756,18 +2824,17 @@
|
||||||
|
alternative = cc + GET(cc, 1);
|
||||||
|
if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
|
||||||
|
{
|
||||||
|
- private_count = 1;
|
||||||
|
private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
+ if (recurse_check_bit(common, private_srcw[0]))
|
||||||
|
+ private_count = 1;
|
||||||
|
}
|
||||||
|
cc += 1 + LINK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE_ITERATOR_PRIVATE_DATA_1
|
||||||
|
- if (PRIVATE_DATA(cc))
|
||||||
|
- {
|
||||||
|
+ private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
+ if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
|
||||||
|
private_count = 1;
|
||||||
|
- private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
- }
|
||||||
|
cc += 2;
|
||||||
|
#ifdef SUPPORT_UNICODE
|
||||||
|
if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
|
||||||
|
@@ -2775,11 +2842,12 @@
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE_ITERATOR_PRIVATE_DATA_2A
|
||||||
|
- if (PRIVATE_DATA(cc))
|
||||||
|
+ private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
+ if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
|
||||||
|
{
|
||||||
|
private_count = 2;
|
||||||
|
- private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
- private_srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
|
||||||
|
+ private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
|
||||||
|
+ SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
|
||||||
|
}
|
||||||
|
cc += 2;
|
||||||
|
#ifdef SUPPORT_UNICODE
|
||||||
|
@@ -2788,11 +2856,12 @@
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE_ITERATOR_PRIVATE_DATA_2B
|
||||||
|
- if (PRIVATE_DATA(cc))
|
||||||
|
+ private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
+ if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
|
||||||
|
{
|
||||||
|
private_count = 2;
|
||||||
|
- private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
- private_srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
|
||||||
|
+ private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
|
||||||
|
+ SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
|
||||||
|
}
|
||||||
|
cc += 2 + IMM2_SIZE;
|
||||||
|
#ifdef SUPPORT_UNICODE
|
||||||
|
@@ -2801,30 +2870,30 @@
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE_ITERATOR_TYPE_PRIVATE_DATA_1
|
||||||
|
- if (PRIVATE_DATA(cc))
|
||||||
|
- {
|
||||||
|
+ private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
+ if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
|
||||||
|
private_count = 1;
|
||||||
|
- private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
- }
|
||||||
|
cc += 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
|
||||||
|
- if (PRIVATE_DATA(cc))
|
||||||
|
+ private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
+ if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
|
||||||
|
{
|
||||||
|
private_count = 2;
|
||||||
|
- private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
|
||||||
|
+ SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
|
||||||
|
}
|
||||||
|
cc += 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
|
||||||
|
- if (PRIVATE_DATA(cc))
|
||||||
|
+ private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
+ if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
|
||||||
|
{
|
||||||
|
private_count = 2;
|
||||||
|
- private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
|
||||||
|
+ SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
|
||||||
|
}
|
||||||
|
cc += 1 + IMM2_SIZE;
|
||||||
|
break;
|
||||||
|
@@ -2841,14 +2910,17 @@
|
||||||
|
switch(get_class_iterator_size(cc + i))
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
- private_count = 1;
|
||||||
|
private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
- private_count = 2;
|
||||||
|
private_srcw[0] = PRIVATE_DATA(cc);
|
||||||
|
- private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
|
||||||
|
+ if (recurse_check_bit(common, private_srcw[0]))
|
||||||
|
+ {
|
||||||
|
+ private_count = 2;
|
||||||
|
+ private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
|
||||||
|
+ SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
|
||||||
|
+ }
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
@@ -2863,28 +2935,25 @@
|
||||||
|
case OP_PRUNE_ARG:
|
||||||
|
case OP_THEN_ARG:
|
||||||
|
SLJIT_ASSERT(common->mark_ptr != 0);
|
||||||
|
- if (has_quit && !setmark_found)
|
||||||
|
+ if (has_quit && recurse_check_bit(common, common->mark_ptr))
|
||||||
|
{
|
||||||
|
kept_shared_srcw[0] = common->mark_ptr;
|
||||||
|
kept_shared_count = 1;
|
||||||
|
- setmark_found = TRUE;
|
||||||
|
}
|
||||||
|
- if (common->control_head_ptr != 0 && !control_head_found)
|
||||||
|
+ if (common->control_head_ptr != 0 && recurse_check_bit(common, common->control_head_ptr))
|
||||||
|
{
|
||||||
|
private_srcw[0] = common->control_head_ptr;
|
||||||
|
private_count = 1;
|
||||||
|
- control_head_found = TRUE;
|
||||||
|
}
|
||||||
|
cc += 1 + 2 + cc[1];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_THEN:
|
||||||
|
SLJIT_ASSERT(common->control_head_ptr != 0);
|
||||||
|
- if (!control_head_found)
|
||||||
|
+ if (recurse_check_bit(common, common->control_head_ptr))
|
||||||
|
{
|
||||||
|
private_srcw[0] = common->control_head_ptr;
|
||||||
|
private_count = 1;
|
||||||
|
- control_head_found = TRUE;
|
||||||
|
}
|
||||||
|
cc++;
|
||||||
|
break;
|
||||||
|
@@ -2892,7 +2961,7 @@
|
||||||
|
default:
|
||||||
|
cc = next_opcode(common, cc);
|
||||||
|
SLJIT_ASSERT(cc != NULL);
|
||||||
|
- break;
|
||||||
|
+ continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != recurse_copy_shared_to_global && type != recurse_copy_kept_shared_to_global)
|
||||||
|
@@ -7473,7 +7542,7 @@
|
||||||
|
{
|
||||||
|
SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
|
||||||
|
cc++;
|
||||||
|
- if (*cc == PT_CLIST)
|
||||||
|
+ if (*cc == PT_CLIST && cc[-1] == XCL_PROP)
|
||||||
|
{
|
||||||
|
other_cases = PRIV(ucd_caseless_sets) + cc[1];
|
||||||
|
while (*other_cases != NOTACHAR)
|
||||||
|
@@ -13652,7 +13721,7 @@
|
||||||
|
common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
|
||||||
|
|
||||||
|
total_length = ccend - common->start;
|
||||||
|
-common->private_data_ptrs = (sljit_s32 *)SLJIT_MALLOC(total_length * (sizeof(sljit_s32) + (common->has_then ? 1 : 0)), allocator_data);
|
||||||
|
+common->private_data_ptrs = (sljit_s32*)SLJIT_MALLOC(total_length * (sizeof(sljit_s32) + (common->has_then ? 1 : 0)), allocator_data);
|
||||||
|
if (!common->private_data_ptrs)
|
||||||
|
{
|
||||||
|
SLJIT_FREE(common->optimized_cbracket, allocator_data);
|
||||||
|
@@ -13690,7 +13759,8 @@
|
||||||
|
}
|
||||||
|
common->compiler = compiler;
|
||||||
|
|
||||||
|
-/* Main pcre_jit_exec entry. */
|
||||||
|
+/* Main pcre2_jit_exec entry. */
|
||||||
|
+SLJIT_ASSERT((private_data_size & (sizeof(sljit_sw) - 1)) == 0);
|
||||||
|
sljit_emit_enter(compiler, 0, SLJIT_ARG1(SW), 5, 5, 0, 0, private_data_size);
|
||||||
|
|
||||||
|
/* Register init. */
|
||||||
|
@@ -13913,20 +13983,40 @@
|
||||||
|
common->currententry = common->entries;
|
||||||
|
common->local_quit_available = TRUE;
|
||||||
|
quit_label = common->quit_label;
|
||||||
|
-while (common->currententry != NULL)
|
||||||
|
+if (common->currententry != NULL)
|
||||||
|
{
|
||||||
|
- /* Might add new entries. */
|
||||||
|
- compile_recurse(common);
|
||||||
|
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
|
||||||
|
+ /* A free bit for each private data. */
|
||||||
|
+ common->recurse_bitset_size = ((private_data_size / (int)sizeof(sljit_sw)) + 7) >> 3;
|
||||||
|
+ SLJIT_ASSERT(common->recurse_bitset_size > 0);
|
||||||
|
+ common->recurse_bitset = (sljit_u8*)SLJIT_MALLOC(common->recurse_bitset_size, allocator_data);;
|
||||||
|
+
|
||||||
|
+ if (common->recurse_bitset != NULL)
|
||||||
|
+ {
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ /* Might add new entries. */
|
||||||
|
+ compile_recurse(common);
|
||||||
|
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
|
||||||
|
+ break;
|
||||||
|
+ flush_stubs(common);
|
||||||
|
+ common->currententry = common->currententry->next;
|
||||||
|
+ }
|
||||||
|
+ while (common->currententry != NULL);
|
||||||
|
+
|
||||||
|
+ SLJIT_FREE(common->recurse_bitset, allocator_data);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (common->currententry != NULL)
|
||||||
|
{
|
||||||
|
+ /* The common->recurse_bitset has been freed. */
|
||||||
|
+ SLJIT_ASSERT(sljit_get_compiler_error(compiler) || common->recurse_bitset == NULL);
|
||||||
|
+
|
||||||
|
sljit_free_compiler(compiler);
|
||||||
|
SLJIT_FREE(common->optimized_cbracket, allocator_data);
|
||||||
|
SLJIT_FREE(common->private_data_ptrs, allocator_data);
|
||||||
|
PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
|
||||||
|
return PCRE2_ERROR_NOMEMORY;
|
||||||
|
}
|
||||||
|
- flush_stubs(common);
|
||||||
|
- common->currententry = common->currententry->next;
|
||||||
|
}
|
||||||
|
common->local_quit_available = FALSE;
|
||||||
|
common->quit_label = quit_label;
|
20
pcre2_jit_test.c.diff
Normal file
20
pcre2_jit_test.c.diff
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
--- pcre2-10.36.orig/src/pcre2_jit_test.c
|
||||||
|
+++ pcre2-10.36/src/pcre2_jit_test.c
|
||||||
|
@@ -410,6 +410,9 @@
|
||||||
|
{ MUP, A, 0, 0 | F_PROPERTY, "[\\P{L&}]{2}[^\xc2\x85-\xc2\x89\\p{Ll}\\p{Lu}]{2}", "\xc3\xa9\xe6\x92\xad.a\xe6\x92\xad|\xc2\x8a#" },
|
||||||
|
{ PCRE2_UCP, 0, 0, 0 | F_PROPERTY, "[a-b\\s]{2,5}[^a]", "AB baaa" },
|
||||||
|
{ MUP, 0, 0, 0 | F_NOMATCH, "[^\\p{Hangul}\\p{Z}]", " " },
|
||||||
|
+ { MUP, 0, 0, 0, "[\\p{Lu}\\P{Latin}]+", "c\xEA\xA4\xAE,A,b" },
|
||||||
|
+ { MUP, 0, 0, 0, "[\\x{a92e}\\p{Lu}\\P{Latin}]+", "c\xEA\xA4\xAE,A,b" },
|
||||||
|
+ { CMUP, 0, 0, 0, "[^S]\\B", "\xe2\x80\x8a" },
|
||||||
|
|
||||||
|
/* Possible empty brackets. */
|
||||||
|
{ MU, A, 0, 0, "(?:|ab||bc|a)+d", "abcxabcabd" },
|
||||||
|
@@ -745,6 +748,7 @@
|
||||||
|
{ MU, A, 0, 0, "((?(R)a|(?1)){1,3}?)M", "aaaM" },
|
||||||
|
{ MU, A, 0, 0, "((.)(?:.|\\2(?1))){0}#(?1)#", "#aabbccdde# #aabbccddee#" },
|
||||||
|
{ MU, A, 0, 0, "((.)(?:\\2|\\2{4}b)){0}#(?:(?1))+#", "#aaaab# #aaaaab#" },
|
||||||
|
+ { MU, A, 0, 0 | F_NOMATCH, "(?1)$((.|\\2xx){1,2})", "abc" },
|
||||||
|
|
||||||
|
/* 16 bit specific tests. */
|
||||||
|
{ CM, A, 0, 0 | F_FORCECONV, "\xc3\xa1", "\xc3\x81\xc3\xa1" },
|
Loading…
Add table
Reference in a new issue