From 688151205d393f1a64515be46facf4d30d358e40 Mon Sep 17 00:00:00 2001 From: "Philip.Hazel" Date: Tue, 21 Jul 2015 14:03:08 +0000 Subject: [PATCH] Fix not diagnosis of missing ) for callout with string argument. --- ChangeLog | 3 ++ src/pcre2_compile.c | 65 ++++++++++++++++++++++++-------------------- testdata/testinput5 | 2 ++ testdata/testoutput5 | 3 ++ 4 files changed, 43 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6279995..e6afed9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -62,6 +62,9 @@ first of these bugs was discovered by Karl Skomski with the LLVM fuzzer. pcre2_compile() to run for a very long time. This bug was found by the LLVM fuzzer. +17. A missing closing parenthesis for a callout with a string argument was not +being diagnosed, possibly leading to a buffer overflow. This bug was found by +the LLVM fuzzer. Version 10.20 30-June-2015 diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index b9f7e7f..940f693 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -3277,46 +3277,51 @@ for (; ptr < cb->end_pattern; ptr++) if (IS_DIGIT(ptr[1])) { while (IS_DIGIT(ptr[1])) ptr++; - if (ptr[1] != CHAR_RIGHT_PARENTHESIS) - { - errorcode = ERR39; - ptr++; - goto FAILED; - } - break; } /* Handle a string argument */ - ptr++; - delimiter = 0; - for (i = 0; PRIV(callout_start_delims)[i] != 0; i++) - { - if (*ptr == PRIV(callout_start_delims)[i]) + else + { + ptr++; + delimiter = 0; + for (i = 0; PRIV(callout_start_delims)[i] != 0; i++) { - delimiter = PRIV(callout_end_delims)[i]; - break; + if (*ptr == PRIV(callout_start_delims)[i]) + { + delimiter = PRIV(callout_end_delims)[i]; + break; + } } - } - - if (delimiter == 0) - { - errorcode = ERR82; - goto FAILED; - } - - start = ptr; - do - { - if (++ptr >= cb->end_pattern) + + if (delimiter == 0) { - errorcode = ERR81; - ptr = start; /* To give a more useful message */ + errorcode = ERR82; goto FAILED; } - if (ptr[0] == delimiter && ptr[1] == delimiter) ptr += 2; + + start = ptr; + do + { + if (++ptr >= cb->end_pattern) + { + errorcode = ERR81; + ptr = start; /* To give a more useful message */ + goto FAILED; + } + if (ptr[0] == delimiter && ptr[1] == delimiter) ptr += 2; + } + while (ptr[0] != delimiter); + } + + /* Check terminating ) */ + + if (ptr[1] != CHAR_RIGHT_PARENTHESIS) + { + errorcode = ERR39; + ptr++; + goto FAILED; } - while (ptr[0] != delimiter); break; case CHAR_LEFT_PARENTHESIS: diff --git a/testdata/testinput5 b/testdata/testinput5 index 7e2ba45..47afd25 100644 --- a/testdata/testinput5 +++ b/testdata/testinput5 @@ -1651,4 +1651,6 @@ /$(&.+[\p{Me}].\s\xdcC*?(?())(?)\xd1+!~:(?)''(d'E:yD!\s(?'R'\x1e;\x10:U))|')g!\xb0*){29+))#(?'P'})*?/ +"(*UTF)(*UCP)(.UTF).+X(\V+;\^(\D|)!999}(?(?C{7(?C')\H*\S*/^\x5\xa\\xd3\x85n?(;\D*(?m).[^mH+((*UCP)(*U:F)})(?!^)(?'" + # End of testinput5 diff --git a/testdata/testoutput5 b/testdata/testoutput5 index a99c12b..641c563 100644 --- a/testdata/testoutput5 +++ b/testdata/testoutput5 @@ -4050,4 +4050,7 @@ Failed: error 122 at offset 1227: unmatched closing parenthesis /$(&.+[\p{Me}].\s\xdcC*?(?())(?)\xd1+!~:(?)''(d'E:yD!\s(?'R'\x1e;\x10:U))|')g!\xb0*){29+))#(?'P'})*?/ +"(*UTF)(*UCP)(.UTF).+X(\V+;\^(\D|)!999}(?(?C{7(?C')\H*\S*/^\x5\xa\\xd3\x85n?(;\D*(?m).[^mH+((*UCP)(*U:F)})(?!^)(?'" +Failed: error 139 at offset 113: closing parenthesis for (?C expected + # End of testinput5