From 9b741ad59d9acf97b57346a8bde1cae0e5230819 Mon Sep 17 00:00:00 2001 From: "Philip.Hazel" Date: Wed, 6 Jul 2016 08:42:50 +0000 Subject: [PATCH] Detect overflow in pcre2test pattern and subject repetition counts. --- ChangeLog | 2 ++ src/pcre2test.c | 29 ++++++++++++++++++++++++++--- testdata/testinput2 | 6 ++++++ testdata/testoutput2 | 9 +++++++++ 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 47f5835..ffe84b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -168,6 +168,8 @@ large stack size when testing with clang. 42. Fix register overwite in JIT when SSE2 acceleration is enabled. +43. Detect integer overflow in pcre2test pattern and data repetition counts. + Version 10.21 12-January-2016 ----------------------------- diff --git a/src/pcre2test.c b/src/pcre2test.c index b48b3e5..9ce37a5 100644 --- a/src/pcre2test.c +++ b/src/pcre2test.c @@ -4618,8 +4618,19 @@ else if ((pat_patctl.control & CTL_EXPAND) != 0) { uint32_t clen = pe - pc - 2; uint32_t i = 0; + unsigned long uli; + char *endptr; + pe += 2; - while (isdigit(*pe)) i = i * 10 + *pe++ - '0'; + uli = strtoul((const char *)pe, &endptr, 10); + if (U32OVERFLOW(uli)) + { + fprintf(outfile, "** Pattern repeat count too large\n"); + return PR_SKIP; + } + + i = (uint32_t)uli; + pe = (uint8_t *)endptr; if (*pe == '}') { if (i == 0) @@ -5615,13 +5626,15 @@ buffer of the appropriate width. In UTF mode, input can be UTF-8. */ while ((c = *p++) != 0) { - int i = 0; + int32_t i = 0; size_t replen; /* ] may mark the end of a replicated sequence */ if (c == ']' && start_rep != NULL) { + long li; + char *endptr; size_t qoffset = CAST8VAR(q) - dbuffer; size_t rep_offset = start_rep - dbuffer; @@ -5630,12 +5643,22 @@ while ((c = *p++) != 0) fprintf(outfile, "** Expected '{' after \\[....]\n"); return PR_OK; } - while (isdigit(*p)) i = i * 10 + *p++ - '0'; + + li = strtol((const char *)p, &endptr, 10); + if (S32OVERFLOW(li)) + { + fprintf(outfile, "** Repeat count too large\n"); + return PR_OK; + } + + p = (uint8_t *)endptr; if (*p++ != '}') { fprintf(outfile, "** Expected '}' after \\[...]{...\n"); return PR_OK; } + + i = (int32_t)li; if (i-- == 0) { fprintf(outfile, "** Zero repeat not allowed\n"); diff --git a/testdata/testinput2 b/testdata/testinput2 index fa35d40..9d0759f 100644 --- a/testdata/testinput2 +++ b/testdata/testinput2 @@ -4813,4 +4813,10 @@ a)"xI \= Expect no match abc +/aaa/ +\[abc]{10000000000000000000000000000} +\[a]{3} + +/\[AB]{6000000000000000000000}/expand + # End of testinput2 diff --git a/testdata/testoutput2 b/testdata/testoutput2 index 6dae069..01cb193 100644 --- a/testdata/testoutput2 +++ b/testdata/testoutput2 @@ -15186,6 +15186,15 @@ Failed: error 122 at offset 10: unmatched closing parenthesis 0 ^ 0 No match +/aaa/ +\[abc]{10000000000000000000000000000} +** Repeat count too large +\[a]{3} + 0: aaa + +/\[AB]{6000000000000000000000}/expand +** Pattern repeat count too large + # End of testinput2 Error -63: PCRE2_ERROR_BADDATA (unknown error number) Error -62: bad serialized data