Fix bug in processing (?(DEFINE)...) within lookbehind assertions.

This commit is contained in:
Philip.Hazel 2020-01-26 15:31:27 +00:00
parent 9e960f5465
commit 3a6b4948d1
6 changed files with 61 additions and 6 deletions

View File

@ -48,6 +48,14 @@ the minimum.
13. In pcre2grep, if the final line in a scanned file is output but does not 13. In pcre2grep, if the final line in a scanned file is output but does not
end with a newline sequence, add a newline according to the --newline setting. end with a newline sequence, add a newline according to the --newline setting.
14. (?(DEFINE)...) groups were not being handled correctly when checking for
the fixed length of a lookbehind assertion. Such a group within a lookbehind
should be skipped, as it does not contribute to the length of the group.
Instead, the (DEFINE) group was being processed, and if at the end of the
lookbehind, that end was not correctly recognized. Errors such as "lookbehind
assertion is not fixed length" and also "internal error: bad code value in
parsed_skip()" could result.
Version 10.34 21-November-2019 Version 10.34 21-November-2019
------------------------------ ------------------------------

View File

@ -8800,9 +8800,10 @@ memset(slot + IMM2_SIZE + length, 0,
/* This function is called to skip parts of the parsed pattern when finding the /* This function is called to skip parts of the parsed pattern when finding the
length of a lookbehind branch. It is called after (*ACCEPT) and (*FAIL) to find length of a lookbehind branch. It is called after (*ACCEPT) and (*FAIL) to find
the end of the branch, it is called to skip over an internal lookaround, and it the end of the branch, it is called to skip over an internal lookaround or
is also called to skip to the end of a class, during which it will never (DEFINE) group, and it is also called to skip to the end of a class, during
encounter nested groups (but there's no need to have special code for that). which it will never encounter nested groups (but there's no need to have
special code for that).
When called to find the end of a branch or group, pptr must point to the first When called to find the end of a branch or group, pptr must point to the first
meta code inside the branch, not the branch-starting code. In other cases it meta code inside the branch, not the branch-starting code. In other cases it
@ -9280,14 +9281,21 @@ for (;; pptr++)
itemlength = grouplength; itemlength = grouplength;
break; break;
/* Check nested groups - advance past the initial data for each type and /* A (DEFINE) group is never obeyed inline and so it does not contribute to
then seek a fixed length with get_grouplength(). */ the length of this branch. Skip from the following item to the next
unpaired ket. */
case META_COND_DEFINE:
pptr = parsed_skip(pptr + 1, PSKIP_KET);
break;
/* Check other nested groups - advance past the initial data for each type
and then seek a fixed length with get_grouplength(). */
case META_COND_NAME: case META_COND_NAME:
case META_COND_NUMBER: case META_COND_NUMBER:
case META_COND_RNAME: case META_COND_RNAME:
case META_COND_RNUMBER: case META_COND_RNUMBER:
case META_COND_DEFINE:
pptr += 2 + SIZEOFFSET; pptr += 2 + SIZEOFFSET;
goto CHECK_GROUP; goto CHECK_GROUP;

13
testdata/testinput1 vendored
View File

@ -6411,4 +6411,17 @@ ef) x/x,mark
Hackdaws love my big sphinx of quartz. Hackdaws love my big sphinx of quartz.
Pack my fox with five dozen liquor jugs. Pack my fox with five dozen liquor jugs.
"(?<=X(?(DEFINE)(A)))X(*F)"
\= Expect no match
AXYZ
"(?<=X(?(DEFINE)(A)))."
AXYZ
"(?<=X(?(DEFINE)(.*))Y)."
AXYZ
"(?<=X(?(DEFINE)(Y))(?1))."
AXYZ
# End of testinput1 # End of testinput1

4
testdata/testinput2 vendored
View File

@ -5806,4 +5806,8 @@ a)"xI
12abc34xyz99abc55\=substitute_skip=1 12abc34xyz99abc55\=substitute_skip=1
12abc34xyz99abc55\=substitute_skip=2 12abc34xyz99abc55\=substitute_skip=2
# Expect non-fixed-length error
"(?<=X(?(DEFINE)(.*))(?1))."
# End of testinput2 # End of testinput2

17
testdata/testoutput1 vendored
View File

@ -10165,4 +10165,21 @@ No match
Pack my fox with five dozen liquor jugs. Pack my fox with five dozen liquor jugs.
No match No match
"(?<=X(?(DEFINE)(A)))X(*F)"
\= Expect no match
AXYZ
No match
"(?<=X(?(DEFINE)(A)))."
AXYZ
0: Y
"(?<=X(?(DEFINE)(.*))Y)."
AXYZ
0: Z
"(?<=X(?(DEFINE)(Y))(?1))."
AXYZ
0: Z
# End of testinput1 # End of testinput1

View File

@ -17536,6 +17536,11 @@ Callout 0: last capture = 2
3(2) Old 12 15 "abc" New 5 10 "<abc>" 3(2) Old 12 15 "abc" New 5 10 "<abc>"
3: <abc><abc> 3: <abc><abc>
# Expect non-fixed-length error
"(?<=X(?(DEFINE)(.*))(?1))."
Failed: error 125 at offset 0: lookbehind assertion is not fixed length
# End of testinput2 # End of testinput2
Error -70: PCRE2_ERROR_BADDATA (unknown error number) Error -70: PCRE2_ERROR_BADDATA (unknown error number)
Error -62: bad serialized data Error -62: bad serialized data