From c372df5dce00be7d366f7d6928983a0b17238eaa Mon Sep 17 00:00:00 2001 From: "Philip.Hazel" Date: Sun, 1 Mar 2015 18:34:05 +0000 Subject: [PATCH] Fix compile error for forward reference subroutine call within a group that also contained a recursive back reference. --- ChangeLog | 5 +++++ src/pcre2_compile.c | 5 ++++- testdata/testinput2 | 4 +++- testdata/testinput8 | 2 ++ testdata/testoutput2 | 17 ++++++++++++++++- testdata/testoutput8-16 | 15 +++++++++++++++ testdata/testoutput8-32 | 15 +++++++++++++++ testdata/testoutput8-8 | 15 +++++++++++++++ 8 files changed, 75 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index dac9710..1b77d2e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -105,6 +105,11 @@ referenced subpattern not found" when an incorrect memory address was read. This bug was reported as "heap overflow", discovered by Kai Lu of Fortinet's FortiGuard Labs. +23. A pattern such as "((?+1)(\1))/" containing a forward reference subroutine +call within a group that also contained a recursive back reference caused +incorrect code to be compiled. This bug was reported as "heap overflow", +discovered by Kai Lu of Fortinet's FortiGuard Labs. + Version 10.00 05-January-2015 ----------------------------- diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index 1ebd415..280c3d0 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -6713,6 +6713,7 @@ int32_t firstcuflags, reqcuflags; uint32_t branchfirstcu, branchreqcu; int32_t branchfirstcuflags, branchreqcuflags; size_t length; +size_t save_hwm_offset; unsigned int orig_bracount; unsigned int max_bracount; branch_chain bc; @@ -6734,6 +6735,8 @@ bc.current_branch = code; firstcu = reqcu = 0; firstcuflags = reqcuflags = REQ_UNSET; +save_hwm_offset = cb->hwm - cb->start_workspace; /* hwm at start of group */ + /* Accumulate the length for use in the pre-compile phase. Start with the length of the BRA and KET and any extra code units that are required at the beginning. We accumulate in a local variable to save frequent testing of @@ -6939,7 +6942,7 @@ for (;;) { *code = OP_END; adjust_recurse(start_bracket, 1 + LINK_SIZE, - (options & PCRE2_UTF) != 0, cb, cb->hwm - cb->start_workspace); + (options & PCRE2_UTF) != 0, cb, save_hwm_offset); memmove(start_bracket + 1 + LINK_SIZE, start_bracket, CU2BYTES(code - start_bracket)); *start_bracket = OP_ONCE; diff --git a/testdata/testinput2 b/testdata/testinput2 index 58b47d0..b264415 100644 --- a/testdata/testinput2 +++ b/testdata/testinput2 @@ -4172,8 +4172,10 @@ a random value. /Ix g g\=ovector=1 -# This pattern showed up a compile-time bug +# These two pattern showeds up compile-time bugs "((?2){0,1999}())?" +/((?+1)(\1))/B + # End of testinput2 diff --git a/testdata/testinput8 b/testdata/testinput8 index b781518..d1d62fe 100644 --- a/testdata/testinput8 +++ b/testdata/testinput8 @@ -138,4 +138,6 @@ /(((a\2)|(a*)\g<-1>))*a?/ +/((?+1)(\1))/ + # End of testinput8 diff --git a/testdata/testoutput2 b/testdata/testoutput2 index e695c1a..ba7c05f 100644 --- a/testdata/testoutput2 +++ b/testdata/testoutput2 @@ -13950,8 +13950,23 @@ Matched, but too many substrings Matched, but too many substrings 0: g -# This pattern showed up a compile-time bug +# These two pattern showeds up compile-time bugs "((?2){0,1999}())?" +/((?+1)(\1))/B +------------------------------------------------------------------ + Bra + Once + CBra 1 + Recurse + CBra 2 + \1 + Ket + Ket + Ket + Ket + End +------------------------------------------------------------------ + # End of testinput2 diff --git a/testdata/testoutput8-16 b/testdata/testoutput8-16 index 69fc783..354f2a4 100644 --- a/testdata/testoutput8-16 +++ b/testdata/testoutput8-16 @@ -739,4 +739,19 @@ Memory allocation (code space): 14 41 End ------------------------------------------------------------------ +/((?+1)(\1))/ +------------------------------------------------------------------ + 0 20 Bra + 2 16 Once + 4 12 CBra 1 + 7 9 Recurse + 9 5 CBra 2 + 12 \1 + 14 5 Ket + 16 12 Ket + 18 16 Ket + 20 20 Ket + 22 End +------------------------------------------------------------------ + # End of testinput8 diff --git a/testdata/testoutput8-32 b/testdata/testoutput8-32 index e803b78..b4ca6d2 100644 --- a/testdata/testoutput8-32 +++ b/testdata/testoutput8-32 @@ -739,4 +739,19 @@ Memory allocation (code space): 28 41 End ------------------------------------------------------------------ +/((?+1)(\1))/ +------------------------------------------------------------------ + 0 20 Bra + 2 16 Once + 4 12 CBra 1 + 7 9 Recurse + 9 5 CBra 2 + 12 \1 + 14 5 Ket + 16 12 Ket + 18 16 Ket + 20 20 Ket + 22 End +------------------------------------------------------------------ + # End of testinput8 diff --git a/testdata/testoutput8-8 b/testdata/testoutput8-8 index 9cbfdaa..6bdbd98 100644 --- a/testdata/testoutput8-8 +++ b/testdata/testoutput8-8 @@ -739,4 +739,19 @@ Memory allocation (code space): 10 60 End ------------------------------------------------------------------ +/((?+1)(\1))/ +------------------------------------------------------------------ + 0 31 Bra + 3 25 Once + 6 19 CBra 1 + 11 14 Recurse + 14 8 CBra 2 + 19 \1 + 22 8 Ket + 25 19 Ket + 28 25 Ket + 31 31 Ket + 34 End +------------------------------------------------------------------ + # End of testinput8