MFH: fix #41118 (PHP does not handle overflow of octal integers)

This commit is contained in:
Antony Dovgal 2007-04-22 21:33:10 +00:00
parent e910699347
commit f6cef916bc
5 changed files with 90 additions and 1 deletions

View file

@ -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

View file

@ -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

View 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;
}

View 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

View 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()