mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
MFH: fix #41118 (PHP does not handle overflow of octal integers)
This commit is contained in:
parent
e910699347
commit
f6cef916bc
5 changed files with 90 additions and 1 deletions
27
Zend/tests/hex_overflow_32bit.phpt
Normal file
27
Zend/tests/hex_overflow_32bit.phpt
Normal 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
|
29
Zend/tests/oct_overflow_32bit.phpt
Normal file
29
Zend/tests/oct_overflow_32bit.phpt
Normal 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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue