Fix buffer overflow for recursive byname back reference when duplicate names
exist.
This commit is contained in:
parent
92739ef5d8
commit
56444e9978
|
@ -115,6 +115,10 @@ discovered by the LLVM fuzzer.
|
||||||
a buffer overflow if there was more than one group with the given name. This
|
a buffer overflow if there was more than one group with the given name. This
|
||||||
bug was discovered by the LLVM fuzzer.
|
bug was discovered by the LLVM fuzzer.
|
||||||
|
|
||||||
|
29. A recursive back reference by name within a group that had the same name as
|
||||||
|
another group caused a buffer overflow. For example: /(?J)(?'d'(?'d'\g{d}))/.
|
||||||
|
This bug was discovered by the LLVM fuzzer.
|
||||||
|
|
||||||
|
|
||||||
Version 10.10 06-March-2015
|
Version 10.10 06-March-2015
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
|
@ -5946,18 +5946,34 @@ for (;; ptr++)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The name table does not exist in the first pass; instead we must
|
/* The name table does not exist in the first pass; instead we must
|
||||||
scan the list of names encountered so far in order to get the
|
scan the list of names encountered so far in order to get a number.
|
||||||
number. If the name is not found, set the value to 0 for a forward
|
If there are duplicates, there may be more than one number. For each
|
||||||
reference. */
|
one, if handling a back reference, we must check to see if it is
|
||||||
|
recursive, that is, it is inside the group that it references. A flag
|
||||||
|
is set so that the group can be made atomic. If the name is not
|
||||||
|
found, set the value of recno to 0 for a forward reference. */
|
||||||
|
|
||||||
|
recno = 0;
|
||||||
ng = cb->named_groups;
|
ng = cb->named_groups;
|
||||||
|
|
||||||
for (i = 0; i < cb->names_found; i++, ng++)
|
for (i = 0; i < cb->names_found; i++, ng++)
|
||||||
{
|
{
|
||||||
if (namelen == ng->length &&
|
if (namelen == ng->length &&
|
||||||
PRIV(strncmp)(name, ng->name, namelen) == 0)
|
PRIV(strncmp)(name, ng->name, namelen) == 0)
|
||||||
|
{
|
||||||
|
open_capitem *oc;
|
||||||
|
recno = ng->number;
|
||||||
|
if (is_recurse) break;
|
||||||
|
for (oc = cb->open_caps; oc != NULL; oc = oc->next)
|
||||||
|
{
|
||||||
|
if (oc->number == recno)
|
||||||
|
{
|
||||||
|
oc->flag = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
recno = (i < cb->names_found)? ng->number : 0;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If duplicate names are permitted, we have to allow for a named
|
/* If duplicate names are permitted, we have to allow for a named
|
||||||
reference to a duplicated name (this cannot be determined until the
|
reference to a duplicated name (this cannot be determined until the
|
||||||
|
@ -6002,8 +6018,8 @@ for (;; ptr++)
|
||||||
|
|
||||||
if (is_recurse) goto HANDLE_RECURSION;
|
if (is_recurse) goto HANDLE_RECURSION;
|
||||||
|
|
||||||
/* In the second pass we must see if the name is duplicated. If so, we
|
/* For back references, in the second pass we must see if the name is
|
||||||
generate a different opcode. */
|
duplicated. If so, we generate a different opcode. */
|
||||||
|
|
||||||
if (lengthptr == NULL && cb->dupnames)
|
if (lengthptr == NULL && cb->dupnames)
|
||||||
{
|
{
|
||||||
|
@ -6036,7 +6052,7 @@ for (;; ptr++)
|
||||||
cb->backref_map |= (recno < 32)? (1 << recno) : 1;
|
cb->backref_map |= (recno < 32)? (1 << recno) : 1;
|
||||||
if ((uint32_t)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 is, 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
|
||||||
group can be made atomic. */
|
group can be made atomic. */
|
||||||
|
|
||||||
|
@ -8050,6 +8066,7 @@ at this stage. */
|
||||||
|
|
||||||
#ifdef CALL_PRINTINT
|
#ifdef CALL_PRINTINT
|
||||||
pcre2_printint(re, stderr, TRUE);
|
pcre2_printint(re, stderr, TRUE);
|
||||||
|
fprintf(stderr, "Length=%lu Used=%lu\n", length, usedlength);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Fill in any forward references that are required. There may be repeated
|
/* Fill in any forward references that are required. There may be repeated
|
||||||
|
|
|
@ -4306,4 +4306,8 @@ a random value. /Ix
|
||||||
|
|
||||||
/$(&.+[\p{Me}].\s\xdcC*?(?(<y>))(?<!^)$C((;*?(R))+(?(R)){0,6}?|){12\x8a\X*?\x8a\x0b\xd1^9\3*+(\xc1,\k'P'\xb4)\xcc(z\z(?JJ)(?''8};(\x0b\xd1^9\?'3*+(\xc1.]k+\x0b'Pm'\xb4\xcc4'\xd1'(?''))?-%--\x95$9*\4'|\xd1(''%\x95*$9)#(?'R')3\x07?('P\xed')\\x16:;()\x1e\x10*:(?<y>)\xd1+!~:(?)''(d'E:yD!\s(?'R'\x1e;\x10:U))|')g!\xb0*){29+))#(?'P'})*?/
|
/$(&.+[\p{Me}].\s\xdcC*?(?(<y>))(?<!^)$C((;*?(R))+(?(R)){0,6}?|){12\x8a\X*?\x8a\x0b\xd1^9\3*+(\xc1,\k'P'\xb4)\xcc(z\z(?JJ)(?''8};(\x0b\xd1^9\?'3*+(\xc1.]k+\x0b'Pm'\xb4\xcc4'\xd1'(?''))?-%--\x95$9*\4'|\xd1(''%\x95*$9)#(?'R')3\x07?('P\xed')\\x16:;()\x1e\x10*:(?<y>)\xd1+!~:(?)''(d'E:yD!\s(?'R'\x1e;\x10:U))|')g!\xb0*){29+))#(?'P'})*?/
|
||||||
|
|
||||||
|
"\xa\xf<(.\pZ*\P{Xwd}+^\xa8\3'3yq.::?(?J:()\xd1+!~:3'(8?:)':(?'d'(?'d'^u]!.+.+\\A\Ah(n+?9){7}+\K;(?''u'(?'c'(?'z'(?<y>\xb::\xf0'|\xd3(\xae?'w(z\x8?P>l)\x8?P>a)'\H\R\xd1+!!~:3'(?:h$N{26875}\W+?\\=D{2}\x89(?i:Uy0\N({2\xa(\v\x85*){y*\A(()\p{L}+?\P{^Xan}'+?\xff\+pS\?|).{;y*\A(()\p{L}+?\8}\d?1(|)(/1){7}.+[Lp{Me}].\s\xdcC*?(?(<y>))(?<!^)$C((;*?(R))+(\xbf(R))\x8a\X*?\x8a\xb\xd1^9\3*+(\xc1,\k'R'\xb4)\xcc(z\z(?J)(?''\x1b(\xb\xd1^9\?'3*+P{^Xan}+?\xff\+(\xc1.]k+\xb'Pm'\xb4)\xcc4f\xa7'\xd1V(?i:U,{2,2})'(?''))?-%--\x95$9*\4'|\xd1(\x9c''%\x94$9)#(?'R')3\x7?('P\xed7'\xa8\xb1^u\xeaw\1\0\0\(|(?1){7}.+[\p{Me}].\s\xdcC*^\x14?(?(<y>))(?<!^)$C((;*?(R*?))+(?(R)\x8a\X*?\x8a\xb\xd1^9\3*+|(\xc1,\k'R'\xb4)\xcc! z)\z(?JJ)(?'';(\xb\xd1^9\?'3*+(\xc1.]k+\xb'Pm'\xb4))':(?'d')(?'RD'(d')|)|$)'|(?<x>\g{d});\g{x}\x11\g{d}\x81\|$((?''\'X'(?'W''\x92()'9'\x83*))\xba*\!?^ <){)':;\xcc4'\xd1'(?''28))?-%--\x95$9*\4'|\xd1((''e\x94*$9:)*#(?'R')3)\x7?('P\xed')\\x16:;()\x1e\x10*:(?<y>)\xd1+0!~:(?)'d'E:yD!\s(?'R'\x1e;\x10:U))|'\x9g!\xb0*){)\\x16:;()\x1e\x10\x87*:(?<y>)\xd1+!~:(?)'}'\d'E:yD!\s(?'R'\x1e;\x10:U))|'))|)g!\xb0*R+9{29+)#(?'P'})*?pS\{3,}\x85,{0,}l{*UTF)(\xe{7}){3722,{9,}d{2,?|))|{)\(A?&d}}{\xa,}2}){3,}7,l{)22}(,}l:7{2,4}}29\x19+)#?'P'})*v?))\x5"
|
||||||
|
|
||||||
|
"(?J)(?'d'(?'d'\g{d}))"
|
||||||
|
|
||||||
# End of testinput2
|
# End of testinput2
|
||||||
|
|
|
@ -14405,4 +14405,9 @@ Failed: error 115 at offset 26: reference to non-existent subpattern
|
||||||
|
|
||||||
/$(&.+[\p{Me}].\s\xdcC*?(?(<y>))(?<!^)$C((;*?(R))+(?(R)){0,6}?|){12\x8a\X*?\x8a\x0b\xd1^9\3*+(\xc1,\k'P'\xb4)\xcc(z\z(?JJ)(?''8};(\x0b\xd1^9\?'3*+(\xc1.]k+\x0b'Pm'\xb4\xcc4'\xd1'(?''))?-%--\x95$9*\4'|\xd1(''%\x95*$9)#(?'R')3\x07?('P\xed')\\x16:;()\x1e\x10*:(?<y>)\xd1+!~:(?)''(d'E:yD!\s(?'R'\x1e;\x10:U))|')g!\xb0*){29+))#(?'P'})*?/
|
/$(&.+[\p{Me}].\s\xdcC*?(?(<y>))(?<!^)$C((;*?(R))+(?(R)){0,6}?|){12\x8a\X*?\x8a\x0b\xd1^9\3*+(\xc1,\k'P'\xb4)\xcc(z\z(?JJ)(?''8};(\x0b\xd1^9\?'3*+(\xc1.]k+\x0b'Pm'\xb4\xcc4'\xd1'(?''))?-%--\x95$9*\4'|\xd1(''%\x95*$9)#(?'R')3\x07?('P\xed')\\x16:;()\x1e\x10*:(?<y>)\xd1+!~:(?)''(d'E:yD!\s(?'R'\x1e;\x10:U))|')g!\xb0*){29+))#(?'P'})*?/
|
||||||
|
|
||||||
|
"\xa\xf<(.\pZ*\P{Xwd}+^\xa8\3'3yq.::?(?J:()\xd1+!~:3'(8?:)':(?'d'(?'d'^u]!.+.+\\A\Ah(n+?9){7}+\K;(?''u'(?'c'(?'z'(?<y>\xb::\xf0'|\xd3(\xae?'w(z\x8?P>l)\x8?P>a)'\H\R\xd1+!!~:3'(?:h$N{26875}\W+?\\=D{2}\x89(?i:Uy0\N({2\xa(\v\x85*){y*\A(()\p{L}+?\P{^Xan}'+?\xff\+pS\?|).{;y*\A(()\p{L}+?\8}\d?1(|)(/1){7}.+[Lp{Me}].\s\xdcC*?(?(<y>))(?<!^)$C((;*?(R))+(\xbf(R))\x8a\X*?\x8a\xb\xd1^9\3*+(\xc1,\k'R'\xb4)\xcc(z\z(?J)(?''\x1b(\xb\xd1^9\?'3*+P{^Xan}+?\xff\+(\xc1.]k+\xb'Pm'\xb4)\xcc4f\xa7'\xd1V(?i:U,{2,2})'(?''))?-%--\x95$9*\4'|\xd1(\x9c''%\x94$9)#(?'R')3\x7?('P\xed7'\xa8\xb1^u\xeaw\1\0\0\(|(?1){7}.+[\p{Me}].\s\xdcC*^\x14?(?(<y>))(?<!^)$C((;*?(R*?))+(?(R)\x8a\X*?\x8a\xb\xd1^9\3*+|(\xc1,\k'R'\xb4)\xcc! z)\z(?JJ)(?'';(\xb\xd1^9\?'3*+(\xc1.]k+\xb'Pm'\xb4))':(?'d')(?'RD'(d')|)|$)'|(?<x>\g{d});\g{x}\x11\g{d}\x81\|$((?''\'X'(?'W''\x92()'9'\x83*))\xba*\!?^ <){)':;\xcc4'\xd1'(?''28))?-%--\x95$9*\4'|\xd1((''e\x94*$9:)*#(?'R')3)\x7?('P\xed')\\x16:;()\x1e\x10*:(?<y>)\xd1+0!~:(?)'d'E:yD!\s(?'R'\x1e;\x10:U))|'\x9g!\xb0*){)\\x16:;()\x1e\x10\x87*:(?<y>)\xd1+!~:(?)'}'\d'E:yD!\s(?'R'\x1e;\x10:U))|'))|)g!\xb0*R+9{29+)#(?'P'})*?pS\{3,}\x85,{0,}l{*UTF)(\xe{7}){3722,{9,}d{2,?|))|{)\(A?&d}}{\xa,}2}){3,}7,l{)22}(,}l:7{2,4}}29\x19+)#?'P'})*v?))\x5"
|
||||||
|
Failed: error 122 at offset 1221: unmatched closing parenthesis
|
||||||
|
|
||||||
|
"(?J)(?'d'(?'d'\g{d}))"
|
||||||
|
|
||||||
# End of testinput2
|
# End of testinput2
|
||||||
|
|
Loading…
Reference in New Issue