Fix pcre2grep loop provoked by \K in a lookbehind assertion in a non-anchored
pattern.
This commit is contained in:
parent
ade67323e7
commit
cda8384a95
|
@ -27,7 +27,7 @@ error about an unsupported item.
|
||||||
|
|
||||||
8. For some types of pattern, for example /Z*(|d*){216}/, the auto-
|
8. For some types of pattern, for example /Z*(|d*){216}/, the auto-
|
||||||
possessification code could take exponential time to complete. A recursion
|
possessification code could take exponential time to complete. A recursion
|
||||||
depth limit of 10000 has been imposed to limit the resources used by this
|
depth limit of 1000 has been imposed to limit the resources used by this
|
||||||
optimization. This infelicity was discovered by the LLVM fuzzer.
|
optimization. This infelicity was discovered by the LLVM fuzzer.
|
||||||
|
|
||||||
9. A pattern such as /(*UTF)[\S\V\H]/, which contains a negated special class
|
9. A pattern such as /(*UTF)[\S\V\H]/, which contains a negated special class
|
||||||
|
@ -67,6 +67,9 @@ have either been changed to uint32_t or commented as "must be signed".
|
||||||
caused a stack overflow instead of the diagnosis of a non-fixed length
|
caused a stack overflow instead of the diagnosis of a non-fixed length
|
||||||
lookbehind assertion. This bug was discovered by the LLVM fuzzer.
|
lookbehind assertion. This bug was discovered by the LLVM fuzzer.
|
||||||
|
|
||||||
|
17. The use of \K in a positive lookbehind assertion in a non-anchored pattern
|
||||||
|
(e.g. /(?<=\Ka)/) could make pcre2grep loop.
|
||||||
|
|
||||||
|
|
||||||
Version 10.10 06-March-2015
|
Version 10.10 06-March-2015
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
|
@ -524,6 +524,11 @@ echo "---------------------------- Test 106 -----------------------------" >>tes
|
||||||
(cd $srcdir; echo "a" | $valgrind $pcre2grep -M "|a" ) >>testtrygrep 2>&1
|
(cd $srcdir; echo "a" | $valgrind $pcre2grep -M "|a" ) >>testtrygrep 2>&1
|
||||||
echo "RC=$?" >>testtrygrep
|
echo "RC=$?" >>testtrygrep
|
||||||
|
|
||||||
|
echo "---------------------------- Test 107 -----------------------------" >>testtrygrep
|
||||||
|
echo "a" >testtemp1grep
|
||||||
|
echo "aaaaa" >>testtemp1grep
|
||||||
|
(cd $srcdir; $valgrind $pcre2grep --line-offsets '(?<=\Ka)' testtemp1grep) >>testtrygrep 2>&1
|
||||||
|
echo "RC=$?" >>testtrygrep
|
||||||
|
|
||||||
# Now compare the results.
|
# Now compare the results.
|
||||||
|
|
||||||
|
@ -544,6 +549,10 @@ if [ $utf8 -ne 0 ] ; then
|
||||||
(cd $srcdir; $valgrind $pcre2grep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtrygrep
|
(cd $srcdir; $valgrind $pcre2grep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtrygrep
|
||||||
echo "RC=$?" >>testtrygrep
|
echo "RC=$?" >>testtrygrep
|
||||||
|
|
||||||
|
echo "---------------------------- Test U3 ------------------------------" >>testtrygrep
|
||||||
|
(cd $srcdir; $valgrind $pcre2grep --line-offsets -u '(?<=\K\x{17f})' ./testdata/grepinput8) >>testtrygrep
|
||||||
|
echo "RC=$?" >>testtrygrep
|
||||||
|
|
||||||
$cf $srcdir/testdata/grepoutput8 testtrygrep
|
$cf $srcdir/testdata/grepoutput8 testtrygrep
|
||||||
if [ $? != 0 ] ; then exit 1; fi
|
if [ $? != 0 ] ; then exit 1; fi
|
||||||
|
|
||||||
|
|
|
@ -1433,7 +1433,7 @@ Returns: TRUE if there was a match
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
match_patterns(char *matchptr, size_t length, unsigned int options,
|
match_patterns(char *matchptr, size_t length, unsigned int options,
|
||||||
int startoffset, int *mrc)
|
size_t startoffset, int *mrc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
size_t slen = length;
|
size_t slen = length;
|
||||||
|
@ -1581,12 +1581,12 @@ while (ptr < endptr)
|
||||||
{
|
{
|
||||||
int endlinelength;
|
int endlinelength;
|
||||||
int mrc = 0;
|
int mrc = 0;
|
||||||
int startoffset = 0;
|
|
||||||
unsigned int options = 0;
|
unsigned int options = 0;
|
||||||
BOOL match;
|
BOOL match;
|
||||||
char *matchptr = ptr;
|
char *matchptr = ptr;
|
||||||
char *t = ptr;
|
char *t = ptr;
|
||||||
size_t length, linelength;
|
size_t length, linelength;
|
||||||
|
size_t startoffset = 0;
|
||||||
|
|
||||||
/* At this point, ptr is at the start of a line. We need to find the length
|
/* At this point, ptr is at the start of a line. We need to find the length
|
||||||
of the subject string to pass to pcre_exec(). In multiline mode, it is the
|
of the subject string to pass to pcre_exec(). In multiline mode, it is the
|
||||||
|
@ -1729,6 +1729,8 @@ while (ptr < endptr)
|
||||||
{
|
{
|
||||||
if (!invert)
|
if (!invert)
|
||||||
{
|
{
|
||||||
|
size_t oldstartoffset;
|
||||||
|
|
||||||
if (printname != NULL) fprintf(stdout, "%s:", printname);
|
if (printname != NULL) fprintf(stdout, "%s:", printname);
|
||||||
if (number) fprintf(stdout, "%d:", linenumber);
|
if (number) fprintf(stdout, "%d:", linenumber);
|
||||||
|
|
||||||
|
@ -1772,12 +1774,23 @@ while (ptr < endptr)
|
||||||
if (printed || printname != NULL || number) fprintf(stdout, "\n");
|
if (printed || printname != NULL || number) fprintf(stdout, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare to repeat to find the next match */
|
/* Prepare to repeat to find the next match. If the pattern contained a
|
||||||
|
lookbehind that included \K, it is possible that the end of the match
|
||||||
|
might be at or before the actual starting offset we have just used. In
|
||||||
|
this case, start one character further on. */
|
||||||
|
|
||||||
match = FALSE;
|
match = FALSE;
|
||||||
if (line_buffered) fflush(stdout);
|
if (line_buffered) fflush(stdout);
|
||||||
rc = 0; /* Had some success */
|
rc = 0; /* Had some success */
|
||||||
startoffset = offsets[1]; /* Restart after the match */
|
startoffset = offsets[1]; /* Restart after the match */
|
||||||
|
oldstartoffset = pcre2_get_startchar(match_data);
|
||||||
|
if (startoffset <= oldstartoffset)
|
||||||
|
{
|
||||||
|
if (startoffset >= length) goto END_ONE_MATCH; /* Were at end */
|
||||||
|
startoffset = oldstartoffset + 1;
|
||||||
|
if (utf)
|
||||||
|
while ((matchptr[startoffset] & 0xc0) == 0x80) startoffset++;
|
||||||
|
}
|
||||||
goto ONLY_MATCHING_RESTART;
|
goto ONLY_MATCHING_RESTART;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1917,7 +1930,7 @@ while (ptr < endptr)
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
startoffset = offsets[1];
|
startoffset = offsets[1];
|
||||||
if (startoffset >= (int)linelength + endlinelength ||
|
if (startoffset >= linelength + endlinelength ||
|
||||||
!match_patterns(matchptr, length, options, startoffset, &mrc))
|
!match_patterns(matchptr, length, options, startoffset, &mrc))
|
||||||
break;
|
break;
|
||||||
FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout);
|
FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout);
|
||||||
|
@ -1973,6 +1986,7 @@ while (ptr < endptr)
|
||||||
/* Advance to after the newline and increment the line number. The file
|
/* Advance to after the newline and increment the line number. The file
|
||||||
offset to the current line is maintained in filepos. */
|
offset to the current line is maintained in filepos. */
|
||||||
|
|
||||||
|
END_ONE_MATCH:
|
||||||
ptr += linelength + endlinelength;
|
ptr += linelength + endlinelength;
|
||||||
filepos += (int)(linelength + endlinelength);
|
filepos += (int)(linelength + endlinelength);
|
||||||
linenumber++;
|
linenumber++;
|
||||||
|
|
|
@ -9,3 +9,5 @@ After 111
|
||||||
After 222
After 333
|
After 222
After 333
|
||||||
And so on and so on
|
And so on and so on
|
||||||
And so on and so on
|
And so on and so on
|
||||||
|
ſ
|
||||||
|
ſſſſſ
|
||||||
|
|
|
@ -743,3 +743,11 @@ RC=0
|
||||||
---------------------------- Test 106 -----------------------------
|
---------------------------- Test 106 -----------------------------
|
||||||
a
|
a
|
||||||
RC=0
|
RC=0
|
||||||
|
---------------------------- Test 107 -----------------------------
|
||||||
|
1:0,1
|
||||||
|
2:0,1
|
||||||
|
2:1,1
|
||||||
|
2:2,1
|
||||||
|
2:3,1
|
||||||
|
2:4,1
|
||||||
|
RC=0
|
||||||
|
|
|
@ -10,3 +10,11 @@ RC=0
|
||||||
16-After 111
|
16-After 111
|
||||||
17-After 222
18-After 333
|
17-After 222
18-After 333
|
||||||
RC=0
|
RC=0
|
||||||
|
---------------------------- Test U3 ------------------------------
|
||||||
|
12:0,2
|
||||||
|
13:0,2
|
||||||
|
13:2,2
|
||||||
|
13:4,2
|
||||||
|
13:6,2
|
||||||
|
13:8,2
|
||||||
|
RC=0
|
||||||
|
|
Loading…
Reference in New Issue