From eea35d0cab4c4751c5e24d54428f6c51bf072afb Mon Sep 17 00:00:00 2001 From: "Philip.Hazel" Date: Wed, 19 Nov 2014 11:17:20 +0000 Subject: [PATCH] Fix zero-repeated assertion-as-condition bug. --- ChangeLog | 3 +++ src/pcre2_match.c | 7 +++++-- testdata/testinput2 | 6 ++++++ testdata/testoutput2 | 10 ++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8e67b5f..5f548bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -53,4 +53,7 @@ matched against "abcd". 8. The pcre2_substitute() function has been implemented. +9. If an assertion condition was quantified with a minimum of zero (an odd +thing to do, but it happened), SIGSEGV or other misbehaviour could occur. + **** diff --git a/src/pcre2_match.c b/src/pcre2_match.c index 0699895..f03f3ed 100644 --- a/src/pcre2_match.c +++ b/src/pcre2_match.c @@ -1401,8 +1401,11 @@ for (;;) condition = TRUE; /* Advance ecode past the assertion to the start of the first branch, - but adjust it so that the general choosing code below works. */ - + but adjust it so that the general choosing code below works. If the + assertion has a quantifier that allows zero repeats we must skip over + the BRAZERO. This is a lunatic thing to do, but somebody did! */ + + if (*ecode == OP_BRAZERO) ecode++; ecode += GET(ecode, 1); while (*ecode == OP_ALT) ecode += GET(ecode, 1); ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode]; diff --git a/testdata/testinput2 b/testdata/testinput2 index 3c547d2..e318fac 100644 --- a/testdata/testinput2 +++ b/testdata/testinput2 @@ -4078,4 +4078,10 @@ a random value. /Ix # End of substitute tests +"((?=(?(?=(?(?=(?(?=())))*)))))" + a + +"(?(?=)?==)(((((((((?=)))))))))" + a + # End of testinput2 diff --git a/testdata/testoutput2 b/testdata/testoutput2 index 7b72388..861741a 100644 --- a/testdata/testoutput2 +++ b/testdata/testoutput2 @@ -13705,4 +13705,14 @@ Failed: error -34: bad option value # End of substitute tests +"((?=(?(?=(?(?=(?(?=())))*)))))" + a + 0: + 1: + 2: + +"(?(?=)?==)(((((((((?=)))))))))" + a +No match + # End of testinput2