diff --git a/ChangeLog b/ChangeLog index a6cc7fa..c229469 100644 --- a/ChangeLog +++ b/ChangeLog @@ -111,6 +111,10 @@ incorrect code to be compiled when recursive forward references were involved. For example, in this pattern: /(?1)()((((((\1++))\x85)+)|))/. This bug was discovered by the LLVM fuzzer. +28. A repeated conditional group whose condition was a reference by name caused +a buffer overflow if there was more than one group with the given name. This +bug was discovered by the LLVM fuzzer. + Version 10.10 06-March-2015 --------------------------- diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index 99ee415..17f3d06 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -5425,7 +5425,8 @@ for (;; ptr++) the referenced name is one of a number of duplicates, a different opcode is used and it needs more memory. Unfortunately we cannot tell whether this is the case in the first pass, so we have to allow for - more memory always. */ + more memory always. In the second pass, the additional to skipunits + happens later. */ else { @@ -5445,7 +5446,7 @@ for (;; ptr++) ptr++; } namelen = (int)(ptr - name); - if (lengthptr != NULL) *lengthptr += IMM2_SIZE; + if (lengthptr != NULL) skipunits += IMM2_SIZE; } /* Check the terminator */ @@ -8010,8 +8011,6 @@ if (cb.names_found > 0) error, errorcode will be set non-zero, so we don't need to look at the result of the function here. */ -/* fprintf(stderr, "+++\n\nPASS TWO\n"); */ - ptr = pattern + skipatstart; code = (PCRE2_UCHAR *)codestart; *code = OP_BRA; @@ -8068,9 +8067,6 @@ if (cb.hwm > cb.start_workspace) cb.hwm -= LINK_SIZE; offset = GET(cb.hwm, 0); recno = GET(codestart, offset); - -/* fprintf(stderr, "+++offset=%d recno=%d\n", offset, recno); */ - if (recno != prev_recno) { groupptr = PRIV(find_bracket)(codestart, utf, recno); diff --git a/testdata/testinput2 b/testdata/testinput2 index 4e1d2f8..0869e08 100644 --- a/testdata/testinput2 +++ b/testdata/testinput2 @@ -4298,4 +4298,12 @@ a random value. /Ix /\V\x85\9*+((?2)\3++()2)*:2/ +/(((?(R)){0,2}) (?''((?'R')((?'R')))))/dupnames + +/(((?(X)){0,2}) (?''((?'X')((?'X')))))/dupnames + +/(((?(R)){0,2}) (?''((?'X')((?'R')))))/ + +/$(&.+[\p{Me}].\s\xdcC*?(?())(?)\xd1+!~:(?)''(d'E:yD!\s(?'R'\x1e;\x10:U))|')g!\xb0*){29+))#(?'P'})*?/ + # End of testinput2 diff --git a/testdata/testoutput2 b/testdata/testoutput2 index 2d0f0eb..ecabe2c 100644 --- a/testdata/testoutput2 +++ b/testdata/testoutput2 @@ -14397,4 +14397,12 @@ Failed: error 115 at offset 22: reference to non-existent subpattern /\V\x85\9*+((?2)\3++()2)*:2/ Failed: error 115 at offset 26: reference to non-existent subpattern +/(((?(R)){0,2}) (?''((?'R')((?'R')))))/dupnames + +/(((?(X)){0,2}) (?''((?'X')((?'X')))))/dupnames + +/(((?(R)){0,2}) (?''((?'X')((?'R')))))/ + +/$(&.+[\p{Me}].\s\xdcC*?(?())(?)\xd1+!~:(?)''(d'E:yD!\s(?'R'\x1e;\x10:U))|')g!\xb0*){29+))#(?'P'})*?/ + # End of testinput2