Fix issue with \Q\E after a callout before an assertion condition.

This commit is contained in:
Philip.Hazel 2016-12-28 12:26:12 +00:00
parent fdf7946ee0
commit f676362977
4 changed files with 26 additions and 8 deletions

View File

@ -41,6 +41,9 @@ some minor bugs and Perl incompatibilities were fixed, including:
(g) A hyphen appearing immediately after a POSIX character class (for example (g) A hyphen appearing immediately after a POSIX character class (for example
/[[:ascii:]-z]/) now generates an error. Perl does accept this as a /[[:ascii:]-z]/) now generates an error. Perl does accept this as a
literal, but gives a warning, so it seems best to fail it in PCRE. literal, but gives a warning, so it seems best to fail it in PCRE.
(h) An empty \Q\E sequence may appear after a callout that precedes an
assertion condition (it is, of course, ignored).
One effect of the refactoring is that some error numbers and messages have One effect of the refactoring is that some error numbers and messages have
changed, and the pattern offset given for compiling errors is not always the changed, and the pattern offset given for compiling errors is not always the

View File

@ -2321,6 +2321,12 @@ while (ptr < ptrend)
} }
else else
{ {
if (expect_cond_assert > 0) /* A literal is not allowed if we are */
{ /* expecting a conditional assertion, */
ptr--; /* but an empty \Q\E sequence is OK. */
errorcode = ERR28;
goto FAILED;
}
if (!inverbname && after_manual_callout-- <= 0) if (!inverbname && after_manual_callout-- <= 0)
parsed_pattern = manage_callouts(thisptr, &previous_callout, options, parsed_pattern = manage_callouts(thisptr, &previous_callout, options,
parsed_pattern, cb); parsed_pattern, cb);
@ -2992,17 +2998,17 @@ while (ptr < ptrend)
goto FAILED; goto FAILED;
} }
ptr = tempptr + 2; ptr = tempptr + 2;
/* Perl treats a hyphen after a POSIX class as a literal, not the /* Perl treats a hyphen after a POSIX class as a literal, not the
start of a range. However, it gives a warning in its warning mode. PCRE start of a range. However, it gives a warning in its warning mode. PCRE
does not have a warning mode, so we give an error, because this is does not have a warning mode, so we give an error, because this is
likely an error on the user's part. */ likely an error on the user's part. */
if (ptr < ptrend && *ptr == CHAR_MINUS) if (ptr < ptrend && *ptr == CHAR_MINUS)
{ {
errorcode = ERR50; errorcode = ERR50;
goto FAILED; goto FAILED;
} }
/* When PCRE2_UCP is set, some of the POSIX classes are converted to /* When PCRE2_UCP is set, some of the POSIX classes are converted to
use Unicode properties \p or \P or, in one case, \h or \H. The use Unicode properties \p or \P or, in one case, \h or \H. The
@ -4938,13 +4944,13 @@ for (;; pptr++)
automatically handled by the use of OP_CLASS or OP_NCLASS, but an automatically handled by the use of OP_CLASS or OP_NCLASS, but an
explicit range is needed for OP_XCLASS. Setting a flag here explicit range is needed for OP_XCLASS. Setting a flag here
causes the range to be generated later when it is known that causes the range to be generated later when it is known that
OP_XCLASS is required. In the 8-bit library this is relevant only in OP_XCLASS is required. In the 8-bit library this is relevant only in
utf mode, since no wide characters can exist otherwise. */ utf mode, since no wide characters can exist otherwise. */
default: default:
#if PCRE2_CODE_UNIT_WIDTH == 8 #if PCRE2_CODE_UNIT_WIDTH == 8
if (utf) if (utf)
#endif #endif
match_all_or_no_wide_chars |= local_negate; match_all_or_no_wide_chars |= local_negate;
break; break;
} }
@ -7941,7 +7947,7 @@ Arguments:
Returns: new value of pptr Returns: new value of pptr
NULL if META_END is reached - should never occur NULL if META_END is reached - should never occur
or for an unknown meta value - likewise or for an unknown meta value - likewise
*/ */
static uint32_t * static uint32_t *
@ -7952,7 +7958,7 @@ uint32_t nestlevel = 0;
for (pptr += 1;; pptr++) for (pptr += 1;; pptr++)
{ {
uint32_t meta = META_CODE(*pptr); uint32_t meta = META_CODE(*pptr);
switch(meta) switch(meta)
{ {
default: /* Just skip over most items */ default: /* Just skip over most items */
@ -8517,7 +8523,7 @@ cb->erroroffset = PCRE2_UNSET;
for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++) for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++)
{ {
if (*pptr < META_END) continue; /* Literal */ if (*pptr < META_END) continue; /* Literal */
switch (META_CODE(*pptr)) switch (META_CODE(*pptr))
{ {
default: default:

4
testdata/testinput2 vendored
View File

@ -4952,4 +4952,8 @@ a)"xI
/[:[:alnum:]-[[a:lnum:]+/ /[:[:alnum:]-[[a:lnum:]+/
/((?(?C'')\QX\E(?!((?(?C'')(?!X=X));=)r*X=X));=)/
/((?(?C'')\Q\E(?!((?(?C'')(?!X=X));=)r*X=X));=)/
# End of testinput2 # End of testinput2

View File

@ -15434,6 +15434,11 @@ Failed: error 128 at offset 63: assertion expected after (?( or (?(?C)
/[:[:alnum:]-[[a:lnum:]+/ /[:[:alnum:]-[[a:lnum:]+/
Failed: error 150 at offset 11: invalid range in character class Failed: error 150 at offset 11: invalid range in character class
/((?(?C'')\QX\E(?!((?(?C'')(?!X=X));=)r*X=X));=)/
Failed: error 128 at offset 11: assertion expected after (?( or (?(?C)
/((?(?C'')\Q\E(?!((?(?C'')(?!X=X));=)r*X=X));=)/
# End of testinput2 # End of testinput2
Error -63: PCRE2_ERROR_BADDATA (unknown error number) Error -63: PCRE2_ERROR_BADDATA (unknown error number)
Error -62: bad serialized data Error -62: bad serialized data