mirror of
https://github.com/danog/PHP-Parser.git
synced 2024-11-26 20:04:48 +01:00
Fix parsing of integers that overflow into floats
Integers in hex/oct/bin notation that overflowed into floats were parsed incorrectly.
This commit is contained in:
parent
faf0351bab
commit
cf3117d82d
@ -138,12 +138,6 @@ function resolveMacros($code) {
|
||||
return 'substr(' . $args[0] . ', 1)';
|
||||
}
|
||||
|
||||
if ('parseDNumber' == $name) {
|
||||
assertArgs(1, $args, $name);
|
||||
|
||||
return '(double) ' . $args[0];
|
||||
}
|
||||
|
||||
if ('parseEncapsed' == $name) {
|
||||
assertArgs(2, $args, $name);
|
||||
|
||||
|
@ -659,7 +659,7 @@ ctor_arguments:
|
||||
|
||||
common_scalar:
|
||||
T_LNUMBER { $$ = Scalar_LNumber[Scalar_LNumber::parse($1)]; }
|
||||
| T_DNUMBER { $$ = Scalar_DNumber[parseDNumber($1)]; }
|
||||
| T_DNUMBER { $$ = Scalar_DNumber[Scalar_DNumber::parse($1)]; }
|
||||
| T_CONSTANT_ENCAPSED_STRING { $$ = Scalar_String::create($1, $line, $docComment); }
|
||||
| T_LINE { $$ = Scalar_LineConst[]; }
|
||||
| T_FILE { $$ = Scalar_FileConst[]; }
|
||||
|
@ -20,4 +20,40 @@ class PHPParser_Node_Scalar_DNumber extends PHPParser_Node_Scalar
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a DNUMBER token like PHP would.
|
||||
*
|
||||
* @param string $str A string number
|
||||
*
|
||||
* @return float The parsed number
|
||||
*/
|
||||
public static function parse($str) {
|
||||
// if string contains any of .eE just cast it to float
|
||||
if (false !== strpbrk($str, '.eE')) {
|
||||
return (float) $str;
|
||||
}
|
||||
|
||||
// otherwise it's an integer notation that overflowed into a float
|
||||
// if it starts with 0 it's one of the special integer notations
|
||||
if ('0' === $str[0]) {
|
||||
// hex
|
||||
if ('x' === $str[1] || 'X' === $str[1]) {
|
||||
return hexdec($str);
|
||||
}
|
||||
|
||||
// bin
|
||||
if ('b' === $str[1] || 'B' === $str[1]) {
|
||||
return bindec($str);
|
||||
}
|
||||
|
||||
// oct
|
||||
// substr($str, 0, strcspn($str, '89')) cuts the string at the first invalid digit (8 or 9)
|
||||
// so that only the digits before that are used
|
||||
return octdec(substr($str, 0, strcspn($str, '89')));
|
||||
}
|
||||
|
||||
// dec
|
||||
return (float) $str;
|
||||
}
|
||||
}
|
@ -2157,7 +2157,7 @@ class PHPParser_Parser
|
||||
}
|
||||
|
||||
protected function yyn284($line, $docComment) {
|
||||
$this->yyval = new PHPParser_Node_Scalar_DNumber((double) $this->yyastk[$this->yysp-(1-1)], $line, $docComment);
|
||||
$this->yyval = new PHPParser_Node_Scalar_DNumber(PHPParser_Node_Scalar_DNumber::parse($this->yyastk[$this->yysp-(1-1)]), $line, $docComment);
|
||||
}
|
||||
|
||||
protected function yyn285($line, $docComment) {
|
||||
|
@ -12,6 +12,13 @@ Different float syntaxes
|
||||
30.20e10;
|
||||
300.200e100;
|
||||
1e10000;
|
||||
|
||||
// various integer -> float overflows
|
||||
9999999999999999999;
|
||||
0xFFFFFFFFFFFFFFFF;
|
||||
07777777777777777777777;
|
||||
0777777777777777777777787;
|
||||
0b1111111111111111111111111111111111111111111111111111111111111111;
|
||||
-----
|
||||
array(
|
||||
0: Scalar_DNumber(
|
||||
@ -44,4 +51,19 @@ array(
|
||||
9: Scalar_DNumber(
|
||||
value: INF
|
||||
)
|
||||
10: Scalar_DNumber(
|
||||
value: 1.0E+19
|
||||
)
|
||||
11: Scalar_DNumber(
|
||||
value: 1.844674407371E+19
|
||||
)
|
||||
12: Scalar_DNumber(
|
||||
value: 7.3786976294838E+19
|
||||
)
|
||||
13: Scalar_DNumber(
|
||||
value: 7.3786976294838E+19
|
||||
)
|
||||
14: Scalar_DNumber(
|
||||
value: 1.844674407371E+19
|
||||
)
|
||||
)
|
Loading…
Reference in New Issue
Block a user