Fix diagnosis of negative relative references to non-existent groups.
This commit is contained in:
parent
2327a5860b
commit
6a2cb0d774
|
@ -55,6 +55,10 @@ a fixed maximum following a group that contains a subroutine reference was
|
||||||
incorrectly compiled and could trigger buffer overflow. This bug was discovered
|
incorrectly compiled and could trigger buffer overflow. This bug was discovered
|
||||||
by the LLVM fuzzer.
|
by the LLVM fuzzer.
|
||||||
|
|
||||||
|
14. Negative relative recursive references such as (?-7) to non-existent
|
||||||
|
subpatterns were not being diagnosed and could lead to unpredictable behaviour.
|
||||||
|
This bug was discovered by the LLVM fuzzer.
|
||||||
|
|
||||||
|
|
||||||
Version 10.10 06-March-2015
|
Version 10.10 06-March-2015
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
|
@ -3179,15 +3179,15 @@ for (;; ptr++)
|
||||||
BOOL xclass_has_prop;
|
BOOL xclass_has_prop;
|
||||||
#endif
|
#endif
|
||||||
int newoptions;
|
int newoptions;
|
||||||
uint32_t recno;
|
int recno; /* Must be signed */
|
||||||
int refsign;
|
int refsign; /* Must be signed */
|
||||||
int skipbytes;
|
int skipbytes;
|
||||||
uint32_t subreqcu, subfirstcu;
|
|
||||||
int32_t subreqcuflags, subfirstcuflags;
|
|
||||||
int terminator;
|
int terminator;
|
||||||
unsigned int mclength;
|
unsigned int mclength;
|
||||||
unsigned int tempbracount;
|
unsigned int tempbracount;
|
||||||
uint32_t ec;
|
uint32_t ec;
|
||||||
|
uint32_t subreqcu, subfirstcu;
|
||||||
|
int32_t subreqcuflags, subfirstcuflags; /* Must be signed */
|
||||||
PCRE2_UCHAR mcbuffer[8];
|
PCRE2_UCHAR mcbuffer[8];
|
||||||
|
|
||||||
/* Get next character in the pattern */
|
/* Get next character in the pattern */
|
||||||
|
@ -5443,13 +5443,13 @@ for (;; ptr++)
|
||||||
}
|
}
|
||||||
if (refsign != 0) recno = (refsign == CHAR_MINUS)?
|
if (refsign != 0) recno = (refsign == CHAR_MINUS)?
|
||||||
cb->bracount - recno + 1 : recno + cb->bracount;
|
cb->bracount - recno + 1 : recno + cb->bracount;
|
||||||
if (recno <= 0 || recno > cb->final_bracount)
|
if (recno <= 0 || (uint32_t)recno > cb->final_bracount)
|
||||||
{
|
{
|
||||||
*errorcodeptr = ERR15;
|
*errorcodeptr = ERR15;
|
||||||
goto FAILED;
|
goto FAILED;
|
||||||
}
|
}
|
||||||
PUT2(code, 2+LINK_SIZE, recno);
|
PUT2(code, 2+LINK_SIZE, recno);
|
||||||
if (recno > cb->top_backref) cb->top_backref = recno;
|
if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5475,7 +5475,7 @@ for (;; ptr++)
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
recno = GET2(slot, 0); /* Number for last found */
|
recno = GET2(slot, 0); /* Number for last found */
|
||||||
if (recno > cb->top_backref) cb->top_backref = recno;
|
if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno;
|
||||||
count++;
|
count++;
|
||||||
if (++i >= cb->names_found) break;
|
if (++i >= cb->names_found) break;
|
||||||
slot += cb->name_entry_size;
|
slot += cb->name_entry_size;
|
||||||
|
@ -6000,7 +6000,7 @@ for (;; ptr++)
|
||||||
open_capitem *oc;
|
open_capitem *oc;
|
||||||
recno = GET2(slot, 0);
|
recno = GET2(slot, 0);
|
||||||
cb->backref_map |= (recno < 32)? (1 << recno) : 1;
|
cb->backref_map |= (recno < 32)? (1 << recno) : 1;
|
||||||
if (recno > cb->top_backref) cb->top_backref = recno;
|
if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno;
|
||||||
|
|
||||||
/* Check to see if this back reference is recursive, that it, it
|
/* Check to see if this back reference is recursive, that it, it
|
||||||
is inside the group that it references. A flag is set so that the
|
is inside the group that it references. A flag is set so that the
|
||||||
|
@ -6121,7 +6121,7 @@ for (;; ptr++)
|
||||||
|
|
||||||
if (called == NULL)
|
if (called == NULL)
|
||||||
{
|
{
|
||||||
if (recno > cb->final_bracount)
|
if ((uint32_t)recno > cb->final_bracount)
|
||||||
{
|
{
|
||||||
*errorcodeptr = ERR15;
|
*errorcodeptr = ERR15;
|
||||||
goto FAILED;
|
goto FAILED;
|
||||||
|
@ -6626,7 +6626,7 @@ for (;; ptr++)
|
||||||
*code++ = ((options & PCRE2_CASELESS) != 0)? OP_REFI : OP_REF;
|
*code++ = ((options & PCRE2_CASELESS) != 0)? OP_REFI : OP_REF;
|
||||||
PUT2INC(code, 0, recno);
|
PUT2INC(code, 0, recno);
|
||||||
cb->backref_map |= (recno < 32)? (1 << recno) : 1;
|
cb->backref_map |= (recno < 32)? (1 << recno) : 1;
|
||||||
if (recno > cb->top_backref) cb->top_backref = recno;
|
if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno;
|
||||||
|
|
||||||
/* Check to see if this back reference is recursive, that it, it
|
/* Check to see if this back reference is recursive, that it, it
|
||||||
is inside the group that it references. A flag is set so that the
|
is inside the group that it references. A flag is set so that the
|
||||||
|
|
|
@ -4249,4 +4249,8 @@ a random value. /Ix
|
||||||
|
|
||||||
"X((?2)()*+){2}"B
|
"X((?2)()*+){2}"B
|
||||||
|
|
||||||
|
/(?<=\bABQ(3(?-7)))/
|
||||||
|
|
||||||
|
/(?<=\bABQ(3(?+7)))/
|
||||||
|
|
||||||
# End of testinput2
|
# End of testinput2
|
||||||
|
|
|
@ -14251,4 +14251,10 @@ Failed: error 128 at offset 3: assertion expected after (?( or (?(?C)
|
||||||
End
|
End
|
||||||
------------------------------------------------------------------
|
------------------------------------------------------------------
|
||||||
|
|
||||||
|
/(?<=\bABQ(3(?-7)))/
|
||||||
|
Failed: error 115 at offset 15: reference to non-existent subpattern
|
||||||
|
|
||||||
|
/(?<=\bABQ(3(?+7)))/
|
||||||
|
Failed: error 115 at offset 15: reference to non-existent subpattern
|
||||||
|
|
||||||
# End of testinput2
|
# End of testinput2
|
||||||
|
|
Loading…
Reference in New Issue