From fcd0c39b263eddd7768ca67674d06a60574a67b6 Mon Sep 17 00:00:00 2001 From: "Philip.Hazel" Date: Mon, 3 Apr 2017 18:02:07 +0000 Subject: [PATCH] Fix capturing in conditional negative assertions ended with (*ACCEPT). --- ChangeLog | 5 ++++- src/pcre2_match.c | 17 +++++++---------- testdata/testinput1 | 12 ++++++++++++ testdata/testoutput1 | 20 ++++++++++++++++++++ 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3180e1b..36a5478 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,7 +29,10 @@ bugs were never in fully released code, but are noted here for the record. vector on the stack is not big enough to handle at least 10 frames. Fixes oss-fuzz issue 783. - (c) Handling of (*VERB)s in recursions was wrong in some cases. + (c) Handling of (*VERB)s in recursions was wrong in some cases. + + (d) Captures in negative assertions that were used as conditions were not + happening if the assertion matched via (*ACCEPT). 2. Now that pcre2_match() no longer uses recursive function calls (see above), the "match limit recursion" value seems misnamed. It still exists, and limits diff --git a/src/pcre2_match.c b/src/pcre2_match.c index 476729d..1c35c02 100644 --- a/src/pcre2_match.c +++ b/src/pcre2_match.c @@ -5332,17 +5332,14 @@ fprintf(stderr, "++ op=%d\n", *Fecode); switch(rrc) { - case MATCH_ACCEPT: - if (Lpositive) /* Save captures if a positive assertion */ - { - memcpy(Fovector, - (char *)assert_accept_frame + offsetof(heapframe, ovector), - assert_accept_frame->offset_top * sizeof(PCRE2_SIZE)); - Foffset_top = assert_accept_frame->offset_top; - } + case MATCH_ACCEPT: /* Save captures */ + memcpy(Fovector, + (char *)assert_accept_frame + offsetof(heapframe, ovector), + assert_accept_frame->offset_top * sizeof(PCRE2_SIZE)); + Foffset_top = assert_accept_frame->offset_top; - /* Fall through. In the case of a match for a positive assertion, the - captures have already been put into the current frame. */ + /* Fall through. In the case of a match, the captures have already + been put into the current frame. */ case MATCH_MATCH: condition = Lpositive; /* TRUE for positive assertion */ diff --git a/testdata/testinput1 b/testdata/testinput1 index 29fad9e..2a2e855 100644 --- a/testdata/testinput1 +++ b/testdata/testinput1 @@ -5905,4 +5905,16 @@ ef) x/x,mark /^(.|(.)(?1)?\2)$/ abcba +/^(?(?=(a))abc|def)/ + abc + +/^(?(?!(a))def|abc)/ + abc + +/^(?(?=(a)(*ACCEPT))abc|def)/ + abc + +/^(?(?!(a)(*ACCEPT))def|abc)/ + abc + # End of testinput1 diff --git a/testdata/testoutput1 b/testdata/testoutput1 index 333ea76..95f7f56 100644 --- a/testdata/testoutput1 +++ b/testdata/testoutput1 @@ -9467,4 +9467,24 @@ No match 1: abcba 2: a +/^(?(?=(a))abc|def)/ + abc + 0: abc + 1: a + +/^(?(?!(a))def|abc)/ + abc + 0: abc + 1: a + +/^(?(?=(a)(*ACCEPT))abc|def)/ + abc + 0: abc + 1: a + +/^(?(?!(a)(*ACCEPT))def|abc)/ + abc + 0: abc + 1: a + # End of testinput1