From: Raphael Geissert Date: Sat, 6 Mar 2010 18:54:55 +0000 (+0000) Subject: Detect overflows before they occur in the filter extension (bug #51023) X-Git-Tag: php-5.2.14RC1~109 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7d4660d7a482259ec7b3fe2f1a4fc85b19fb92ee;p=php Detect overflows before they occur in the filter extension (bug #51023) Thanks to Sean Finney for the patch --- diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index 52dcb504ec..28fae50226 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -68,7 +68,7 @@ static int php_filter_parse_int(const char *str, unsigned int str_len, long *ret TSRMLS_DC) { /* {{{ */ long ctx_value; - int sign = 0; + int sign = 0, digit = 0; const char *end = str + str_len; switch (*str) { @@ -82,7 +82,7 @@ static int php_filter_parse_int(const char *str, unsigned int str_len, long *ret /* must start with 1..9*/ if (str < end && *str >= '1' && *str <= '9') { - ctx_value = ((*(str++)) - '0'); + ctx_value = ((sign)?-1:1) * ((*(str++)) - '0'); } else { return -1; } @@ -95,19 +95,18 @@ static int php_filter_parse_int(const char *str, unsigned int str_len, long *ret while (str < end) { if (*str >= '0' && *str <= '9') { - ctx_value = (ctx_value * 10) + (*(str++) - '0'); + digit = (*(str++) - '0'); + if ( (!sign) && ctx_value <= (LONG_MAX-digit)/10 ) { + ctx_value = (ctx_value * 10) + digit; + } else if ( sign && ctx_value >= (LONG_MIN+digit)/10) { + ctx_value = (ctx_value * 10) - digit; + } else { + return -1; + } } else { return -1; } } - if (sign) { - ctx_value = -ctx_value; - if (ctx_value > 0) { /* overflow */ - return -1; - } - } else if (ctx_value < 0) { /* overflow */ - return -1; - } *ret = ctx_value; return 1; diff --git a/ext/filter/tests/046.phpt b/ext/filter/tests/046.phpt index 8133289461..bc454420ad 100755 --- a/ext/filter/tests/046.phpt +++ b/ext/filter/tests/046.phpt @@ -4,16 +4,46 @@ Integer overflow --FILE-- ---EXPECT-- -bool(true) -bool(false) -bool(true) +--EXPECTF-- +max filtered: int(%d) +max is_long: bool(true) +max equal: bool(true) +overflow filtered: bool(false) +overflow is_long: bool(false) +overflow equal: bool(false) +min filtered: int(-%d) +min is_long: bool(true) +min equal: bool(true) +underflow filtered: bool(false) +underflow is_long: bool(false) +underflow equal: bool(false)