diff --git a/ChangeLog b/ChangeLog index a026ec2..23589ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -85,6 +85,9 @@ otherwise), an atomic group, or a recursion. 16. Give error if pcre2test -t, -T, -tm or -TM is given an argument of zero. +17. Check for integer overflow when computing lookbehind lengths. Fixes +Clusterfuzz issue 15636. + Version 10.33 16-April-2019 --------------------------- diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index 4474bb9..a1af793 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -9269,8 +9269,26 @@ for (;; pptr++) case META_MINMAX_QUERY: if (pptr[1] == pptr[2]) { - if (pptr[1] == 0) branchlength -= lastitemlength; - else itemlength = (pptr[1] - 1) * lastitemlength; + switch(pptr[1]) + { + case 0: + branchlength -= lastitemlength; + break; + + case 1: + itemlength = 0; + break; + + default: /* Check for integer overflow */ + if (lastitemlength != 0 && /* Should not occur, but just in case */ + INT_MAX/lastitemlength < pptr[1] - 1) + { + *errcodeptr = ERR87; /* Integer overflow; lookbehind too big */ + return -1; + } + itemlength = (pptr[1] - 1) * lastitemlength; + break; + } pptr += 2; break; } @@ -9284,19 +9302,19 @@ for (;; pptr++) return -1; } - /* Add the item length to the branchlength, and save it for use if the next - thing is a quantifier. */ + /* Add the item length to the branchlength, checking for integer overflow and + for the branch length exceeding the limit. */ - branchlength += itemlength; - lastitemlength = itemlength; - - /* Ensure that the length does not overflow the limit. */ - - if (branchlength > LOOKBEHIND_MAX) + if (INT_MAX - branchlength < (int)itemlength || + (branchlength += itemlength) > LOOKBEHIND_MAX) { *errcodeptr = ERR87; return -1; } + + /* Save this item length for use if the next item is a quantifier. */ + + lastitemlength = itemlength; } EXIT: diff --git a/testdata/testinput2 b/testdata/testinput2 index 004ec80..251d625 100644 --- a/testdata/testinput2 +++ b/testdata/testinput2 @@ -5647,4 +5647,6 @@ a)"xI /(?<=(?<=a)b)(?