From 0820852df64a8236684759fc7e80298d4fdc70bd Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Fri, 1 Dec 2023 09:55:58 +0000 Subject: [PATCH] Fix incorrect auto-possessification at end of variable length lookbehind --- src/pcre2_auto_possess.c | 18 ++++++++++++------ testdata/testinput1 | 3 +++ testdata/testoutput1 | 4 ++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/pcre2_auto_possess.c b/src/pcre2_auto_possess.c index 419fd4900..95e4b6910 100644 --- a/src/pcre2_auto_possess.c +++ b/src/pcre2_auto_possess.c @@ -560,6 +560,8 @@ matches to an empty string (also represented by a non-zero value). */ for(;;) { + PCRE2_SPTR bracode; + /* All operations move the code pointer forward. Therefore infinite recursions are not possible. */ @@ -616,8 +618,9 @@ for(;;) so its last iterator can never be possessified if the pattern contains recursions. (This could be improved by keeping a list of group numbers that are called by recursion.) */ - - switch(*(code - GET(code, 1))) + + bracode = code - GET(code, 1); + switch(*bracode) { case OP_CBRA: case OP_SCBRA: @@ -636,16 +639,19 @@ for(;;) break; /* Atomic sub-patterns and assertions can always auto-possessify their - last iterator. However, if the group was entered as a result of checking - a previous iterator, this is not possible. */ + last iterator except for variable length lookbehinds. However, if the + group was entered as a result of checking a previous iterator, this is + not possible. */ case OP_ASSERT: case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: case OP_ONCE: return !entered_a_group; + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + return (bracode[1+LINK_SIZE] == OP_VREVERSE)? FALSE : !entered_a_group; + /* Non-atomic assertions - don't possessify last iterator. This needs more thought. */ diff --git a/testdata/testinput1 b/testdata/testinput1 index e7140601b..00e76dad2 100644 --- a/testdata/testinput1 +++ b/testdata/testinput1 @@ -6651,4 +6651,7 @@ $/x /^..A(*SKIP)B|C/ 12ADC +/(?