From b15698b077ff69f24b7cb31e1cb2ab539ffc5d22 Mon Sep 17 00:00:00 2001 From: "Philip.Hazel" Date: Fri, 20 Mar 2015 12:37:28 +0000 Subject: [PATCH] Fix data overrun for /(?(?C)/ --- ChangeLog | 4 ++++ src/pcre2_compile.c | 13 +++++++++++-- src/pcre2_error.c | 2 +- src/pcre2posix.c | 4 ++-- testdata/testinput17 | 2 ++ testdata/testoutput17 | 3 +++ testdata/testoutput2 | 4 ++-- 7 files changed, 25 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 692fcf6..4938a94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,10 @@ Version 10.20 xx-xx-2015 2. Assertion code generator in JIT has been optimized. +3. The invalid pattern (?(?C) has a missing assertion condition at the end. The +pcre2_compile() function read past the end of the input before diagnosing an +error. + Version 10.10 06-March-2015 --------------------------- diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index ee167d4..2d958b1 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -5248,10 +5248,19 @@ for (;; ptr++) if (ptr[i+1] == CHAR_RIGHT_PARENTHESIS) tempptr += i + 2; break; } - } + } } } } + + /* tempptr should now be pointing to the opening parenthesis of the + assertion condition. */ + + if (*tempptr != CHAR_LEFT_PARENTHESIS) + { + *errorcodeptr = ERR28; + goto FAILED; + } } /* For conditions that are assertions, check the syntax, and then exit @@ -5657,7 +5666,7 @@ for (;; ptr++) /* In the real compile we can copy the string, knowing that it is syntactically OK. The starting delimiter is included so that the - client can discover it if they want. We also pass the start offset to + client can discover it if they want. We also pass the start offset to help a script language give better error messages. */ else diff --git a/src/pcre2_error.c b/src/pcre2_error.c index c67b5f5..59d89bd 100644 --- a/src/pcre2_error.c +++ b/src/pcre2_error.c @@ -97,7 +97,7 @@ static const char compile_error_texts[] = "lookbehind assertion is not fixed length\0" "malformed number or name after (?(\0" "conditional group contains more than two branches\0" - "assertion expected after (?(\0" + "assertion expected after (?( or (?(?C)\0" "(?R or (?[+-]digits must be followed by )\0" /* 30 */ "unknown POSIX class name\0" diff --git a/src/pcre2posix.c b/src/pcre2posix.c index e57b882..da212fc 100644 --- a/src/pcre2posix.c +++ b/src/pcre2posix.c @@ -216,8 +216,8 @@ if ((cflags & REG_UTF) != 0) options |= PCRE2_UTF; if ((cflags & REG_UCP) != 0) options |= PCRE2_UCP; if ((cflags & REG_UNGREEDY) != 0) options |= PCRE2_UNGREEDY; -preg->re_pcre2_code = pcre2_compile((PCRE2_SPTR)pattern, -1, options, - &errorcode, &erroffset, NULL); +preg->re_pcre2_code = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, + options, &errorcode, &erroffset, NULL); preg->re_erroffset = erroffset; if (preg->re_pcre2_code == NULL) diff --git a/testdata/testinput17 b/testdata/testinput17 index 01f8d9d..d636d38 100644 --- a/testdata/testinput17 +++ b/testdata/testinput17 @@ -90,4 +90,6 @@ /abc/\ +"(?(?C)" + # End of testdata/testinput16 diff --git a/testdata/testoutput17 b/testdata/testoutput17 index 9cfe3d9..f46b7e7 100644 --- a/testdata/testoutput17 +++ b/testdata/testoutput17 @@ -142,4 +142,7 @@ No match: POSIX code 17: match failed /abc/\ Failed: POSIX code 9: bad escape sequence at offset 4 +"(?(?C)" +Failed: POSIX code 3: pattern error at offset 2 + # End of testdata/testinput16 diff --git a/testdata/testoutput2 b/testdata/testoutput2 index 357e0c7..02415e9 100644 --- a/testdata/testoutput2 +++ b/testdata/testoutput2 @@ -567,7 +567,7 @@ Failed: error 126 at offset 4: malformed number or name after (?( Failed: error 126 at offset 4: malformed number or name after (?( /(?(?i))/ -Failed: error 128 at offset 3: assertion expected after (?( +Failed: error 128 at offset 3: assertion expected after (?( or (?(?C) /(?(abc))/ Failed: error 115 at offset 7: reference to non-existent subpattern @@ -7367,7 +7367,7 @@ No match Failed: error 126 at offset 6: malformed number or name after (?( /(?(''))/ -Failed: error 128 at offset 4: assertion expected after (?( +Failed: error 128 at offset 4: assertion expected after (?( or (?(?C) /(?('R')stuff)/ Failed: error 115 at offset 7: reference to non-existent subpattern