!31 update to 10.40
From: @dillon_chen Reviewed-by: @overweight Signed-off-by: @overweight
This commit is contained in:
commit
157001352a
@ -1,53 +0,0 @@
|
|||||||
From 50a51cb7e67268e6ad417eb07c9de9bfea5cc55a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zoltan Herczeg <hzmester@freemail.hu>
|
|
||||||
Date: Wed, 23 Mar 2022 07:53:25 +0000
|
|
||||||
Subject: [PATCH] Fixed a unicode properrty matching issue in JIT
|
|
||||||
|
|
||||||
---
|
|
||||||
ChangeLog | 3 +++
|
|
||||||
src/pcre2_jit_compile.c | 2 +-
|
|
||||||
src/pcre2_jit_test.c | 1 +
|
|
||||||
3 files changed, 5 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/ChangeLog b/ChangeLog
|
|
||||||
index d27542d..cd3da65 100644
|
|
||||||
--- a/ChangeLog
|
|
||||||
+++ b/ChangeLog
|
|
||||||
@@ -63,6 +63,9 @@ Version 10.39 29-October-2021
|
|
||||||
|
|
||||||
Reformat slightly to make it C89 compatible again.
|
|
||||||
|
|
||||||
+23. Fixed a unicode properrty matching issue in JIT. The character was not
|
|
||||||
+fully read in caseless matching.
|
|
||||||
+
|
|
||||||
|
|
||||||
Version 10.38 01-October-2021
|
|
||||||
-----------------------------
|
|
||||||
diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c
|
|
||||||
index db2ce65..5baca9b 100644
|
|
||||||
--- a/src/pcre2_jit_compile.c
|
|
||||||
+++ b/src/pcre2_jit_compile.c
|
|
||||||
@@ -7473,7 +7473,7 @@ while (*cc != XCL_END)
|
|
||||||
{
|
|
||||||
SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
|
|
||||||
cc++;
|
|
||||||
- if (*cc == PT_CLIST)
|
|
||||||
+ if (*cc == PT_CLIST && *cc == XCL_PROP)
|
|
||||||
{
|
|
||||||
other_cases = PRIV(ucd_caseless_sets) + cc[1];
|
|
||||||
while (*other_cases != NOTACHAR)
|
|
||||||
diff --git a/src/pcre2_jit_test.c b/src/pcre2_jit_test.c
|
|
||||||
index 8dee16e..bf94c6d 100644
|
|
||||||
--- a/src/pcre2_jit_test.c
|
|
||||||
+++ b/src/pcre2_jit_test.c
|
|
||||||
@@ -412,6 +412,7 @@ static struct regression_test_case regression_test_cases[] = {
|
|
||||||
{ 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}]", " " },
|
|
||||||
+ { CMUP, 0, 0, 0, "[^S]\\B", "\xe2\x80\x8a" },
|
|
||||||
|
|
||||||
/* Possible empty brackets. */
|
|
||||||
{ MU, A, 0, 0, "(?:|ab||bc|a)+d", "abcxabcabd" },
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
From d4fa336fbcc388f89095b184ba6d99422cfc676c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zoltan Herczeg <hzmester@freemail.hu>
|
|
||||||
Date: Thu, 24 Mar 2022 05:34:42 +0000
|
|
||||||
Subject: [PATCH] Fix incorrect value reading in JIT.
|
|
||||||
|
|
||||||
---
|
|
||||||
src/pcre2_jit_compile.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c
|
|
||||||
index 94f6a58..7fcdac8 100644
|
|
||||||
--- a/src/pcre2_jit_compile.c
|
|
||||||
+++ b/src/pcre2_jit_compile.c
|
|
||||||
@@ -7489,7 +7489,7 @@ while (*cc != XCL_END)
|
|
||||||
{
|
|
||||||
SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
|
|
||||||
cc++;
|
|
||||||
- if (*cc == PT_CLIST && *cc == XCL_PROP)
|
|
||||||
+ if (*cc == PT_CLIST && cc[-1] == XCL_PROP)
|
|
||||||
{
|
|
||||||
other_cases = PRIV(ucd_caseless_sets) + cc[1];
|
|
||||||
while (*other_cases != NOTACHAR)
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,656 +0,0 @@
|
|||||||
From 03654e751e7f0700693526b67dfcadda6b42c9d0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zoltan Herczeg <hzmester@freemail.hu>
|
|
||||||
Date: Sat, 26 Mar 2022 07:55:50 +0000
|
|
||||||
Subject: [PATCH] Fixed an issue affecting recursions in JIT
|
|
||||||
|
|
||||||
---
|
|
||||||
ChangeLog | 3 +
|
|
||||||
src/pcre2_jit_compile.c | 290 ++++++++++++++++++++++++++--------------
|
|
||||||
src/pcre2_jit_test.c | 1 +
|
|
||||||
3 files changed, 194 insertions(+), 100 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ChangeLog b/ChangeLog
|
|
||||||
index cd3da65..4e8815d 100644
|
|
||||||
--- a/ChangeLog
|
|
||||||
+++ b/ChangeLog
|
|
||||||
@@ -66,6 +66,9 @@ Version 10.39 29-October-2021
|
|
||||||
23. Fixed a unicode properrty matching issue in JIT. The character was not
|
|
||||||
fully read in caseless matching.
|
|
||||||
|
|
||||||
+24. Fixed an issue affecting recursions in JIT caused by duplicated data
|
|
||||||
+transfers.
|
|
||||||
+
|
|
||||||
|
|
||||||
Version 10.38 01-October-2021
|
|
||||||
-----------------------------
|
|
||||||
diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c
|
|
||||||
index 5baca9b..08df1cf 100644
|
|
||||||
--- a/src/pcre2_jit_compile.c
|
|
||||||
+++ b/src/pcre2_jit_compile.c
|
|
||||||
@@ -413,6 +413,9 @@ typedef struct compiler_common {
|
|
||||||
/* 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;
|
|
||||||
@@ -2315,19 +2318,39 @@ for (i = 0; i < RECURSE_TMP_REG_COUNT; i++)
|
|
||||||
|
|
||||||
#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;
|
|
||||||
@@ -2350,15 +2373,17 @@ while (cc < ccend)
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
@@ -2377,39 +2402,55 @@ while (cc < ccend)
|
|
||||||
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
|
|
||||||
@@ -2418,8 +2459,12 @@ while (cc < ccend)
|
|
||||||
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]);
|
|
||||||
@@ -2427,8 +2472,12 @@ while (cc < ccend)
|
|
||||||
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]);
|
|
||||||
@@ -2436,20 +2485,29 @@ while (cc < ccend)
|
|
||||||
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;
|
|
||||||
|
|
||||||
@@ -2461,7 +2519,9 @@ while (cc < ccend)
|
|
||||||
#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;
|
|
||||||
@@ -2496,8 +2556,7 @@ while (cc < ccend)
|
|
||||||
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;
|
|
||||||
|
|
||||||
@@ -2517,8 +2576,6 @@ SLJIT_ASSERT(cc == ccend);
|
|
||||||
|
|
||||||
if (control_head_found)
|
|
||||||
length++;
|
|
||||||
-if (capture_last_found)
|
|
||||||
- length++;
|
|
||||||
if (quit_found)
|
|
||||||
{
|
|
||||||
if (setsom_found)
|
|
||||||
@@ -2551,14 +2608,12 @@ sljit_sw shared_srcw[3];
|
|
||||||
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)
|
|
||||||
@@ -2646,11 +2701,10 @@ while (cc < ccend)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
@@ -2658,33 +2712,31 @@ while (cc < ccend)
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
@@ -2703,50 +2755,66 @@ while (cc < ccend)
|
|
||||||
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;
|
|
||||||
|
|
||||||
@@ -2755,18 +2823,17 @@ while (cc < ccend)
|
|
||||||
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]);
|
|
||||||
@@ -2774,11 +2841,12 @@ while (cc < ccend)
|
|
||||||
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
|
|
||||||
@@ -2787,11 +2855,12 @@ while (cc < ccend)
|
|
||||||
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
|
|
||||||
@@ -2800,30 +2869,30 @@ while (cc < ccend)
|
|
||||||
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;
|
|
||||||
@@ -2840,14 +2909,17 @@ while (cc < ccend)
|
|
||||||
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:
|
|
||||||
@@ -2862,28 +2934,25 @@ while (cc < ccend)
|
|
||||||
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;
|
|
||||||
@@ -2891,7 +2960,7 @@ while (cc < ccend)
|
|
||||||
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)
|
|
||||||
@@ -13652,7 +13721,7 @@ SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
|
|
||||||
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);
|
|
||||||
@@ -13693,6 +13762,7 @@ if (!compiler)
|
|
||||||
common->compiler = compiler;
|
|
||||||
|
|
||||||
/* Main pcre_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. */
|
|
||||||
@@ -13915,20 +13985,40 @@ common->early_fail_end_ptr = 0;
|
|
||||||
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;
|
|
||||||
diff --git a/src/pcre2_jit_test.c b/src/pcre2_jit_test.c
|
|
||||||
index bf94c6d..26de6c7 100644
|
|
||||||
--- a/src/pcre2_jit_test.c
|
|
||||||
+++ b/src/pcre2_jit_test.c
|
|
||||||
@@ -748,6 +748,7 @@ static struct regression_test_case regression_test_cases[] = {
|
|
||||||
{ 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" },
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
From d07c967b3ac93a9bd8816837053a75b0f8a816c9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zoltan Herczeg <hzmester@freemail.hu>
|
|
||||||
Date: Thu, 14 Apr 2022 19:09:40 +0000
|
|
||||||
Subject: [PATCH] Fix recursion issue in JIT
|
|
||||||
|
|
||||||
Conflict:NA
|
|
||||||
Reference:https://github.com/PCRE2Project/pcre2/commit/d07c967b3ac93a9bd8816837053a75b0f8a816c9
|
|
||||||
---
|
|
||||||
src/pcre2_jit_compile.c | 6 ++++--
|
|
||||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c
|
|
||||||
index e47a9f3..b98bf95 100644
|
|
||||||
--- a/src/pcre2_jit_compile.c
|
|
||||||
+++ b/src/pcre2_jit_compile.c
|
|
||||||
@@ -2909,14 +2909,15 @@ while (cc < ccend)
|
|
||||||
i = 1 + 32 / (int)sizeof(PCRE2_UCHAR);
|
|
||||||
#endif
|
|
||||||
if (PRIVATE_DATA(cc) != 0)
|
|
||||||
+ {
|
|
||||||
+ private_count = 1;
|
|
||||||
+ private_srcw[0] = PRIVATE_DATA(cc);
|
|
||||||
switch(get_class_iterator_size(cc + i))
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
- private_srcw[0] = PRIVATE_DATA(cc);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
- private_srcw[0] = PRIVATE_DATA(cc);
|
|
||||||
if (recurse_check_bit(common, private_srcw[0]))
|
|
||||||
{
|
|
||||||
private_count = 2;
|
|
||||||
@@ -2929,6 +2930,7 @@ while (cc < ccend)
|
|
||||||
SLJIT_UNREACHABLE();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
+ }
|
|
||||||
cc += i;
|
|
||||||
break;
|
|
||||||
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
From d144199dfbefd276669a138b042f559b687b8bc8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zoltan Herczeg <zherczeg.u-szeged@partner.samsung.com>
|
|
||||||
Date: Wed, 24 Nov 2021 17:58:30 +0100
|
|
||||||
Subject: [PATCH] Revert an unintended change in JIT repeat detection. (#58)
|
|
||||||
|
|
||||||
Co-authored-by: Zoltan Herczeg <hzmester@freemail.hu>
|
|
||||||
|
|
||||||
Conflict:delete changelog
|
|
||||||
Reference:https://github.com/PCRE2Project/pcre2/commit/d144199dfbefd276669a138b042f559b687b8bc8
|
|
||||||
---
|
|
||||||
src/pcre2_jit_compile.c | 2 +-
|
|
||||||
src/pcre2_jit_test.c | 1 +
|
|
||||||
2 files changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c
|
|
||||||
index 6c42318..ac75c7f 100644
|
|
||||||
--- a/src/pcre2_jit_compile.c
|
|
||||||
+++ b/src/pcre2_jit_compile.c
|
|
||||||
@@ -1624,7 +1624,7 @@ if (end[-(1 + LINK_SIZE)] != OP_KET || PRIVATE_DATA(begin) != 0)
|
|
||||||
|
|
||||||
/* /(?:AB){4,6}/ is currently converted to /(?:AB){3}(?AB){1,3}/
|
|
||||||
* Skip the check of the second part. */
|
|
||||||
-if (PRIVATE_DATA(end - LINK_SIZE) == 0)
|
|
||||||
+if (PRIVATE_DATA(end - LINK_SIZE) != 0)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
next = end;
|
|
||||||
diff --git a/src/pcre2_jit_test.c b/src/pcre2_jit_test.c
|
|
||||||
index 26de6c7..f7b9f6d 100644
|
|
||||||
--- a/src/pcre2_jit_test.c
|
|
||||||
+++ b/src/pcre2_jit_test.c
|
|
||||||
@@ -291,6 +291,7 @@ static struct regression_test_case regression_test_cases[] = {
|
|
||||||
{ MU, A, 0, 0, "(a(?:bc|cb|b|c)+?|ss)+e", "accssabccbcacbccbbXaccssabccbcacbccbbe" },
|
|
||||||
{ MU, A, 0, 0, "(a(?:bc|cb|b|c)+|ss)+?e", "accssabccbcacbccbbXaccssabccbcacbccbbe" },
|
|
||||||
{ MU, A, 0, 0, "(?:(b(c)+?)+)?\?(?:(bc)+|(cb)+)+(?:m)+", "bccbcccbcbccbcbPbccbcccbcbccbcbmmn" },
|
|
||||||
+ { MU, A, 0, 0, "(aa|bb){8,1000}", "abaabbaabbaabbaab_aabbaabbaabbaabbaabbaabb_" },
|
|
||||||
|
|
||||||
/* Greedy and non-greedy * operators */
|
|
||||||
{ CMU, A, 0, 0, "(?:AA)*AB", "aaaaaaamaaaaaaab" },
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
From eb42305f072549facb3293f392f25768f35fa218 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= <carenas@gmail.com>
|
|
||||||
Date: Fri, 19 Nov 2021 00:23:46 -0800
|
|
||||||
Subject: [PATCH] jit: avoid integer wraparound in stack size definition (#42)
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
pcre2_jit_stack_create() allows the user to indicate how big of a
|
|
||||||
stack size JIT should be able to allocate and use, using a size_t
|
|
||||||
variable which should be able to hold bigger values than reasonable.
|
|
||||||
|
|
||||||
Internally, the value is rounded to the next 8K, but if the value
|
|
||||||
is unreasonable large, would overflow and could result in a smaller
|
|
||||||
than expected stack or a maximun size that is smaller than the
|
|
||||||
minimum..
|
|
||||||
|
|
||||||
Avoid the overflow by checking the value and failing early, and
|
|
||||||
while at it make the check clearer while documenting the failure
|
|
||||||
mode.
|
|
||||||
|
|
||||||
Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
|
|
||||||
|
|
||||||
Conflict:NA
|
|
||||||
Reference:https://github.com/PCRE2Project/pcre2/commit/eb42305f072549facb3293f392f25768f35fa218
|
|
||||||
---
|
|
||||||
doc/pcre2_jit_stack_create.3 | 3 ++-
|
|
||||||
src/pcre2_jit_misc.c | 2 +-
|
|
||||||
2 files changed, 3 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/doc/pcre2_jit_stack_create.3 b/doc/pcre2_jit_stack_create.3
|
|
||||||
index f0b29f0..d332b72 100644
|
|
||||||
--- a/doc/pcre2_jit_stack_create.3
|
|
||||||
+++ b/doc/pcre2_jit_stack_create.3
|
|
||||||
@@ -22,7 +22,8 @@ allocation. The result can be passed to the JIT run-time code by calling
|
|
||||||
\fBpcre2_jit_stack_assign()\fP to associate the stack with a compiled pattern,
|
|
||||||
which can then be processed by \fBpcre2_match()\fP or \fBpcre2_jit_match()\fP.
|
|
||||||
A maximum stack size of 512KiB to 1MiB should be more than enough for any
|
|
||||||
-pattern. For more details, see the
|
|
||||||
+pattern. If the stack couldn't be allocated or the values passed were not
|
|
||||||
+reasonable, NULL will be returned. For more details, see the
|
|
||||||
.\" HREF
|
|
||||||
\fBpcre2jit\fP
|
|
||||||
.\"
|
|
||||||
diff --git a/src/pcre2_jit_misc.c b/src/pcre2_jit_misc.c
|
|
||||||
index ec924e0..d532df9 100644
|
|
||||||
--- a/src/pcre2_jit_misc.c
|
|
||||||
+++ b/src/pcre2_jit_misc.c
|
|
||||||
@@ -135,7 +135,7 @@ return NULL;
|
|
||||||
|
|
||||||
pcre2_jit_stack *jit_stack;
|
|
||||||
|
|
||||||
-if (startsize < 1 || maxsize < 1)
|
|
||||||
+if (startsize == 0 || maxsize == 0 || maxsize > PCRE2_SIZE_MAX - STACK_GROWTH_RATE)
|
|
||||||
return NULL;
|
|
||||||
if (startsize > maxsize)
|
|
||||||
startsize = maxsize;
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
From 14dbc6e6ec9900b2e06a04d2612de37ccd564dfc Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= <carenas@gmail.com>
|
|
||||||
Date: Thu, 6 Jan 2022 05:46:43 -0800
|
|
||||||
Subject: [PATCH] jit: use correct type when checking for max value (#73)
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
eb42305f (jit: avoid integer wraparound in stack size definition (#42),
|
|
||||||
2021-11-19) introduces a check to avoid an integer overflow when
|
|
||||||
allocating stack size for JIT.
|
|
||||||
|
|
||||||
Unfortunately the maximum value was using PCRE2_SIZE_MAX, eventhough
|
|
||||||
the variable is of type size_t, so correct it.
|
|
||||||
|
|
||||||
Practically; the issue shouldn't affect the most common configurations
|
|
||||||
where both values are the same, and it will be unlikely that there would
|
|
||||||
be a configuration where PCRE2_SIZE_MAX > SIZE_MAX, hence the mistake
|
|
||||||
is unlikely to have reintroduced the original bug and this change should
|
|
||||||
be therefore mostly equivalent.
|
|
||||||
|
|
||||||
Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
|
|
||||||
|
|
||||||
Conflict:NA
|
|
||||||
Reference:https://github.com/PCRE2Project/pcre2/commit/14dbc6e6ec9900b2e06a04d2612de37ccd564dfc
|
|
||||||
---
|
|
||||||
src/pcre2_jit_misc.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/pcre2_jit_misc.c b/src/pcre2_jit_misc.c
|
|
||||||
index d532df9..e57afad 100644
|
|
||||||
--- a/src/pcre2_jit_misc.c
|
|
||||||
+++ b/src/pcre2_jit_misc.c
|
|
||||||
@@ -135,7 +135,7 @@ return NULL;
|
|
||||||
|
|
||||||
pcre2_jit_stack *jit_stack;
|
|
||||||
|
|
||||||
-if (startsize == 0 || maxsize == 0 || maxsize > PCRE2_SIZE_MAX - STACK_GROWTH_RATE)
|
|
||||||
+if (startsize == 0 || maxsize == 0 || maxsize > SIZE_MAX - STACK_GROWTH_RATE)
|
|
||||||
return NULL;
|
|
||||||
if (startsize > maxsize)
|
|
||||||
startsize = maxsize;
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,193 +0,0 @@
|
|||||||
From ae4e6261e5681658f88a0dff8eb2d60112bd7e54 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= <carenas@gmail.com>
|
|
||||||
Date: Sat, 27 Nov 2021 08:49:31 -0800
|
|
||||||
Subject: [PATCH] match: avoid crash if subject NULL and PCRE2_ZERO_TERMINATED
|
|
||||||
(#53)
|
|
||||||
|
|
||||||
* pcre2_match: avoid crash if subject NULL and PCRE2_ZERO_TERMINATED
|
|
||||||
|
|
||||||
When length of subject is PCRE2_ZERO_TERMINATED strlen is used
|
|
||||||
to calculate its size, which will trigger a crash if subject is
|
|
||||||
also NULL.
|
|
||||||
|
|
||||||
Move the NULL check before strlen on it would be used, and make
|
|
||||||
sure or dependent variables are set after the NULL validation
|
|
||||||
as well.
|
|
||||||
|
|
||||||
While at it, fix a typo in a debug flag in the same file, which
|
|
||||||
is otherwise unrelated and make sure the full section of constrain
|
|
||||||
checks can be identified clearly using the leading comment alone.
|
|
||||||
|
|
||||||
* pcre2_dfa_match: avoid crash if subject NULL and PCRE2_ZERO_TERMINATED
|
|
||||||
|
|
||||||
When length of subject is PCRE2_ZERO_TERMINATED strlen is used
|
|
||||||
to calculate its size, which will trigger a crash if subject is
|
|
||||||
also NULL.
|
|
||||||
|
|
||||||
Move the NULL check before the detection for subject sizes to
|
|
||||||
avoid this issue.
|
|
||||||
|
|
||||||
* pcre2_substitute: avoid crash if subject or replacement are NULL
|
|
||||||
|
|
||||||
The underlying pcre2_match() function will validate the subject if
|
|
||||||
needed, but will crash when length is PCRE2_ZERO_TERMINATED or if
|
|
||||||
subject == NULL and pcre2_match() is not being called because
|
|
||||||
match_data was provided.
|
|
||||||
|
|
||||||
The replacement parameter is missing NULL checks, and so currently
|
|
||||||
allows for an equivalent response to "" if rlength == 0.
|
|
||||||
|
|
||||||
Restrict all other cases to avoid strlen(NULL) crashes in the same
|
|
||||||
way that is done for subject, but also make sure to reject invalid
|
|
||||||
length values as early as possible.
|
|
||||||
|
|
||||||
Conflict:NA
|
|
||||||
Reference:https://github.com/PCRE2Project/pcre2/commit/ae4e6261e5681658f88a0dff8eb2d60112bd7e54
|
|
||||||
---
|
|
||||||
doc/pcre2api.3 | 4 +++-
|
|
||||||
src/pcre2_dfa_match.c | 12 +++++-------
|
|
||||||
src/pcre2_match.c | 20 ++++++++++----------
|
|
||||||
src/pcre2_substitute.c | 15 ++++++++++-----
|
|
||||||
4 files changed, 28 insertions(+), 23 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/doc/pcre2api.3 b/doc/pcre2api.3
|
|
||||||
index 1caccbb..fe84fa4 100644
|
|
||||||
--- a/doc/pcre2api.3
|
|
||||||
+++ b/doc/pcre2api.3
|
|
||||||
@@ -3649,7 +3649,9 @@ needed is returned via \fIoutlengthptr\fP. Note that this does not happen by
|
|
||||||
default.
|
|
||||||
.P
|
|
||||||
PCRE2_ERROR_NULL is returned if PCRE2_SUBSTITUTE_MATCHED is set but the
|
|
||||||
-\fImatch_data\fP argument is NULL.
|
|
||||||
+\fImatch_data\fP argument is NULL or if the \fIsubject\fP or \fIreplacement\fP
|
|
||||||
+arguments are NULL. For backward compatibility reasons an exception is made for
|
|
||||||
+the \fIreplacement\fP argument if the \fIrlength\fP argument is also 0.
|
|
||||||
.P
|
|
||||||
PCRE2_ERROR_BADREPLACEMENT is used for miscellaneous syntax errors in the
|
|
||||||
replacement string, with more particular errors being PCRE2_ERROR_BADREPESCAPE
|
|
||||||
diff --git a/src/pcre2_dfa_match.c b/src/pcre2_dfa_match.c
|
|
||||||
index 060dc76..a97e071 100644
|
|
||||||
--- a/src/pcre2_dfa_match.c
|
|
||||||
+++ b/src/pcre2_dfa_match.c
|
|
||||||
@@ -3285,8 +3285,11 @@ rws->next = NULL;
|
|
||||||
rws->size = RWS_BASE_SIZE;
|
|
||||||
rws->free = RWS_BASE_SIZE - RWS_ANCHOR_SIZE;
|
|
||||||
|
|
||||||
-/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated
|
|
||||||
-subject string. */
|
|
||||||
+/* Plausibility checks */
|
|
||||||
+
|
|
||||||
+if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;
|
|
||||||
+if (re == NULL || subject == NULL || workspace == NULL || match_data == NULL)
|
|
||||||
+ return PCRE2_ERROR_NULL;
|
|
||||||
|
|
||||||
if (length == PCRE2_ZERO_TERMINATED)
|
|
||||||
{
|
|
||||||
@@ -3294,11 +3297,6 @@ if (length == PCRE2_ZERO_TERMINATED)
|
|
||||||
was_zero_terminated = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
-/* Plausibility checks */
|
|
||||||
-
|
|
||||||
-if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;
|
|
||||||
-if (re == NULL || subject == NULL || workspace == NULL || match_data == NULL)
|
|
||||||
- return PCRE2_ERROR_NULL;
|
|
||||||
if (wscount < 20) return PCRE2_ERROR_DFA_WSSIZE;
|
|
||||||
if (start_offset > length) return PCRE2_ERROR_BADOFFSET;
|
|
||||||
|
|
||||||
diff --git a/src/pcre2_match.c b/src/pcre2_match.c
|
|
||||||
index f28cdbb..ea8ca5d 100644
|
|
||||||
--- a/src/pcre2_match.c
|
|
||||||
+++ b/src/pcre2_match.c
|
|
||||||
@@ -49,7 +49,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
/* #define DEBUG_SHOW_OPS */
|
|
||||||
/* #define DEBUG_SHOW_RMATCH */
|
|
||||||
|
|
||||||
-#ifdef DEBUG_FRAME_DISPLAY
|
|
||||||
+#ifdef DEBUG_FRAMES_DISPLAY
|
|
||||||
#include <stdarg.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -6129,8 +6129,8 @@ PCRE2_UCHAR req_cu2 = 0;
|
|
||||||
PCRE2_SPTR bumpalong_limit;
|
|
||||||
PCRE2_SPTR end_subject;
|
|
||||||
PCRE2_SPTR true_end_subject;
|
|
||||||
-PCRE2_SPTR start_match = subject + start_offset;
|
|
||||||
-PCRE2_SPTR req_cu_ptr = start_match - 1;
|
|
||||||
+PCRE2_SPTR start_match;
|
|
||||||
+PCRE2_SPTR req_cu_ptr;
|
|
||||||
PCRE2_SPTR start_partial;
|
|
||||||
PCRE2_SPTR match_partial;
|
|
||||||
|
|
||||||
@@ -6170,9 +6170,14 @@ PCRE2_SPTR stack_frames_vector[START_FRAMES_SIZE/sizeof(PCRE2_SPTR)]
|
|
||||||
PCRE2_KEEP_UNINITIALIZED;
|
|
||||||
mb->stack_frames = (heapframe *)stack_frames_vector;
|
|
||||||
|
|
||||||
-/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated
|
|
||||||
-subject string. */
|
|
||||||
+/* Plausibility checks */
|
|
||||||
+
|
|
||||||
+if ((options & ~PUBLIC_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;
|
|
||||||
+if (code == NULL || subject == NULL || match_data == NULL)
|
|
||||||
+ return PCRE2_ERROR_NULL;
|
|
||||||
|
|
||||||
+start_match = subject + start_offset;
|
|
||||||
+req_cu_ptr = start_match - 1;
|
|
||||||
if (length == PCRE2_ZERO_TERMINATED)
|
|
||||||
{
|
|
||||||
length = PRIV(strlen)(subject);
|
|
||||||
@@ -6180,11 +6185,6 @@ if (length == PCRE2_ZERO_TERMINATED)
|
|
||||||
}
|
|
||||||
true_end_subject = end_subject = subject + length;
|
|
||||||
|
|
||||||
-/* Plausibility checks */
|
|
||||||
-
|
|
||||||
-if ((options & ~PUBLIC_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;
|
|
||||||
-if (code == NULL || subject == NULL || match_data == NULL)
|
|
||||||
- return PCRE2_ERROR_NULL;
|
|
||||||
if (start_offset > length) return PCRE2_ERROR_BADOFFSET;
|
|
||||||
|
|
||||||
/* Check that the first field in the block is the magic number. */
|
|
||||||
diff --git a/src/pcre2_substitute.c b/src/pcre2_substitute.c
|
|
||||||
index 981a106..7aefb60 100644
|
|
||||||
--- a/src/pcre2_substitute.c
|
|
||||||
+++ b/src/pcre2_substitute.c
|
|
||||||
@@ -260,6 +260,12 @@ PCRE2_UNSET, so as not to imply an offset in the replacement. */
|
|
||||||
if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0)
|
|
||||||
return PCRE2_ERROR_BADOPTION;
|
|
||||||
|
|
||||||
+/* Validate length and find the end of the replacement. */
|
|
||||||
+if (replacement == NULL && rlength > 0) return PCRE2_ERROR_NULL;
|
|
||||||
+else if (rlength == PCRE2_ZERO_TERMINATED)
|
|
||||||
+ rlength = PRIV(strlen)(replacement);
|
|
||||||
+repend = replacement + rlength;
|
|
||||||
+
|
|
||||||
/* Check for using a match that has already happened. Note that the subject
|
|
||||||
pointer in the match data may be NULL after a no-match. */
|
|
||||||
|
|
||||||
@@ -292,6 +298,7 @@ else if (use_existing_match)
|
|
||||||
(pcre2_general_context *)mcontext;
|
|
||||||
int pairs = (code->top_bracket + 1 < match_data->oveccount)?
|
|
||||||
code->top_bracket + 1 : match_data->oveccount;
|
|
||||||
+ if (subject == NULL) return PCRE2_ERROR_NULL;
|
|
||||||
internal_match_data = pcre2_match_data_create(match_data->oveccount,
|
|
||||||
gcontext);
|
|
||||||
if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY;
|
|
||||||
@@ -312,11 +319,9 @@ scb.input = subject;
|
|
||||||
scb.output = (PCRE2_SPTR)buffer;
|
|
||||||
scb.ovector = ovector;
|
|
||||||
|
|
||||||
-/* Find lengths of zero-terminated strings and the end of the replacement. */
|
|
||||||
-
|
|
||||||
-if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject);
|
|
||||||
-if (rlength == PCRE2_ZERO_TERMINATED) rlength = PRIV(strlen)(replacement);
|
|
||||||
-repend = replacement + rlength;
|
|
||||||
+/* Find lengths of zero-terminated subject */
|
|
||||||
+if (length == PCRE2_ZERO_TERMINATED)
|
|
||||||
+ length = subject? PRIV(strlen)(subject) : 0;
|
|
||||||
|
|
||||||
/* Check UTF replacement string if necessary. */
|
|
||||||
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,120 +0,0 @@
|
|||||||
From 7db87842963394d250b8405cdb513a502b479005 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= <carenas@gmail.com>
|
|
||||||
Date: Tue, 9 Nov 2021 08:57:48 -0800
|
|
||||||
Subject: [PATCH] pcre2grep: correctly handle multiple passes (#35)
|
|
||||||
|
|
||||||
* tests: use a explicit filehandle to share in testing -m
|
|
||||||
|
|
||||||
The way stdin is shared to all participants of a subshell varies
|
|
||||||
per shell, and at least the standard /bin/sh in Solaris seem to
|
|
||||||
create a new copy for each command, defeating the purpose of the
|
|
||||||
test.
|
|
||||||
|
|
||||||
Use instead exec to create a filehandle that could then be used
|
|
||||||
explicitly in the test to confirm that the stream is set.
|
|
||||||
|
|
||||||
* pcre2grep: correctly handle multiple passes
|
|
||||||
|
|
||||||
When the -m option is used, pcre2grep is meant to exit after enough
|
|
||||||
matches are found but while leaving the stream pinned to the next position
|
|
||||||
after the last match.
|
|
||||||
|
|
||||||
Unfortunately, it wasn't tracking correctly the beginning of the stream
|
|
||||||
on subsequent passes, and therefore it will fail to use the right seek
|
|
||||||
value.
|
|
||||||
|
|
||||||
Grab the position of the stream at the beginning and while at it, make
|
|
||||||
sure that the stream passed hasn't been consumed already.
|
|
||||||
|
|
||||||
Conflict:NA
|
|
||||||
Reference:https://github.com/PCRE2Project/pcre2/commit/7db87842963394d250b8405cdb513a502b479005
|
|
||||||
---
|
|
||||||
RunGrepTest | 6 +++++-
|
|
||||||
src/pcre2grep.c | 15 ++++++++++++---
|
|
||||||
testdata/grepoutput | 11 +++++++++++
|
|
||||||
3 files changed, 28 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/RunGrepTest b/RunGrepTest
|
|
||||||
index 25f69bd..9682c5f 100755
|
|
||||||
--- a/RunGrepTest
|
|
||||||
+++ b/RunGrepTest
|
|
||||||
@@ -674,10 +674,14 @@ echo "---------------------------- Test 131 -----------------------------" >>tes
|
|
||||||
echo "RC=$?" >>testtrygrep
|
|
||||||
|
|
||||||
echo "---------------------------- Test 132 -----------------------------" >>testtrygrep
|
|
||||||
-(cd $srcdir; $valgrind $vjs $pcre2grep -m1 -A3 '^match'; echo '---'; head -1) <$srcdir/testdata/grepinput >>testtrygrep 2>&1
|
|
||||||
+(cd $srcdir; exec 3<$srcdir/testdata/grepinput; $valgrind $vjs $pcre2grep -m1 -A3 '^match' <&3; echo '---'; head -1 <&3; exec 3<&-) >>testtrygrep 2>&1
|
|
||||||
echo "RC=$?" >>testtrygrep
|
|
||||||
|
|
||||||
echo "---------------------------- Test 133 -----------------------------" >>testtrygrep
|
|
||||||
+(cd $srcdir; exec 3<$srcdir/testdata/grepinput; $valgrind $vjs $pcre2grep -m1 -A3 '^match' <&3; echo '---'; $valgrind $vjs $pcre2grep -m1 -A3 '^match' <&3; exec 3<&-) >>testtrygrep 2>&1
|
|
||||||
+echo "RC=$?" >>testtrygrep
|
|
||||||
+
|
|
||||||
+echo "---------------------------- Test 134 -----------------------------" >>testtrygrep
|
|
||||||
(cd $srcdir; $valgrind $vjs $pcre2grep -m1 -O '=$x{41}$x423$o{103}$o1045=' 'fox') <$srcdir/testdata/grepinputv >>testtrygrep 2>&1
|
|
||||||
echo "RC=$?" >>testtrygrep
|
|
||||||
|
|
||||||
diff --git a/src/pcre2grep.c b/src/pcre2grep.c
|
|
||||||
index aa84ea7..519346b 100644
|
|
||||||
--- a/src/pcre2grep.c
|
|
||||||
+++ b/src/pcre2grep.c
|
|
||||||
@@ -2538,6 +2538,7 @@ BOOL endhyphenpending = FALSE;
|
|
||||||
BOOL lines_printed = FALSE;
|
|
||||||
BOOL input_line_buffered = line_buffered;
|
|
||||||
FILE *in = NULL; /* Ensure initialized */
|
|
||||||
+long stream_start = -1; /* Only non-negative if relevant */
|
|
||||||
|
|
||||||
/* Do the first read into the start of the buffer and set up the pointer to end
|
|
||||||
of what we have. In the case of libz, a non-zipped .gz file will be read as a
|
|
||||||
@@ -2547,7 +2548,15 @@ fail. */
|
|
||||||
if (frtype != FR_LIBZ && frtype != FR_LIBBZ2)
|
|
||||||
{
|
|
||||||
in = (FILE *)handle;
|
|
||||||
- if (is_file_tty(in)) input_line_buffered = TRUE;
|
|
||||||
+ if (feof(in))
|
|
||||||
+ return 1;
|
|
||||||
+ if (is_file_tty(in))
|
|
||||||
+ input_line_buffered = TRUE;
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ if (count_limit >= 0 && filename == stdin_name)
|
|
||||||
+ stream_start = ftell(in);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
else input_line_buffered = FALSE;
|
|
||||||
|
|
||||||
@@ -2594,8 +2603,8 @@ while (ptr < endptr)
|
|
||||||
|
|
||||||
if (count_limit >= 0 && count_matched_lines >= count_limit)
|
|
||||||
{
|
|
||||||
- if (frtype == FR_PLAIN && filename == stdin_name && !is_file_tty(handle))
|
|
||||||
- (void)fseek(handle, (long int)filepos, SEEK_SET);
|
|
||||||
+ if (stream_start >= 0)
|
|
||||||
+ (void)fseek(handle, stream_start + (long int)filepos, SEEK_SET);
|
|
||||||
rc = (count_limit == 0)? 1 : 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
diff --git a/testdata/grepoutput b/testdata/grepoutput
|
|
||||||
index 5f3b97c..66af4cf 100644
|
|
||||||
--- a/testdata/grepoutput
|
|
||||||
+++ b/testdata/grepoutput
|
|
||||||
@@ -978,5 +978,16 @@ match 2:
|
|
||||||
a
|
|
||||||
RC=0
|
|
||||||
---------------------------- Test 133 -----------------------------
|
|
||||||
+match 1:
|
|
||||||
+ a
|
|
||||||
+match 2:
|
|
||||||
+ b
|
|
||||||
+---
|
|
||||||
+match 2:
|
|
||||||
+ b
|
|
||||||
+match 3:
|
|
||||||
+ c
|
|
||||||
+RC=0
|
|
||||||
+---------------------------- Test 134 -----------------------------
|
|
||||||
=AB3CD5=
|
|
||||||
RC=0
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
Binary file not shown.
BIN
pcre2-10.40.tar.bz2
Normal file
BIN
pcre2-10.40.tar.bz2
Normal file
Binary file not shown.
16
pcre2.spec
16
pcre2.spec
@ -1,6 +1,6 @@
|
|||||||
Name: pcre2
|
Name: pcre2
|
||||||
Version: 10.39
|
Version: 10.40
|
||||||
Release: 5
|
Release: 1
|
||||||
Summary: Perl Compatible Regular Expressions
|
Summary: Perl Compatible Regular Expressions
|
||||||
License: BSD
|
License: BSD
|
||||||
URL: http://www.pcre.org/
|
URL: http://www.pcre.org/
|
||||||
@ -8,15 +8,6 @@ Source0: https://ftp.pcre.org/pub/pcre/%{name}-%{version}.tar.bz2
|
|||||||
|
|
||||||
# Do no set RPATH if libdir is not /usr/lib
|
# Do no set RPATH if libdir is not /usr/lib
|
||||||
Patch6000: backport-pcre2-10.10-Fix-multilib.patch
|
Patch6000: backport-pcre2-10.10-Fix-multilib.patch
|
||||||
Patch6001: backport-CVE-2022-1586-1.patch
|
|
||||||
Patch6002: backport-CVE-2022-1586-2.patch
|
|
||||||
Patch6003: backport-CVE-2022-1587.patch
|
|
||||||
Patch6004: backport-pcre2grep-correctly-handle-multiple-passes-35.patch
|
|
||||||
Patch6005: backport-jit-avoid-integer-wraparound-in-stack-size-definitio.patch
|
|
||||||
Patch6006: backport-Revert-an-unintended-change-in-JIT-repeat-detection.patch
|
|
||||||
Patch6007: backport-match-avoid-crash-if-subject-NULL-and-PCRE2_ZERO_TER.patch
|
|
||||||
Patch6008: backport-jit-use-correct-type-when-checking-for-max-value-73.patch
|
|
||||||
Patch6009: backport-Fix-recursion-issue-in-JIT.patch
|
|
||||||
Patch6010: backport-doc-avoid-nonexistent-PCRE2_ERROR_MEMORY-error-107.patch
|
Patch6010: backport-doc-avoid-nonexistent-PCRE2_ERROR_MEMORY-error-107.patch
|
||||||
Patch6011: backport-Update-HTML-docs.patch
|
Patch6011: backport-Update-HTML-docs.patch
|
||||||
Patch6012: backport-Fixed-race-condition-that-occurs-when-initializing-t.patch
|
Patch6012: backport-Fixed-race-condition-that-occurs-when-initializing-t.patch
|
||||||
@ -139,6 +130,9 @@ make check
|
|||||||
%{_pkgdocdir}/html/
|
%{_pkgdocdir}/html/
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Nov 18 2022 dillon chen <dillon.chen@gmail.com> - 10.40-1
|
||||||
|
- update to 10.40
|
||||||
|
|
||||||
* Mon Nov 14 2022 zhaozhen <zhaozhen@loongson.cn> - 10.39-5
|
* Mon Nov 14 2022 zhaozhen <zhaozhen@loongson.cn> - 10.39-5
|
||||||
- Type:enhancement
|
- Type:enhancement
|
||||||
- ID:NA
|
- ID:NA
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user