]> granicus.if.org Git - php/commitdiff
Fixed bug #47745 (FILTER_VALIDATE_INT doesn't allow minimum integer)
authorDmitry Stogov <dmitry@php.net>
Tue, 31 Mar 2009 10:02:40 +0000 (10:02 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 31 Mar 2009 10:02:40 +0000 (10:02 +0000)
NEWS
ext/filter/logical_filters.c
ext/filter/tests/bug47745.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 8e8cc82c34d779244c79e5ae2e8b2620b785da5d..7fa93734a65aecb168b2a8252f95c69c2ccd18e0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,8 @@ PHP                                                                        NEWS
   (Matteo)
 - Fixed bug #47771 (Exception during object construction from arg call calls
   object's destructor). (Dmitry)
+- Fixed bug #47745 (FILTER_VALIDATE_INT doesn't allow minimum integer).
+  (Dmitry)
 - Fixed bug #47714 (autoloading classes inside exception_handler leads to
   crashes). (Dmitry)
 - Fixed bug #47699 (autoload and late static binding). (Dmitry)
index 022d539ba48f8ef9b88fd5a2f3580e12249cd1e3..84a54f22bd5c9d0ddbc4f9433d8f4d69fecca645 100644 (file)
 
 static int php_filter_parse_int(const char *str, unsigned int str_len, long *ret TSRMLS_DC) { /* {{{ */
        long ctx_value;
-       long sign = 1;
+       long sign = 0;
        const char *end = str + str_len;
-       double dval;
-       long overflow;
 
        switch (*str) {
                case '-':
-                       sign = -1;
+                       sign = 1;
                case '+':
                        str++;
                default:
@@ -91,22 +89,29 @@ static int php_filter_parse_int(const char *str, unsigned int str_len, long *ret
                return -1;
        }
 
+       if ((end - str > MAX_LENGTH_OF_LONG - 1) /* number too long */
+        || (SIZEOF_LONG == 4 && end - str == MAX_LENGTH_OF_LONG - 1 && *str > '2')) {
+               /* overflow */
+               return -1;
+       }
+
        while (str < end) {
                if (*str >= '0' && *str <= '9') {
-                       ZEND_SIGNED_MULTIPLY_LONG(ctx_value, 10, ctx_value, dval, overflow);
-                       if (overflow) {
-                               return -1;
-                       }
-                       ctx_value += ((*(str++)) - '0');
-                       if (ctx_value & LONG_SIGN_MASK) {
-                               return -1;
-                       }
+                       ctx_value = (ctx_value * 10) + (*(str++) - '0');                                                                \
                } 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 * sign;
+       *ret = ctx_value;
        return 1;
 }
 /* }}} */
diff --git a/ext/filter/tests/bug47745.phpt b/ext/filter/tests/bug47745.phpt
new file mode 100644 (file)
index 0000000..a8656fd
--- /dev/null
@@ -0,0 +1,11 @@
+--TEST--
+Bug #47745 (FILTER_VALIDATE_INT doesn't allow minimum integer)
+--FILE--
+<?php
+$s = (string)(-PHP_INT_MAX-1);
+var_dump(intval($s));
+var_dump(filter_var($s, FILTER_VALIDATE_INT));
+?>
+--EXPECTF--
+int(-%d)
+int(-%d)