From a710d3b37b57aee67a7fb1790fd4d2ffa5fe56e5 Mon Sep 17 00:00:00 2001 From: "Philip.Hazel" Date: Mon, 9 Nov 2015 18:45:15 +0000 Subject: [PATCH] Cap minimum length at 65535 and check for integer overflow. --- ChangeLog | 3 +++ src/pcre2_study.c | 12 +++++++++--- testdata/testinput2 | 4 ++++ testdata/testoutput2 | 9 +++++++++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7c20908..6cf70d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -275,6 +275,9 @@ especially when recursion or subroutine calls are involved. 80. Allow for the possibility of the size of the nest_save structure not being a factor of the size of the compiling workspace (it currently is). +81. Check for integer overflow in minimum length calculation and cap it at +65535. + Version 10.20 30-June-2015 -------------------------- diff --git a/src/pcre2_study.c b/src/pcre2_study.c index 4fae517..de5ea92 100644 --- a/src/pcre2_study.c +++ b/src/pcre2_study.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2014 University of Cambridge + New API code Copyright (c) 2015 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -123,7 +123,7 @@ for (;;) PCRE2_UCHAR *cs, *ce; register PCRE2_UCHAR op = *cc; - if (branchlength > UINT16_MAX) return branchlength; + if (branchlength >= UINT16_MAX) return UINT16_MAX; switch (op) { @@ -562,7 +562,13 @@ for (;;) break; } - branchlength += min * d; + /* Take care not to overflow: (1) min and d are ints, so check that their + product is not greater than INT_MAX. (2) branchlength is limited to + UINT16_MAX (checked at the top of the loop). */ + + if ((d > 0 && (INT_MAX/d) < min) || UINT16_MAX - branchlength < min*d) + branchlength = UINT16_MAX; + else branchlength += min * d; break; /* Recursion always refers to the first occurrence of a subpattern with a diff --git a/testdata/testinput2 b/testdata/testinput2 index 38fdcd9..470a328 100644 --- a/testdata/testinput2 +++ b/testdata/testinput2 @@ -4631,4 +4631,8 @@ a)"xI /\[()]{1024}/I,expand +# Test minlength capped at 65535 + +/(A{65000})\1{65000}/I + # End of testinput2 diff --git a/testdata/testoutput2 b/testdata/testoutput2 index 84be7a5..84e8fa7 100644 --- a/testdata/testoutput2 +++ b/testdata/testoutput2 @@ -14743,4 +14743,13 @@ Capturing subpattern count = 1024 May match empty string Subject length lower bound = 0 +# Test minlength capped at 65535 + +/(A{65000})\1{65000}/I +Capturing subpattern count = 1 +Max back reference = 1 +First code unit = 'A' +Last code unit = 'A' +Subject length lower bound = 65535 + # End of testinput2