update to 10.40

This commit is contained in:
dillon_chen 2022-11-18 17:44:59 +08:00
parent 2b4fa50983
commit ba07b7d029
12 changed files with 5 additions and 1249 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

Binary file not shown.

View File

@ -1,6 +1,6 @@
Name: pcre2
Version: 10.39
Release: 5
Version: 10.40
Release: 1
Summary: Perl Compatible Regular Expressions
License: BSD
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
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
Patch6011: backport-Update-HTML-docs.patch
Patch6012: backport-Fixed-race-condition-that-occurs-when-initializing-t.patch
@ -139,6 +130,9 @@ make check
%{_pkgdocdir}/html/
%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
- Type:enhancement
- ID:NA