]> granicus.if.org Git - php/commitdiff
MFH: fix #41118 (PHP does not handle overflow of octal integers)
authorAntony Dovgal <tony2001@php.net>
Sun, 22 Apr 2007 21:33:10 +0000 (21:33 +0000)
committerAntony Dovgal <tony2001@php.net>
Sun, 22 Apr 2007 21:33:10 +0000 (21:33 +0000)
Zend/tests/hex_overflow_32bit.phpt [new file with mode: 0644]
Zend/tests/oct_overflow_32bit.phpt [new file with mode: 0644]
Zend/zend_language_scanner.l
Zend/zend_strtod.c
Zend/zend_strtod.h

diff --git a/Zend/tests/hex_overflow_32bit.phpt b/Zend/tests/hex_overflow_32bit.phpt
new file mode 100644 (file)
index 0000000..34306cc
--- /dev/null
@@ -0,0 +1,27 @@
+--TEST--
+testing integer overflow (32bit)
+--SKIPIF--
+<?php if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only"); ?>
+--FILE--
+<?php
+
+$doubles = array(
+       0x1736123FFFAAA,
+       0XFFFFFFFFFFFFFFFFFF,
+       0xAAAAAAAAAAAAAAEEEEEEEEEBBB,
+       0x66666666666666666777777,
+       );
+
+foreach ($doubles as $d) {
+       $l = $d;
+       var_dump($l);
+}
+
+echo "Done\n";
+?>
+--EXPECTF--    
+float(4083360297110%d)
+float(4.7223664828%dE+21)
+float(1.3521606402%dE+31)
+float(1.9807040628%dE+27)
+Done
diff --git a/Zend/tests/oct_overflow_32bit.phpt b/Zend/tests/oct_overflow_32bit.phpt
new file mode 100644 (file)
index 0000000..77befba
--- /dev/null
@@ -0,0 +1,29 @@
+--TEST--
+testing integer overflow (32bit)
+--SKIPIF--
+<?php if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only"); ?>
+--FILE--
+<?php
+
+$doubles = array(
+       076545676543223,
+       032325463734,
+       077777797777777,
+       07777777777777977777777777,
+       03333333333333382222222222222,
+       );
+
+foreach ($doubles as $d) {
+       $l = (double)$d;
+       var_dump($l);
+}
+
+echo "Done\n";
+?>
+--EXPECTF--    
+float(4308640384%d)
+float(3545655%d)
+float(262143)
+float(549755813%d)
+float(1884877076%d)
+Done
index bf76d9773c7b4226fcd6f136e20694d5108f5802..ca0912323f3e310e6c839229b167f4790a01bf23 100644 (file)
@@ -1247,7 +1247,11 @@ NEWLINE ("\r"|"\n"|"\r\n")
                errno = 0;
                zendlval->value.lval = strtol(yytext, NULL, 0);
                if (errno == ERANGE) { /* Overflow */
-                       zendlval->value.dval = zend_strtod(yytext, NULL);
+                       if (yytext[0] == '0') { /* octal overflow */
+                               zendlval->value.dval = zend_oct_strtod(yytext, NULL);
+                       } else {
+                               zendlval->value.dval = zend_strtod(yytext, NULL);
+                       }
                        zendlval->type = IS_DOUBLE;
                        return T_DNUMBER;
                }
index 94d1383aa2dfe9fc4417c97878076d57f47d0359..49b591da14598558651b7a429e9edb5de2916468 100644 (file)
@@ -2604,6 +2604,34 @@ ZEND_API double zend_hex_strtod(const char *str, char **endptr)
        return value;
 }
 
+ZEND_API double zend_oct_strtod(const char *str, char **endptr)
+{
+       const char *s = str;
+       char c;
+       double value = 0;
+       int any = 0;
+
+       /* skip leading zero */
+       s++;
+
+       while ((c = *s++)) {
+               if (c > '7') {
+                       /* break and return the current value if the number is not well-formed
+                        * that's what Linux strtol() does 
+                        */
+                       break;
+               }
+               value = value * 8 + c - '0';
+               any = 1;
+       }
+
+       if (endptr != NULL) {
+               *endptr = (char *)(any ? s - 1 : str);
+       }
+
+       return value;
+}
+
 /*
  * Local variables:
  * tab-width: 4
index 2dfe5a1a60ccd9a5113d23aad4daa796244ebb39..f4e066a58aedfd11f58ac823ccf2193ee6f823ae 100644 (file)
@@ -29,6 +29,7 @@ ZEND_API void zend_freedtoa(char *s);
 ZEND_API char * zend_dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve);
 ZEND_API double zend_strtod(const char *s00, char **se);
 ZEND_API double zend_hex_strtod(const char *str, char **endptr);
+ZEND_API double zend_oct_strtod(const char *str, char **endptr);
 ZEND_API int zend_startup_strtod(void);
 ZEND_API int zend_shutdown_strtod(void);
 END_EXTERN_C()