Skip to content

Commit 7027899

Browse files
committed
Fix parsing of large hex floats containing "e"
These ended up taking the code path for normal floats and being cast to zero. (cherry picked from commit 4ce9781)
1 parent 2f1fd78 commit 7027899

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

lib/PhpParser/Node/Scalar/DNumber.php

+7-11
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,7 @@ public static function fromString(string $str, array $attributes = []): DNumber
4747
public static function parse(string $str) : float {
4848
$str = str_replace('_', '', $str);
4949

50-
// if string contains any of .eE just cast it to float
51-
if (false !== strpbrk($str, '.eE')) {
52-
return (float) $str;
53-
}
54-
55-
// otherwise it's an integer notation that overflowed into a float
56-
// if it starts with 0 it's one of the special integer notations
50+
// Check whether this is one of the special integer notations.
5751
if ('0' === $str[0]) {
5852
// hex
5953
if ('x' === $str[1] || 'X' === $str[1]) {
@@ -65,10 +59,12 @@ public static function parse(string $str) : float {
6559
return bindec($str);
6660
}
6761

68-
// oct
69-
// substr($str, 0, strcspn($str, '89')) cuts the string at the first invalid digit (8 or 9)
70-
// so that only the digits before that are used
71-
return octdec(substr($str, 0, strcspn($str, '89')));
62+
// oct, but only if the string does not contain any of '.eE'.
63+
if (false === strpbrk($str, '.eE')) {
64+
// substr($str, 0, strcspn($str, '89')) cuts the string at the first invalid digit
65+
// (8 or 9) so that only the digits before that are used.
66+
return octdec(substr($str, 0, strcspn($str, '89')));
67+
}
7268
}
7369

7470
// dec

test/code/parser/scalar/float.test

+8-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Different float syntaxes
1717
// (all are actually the same number, just in different representations)
1818
18446744073709551615;
1919
0xFFFFFFFFFFFFFFFF;
20+
0xEEEEEEEEEEEEEEEE;
2021
01777777777777777777777;
2122
0177777777777777777777787;
2223
0b1111111111111111111111111111111111111111111111111111111111111111;
@@ -92,7 +93,7 @@ array(
9293
)
9394
12: Stmt_Expression(
9495
expr: Scalar_DNumber(
95-
value: 1.844674407371E+19
96+
value: 1.7216961135462E+19
9697
)
9798
)
9899
13: Stmt_Expression(
@@ -105,4 +106,9 @@ array(
105106
value: 1.844674407371E+19
106107
)
107108
)
108-
)
109+
15: Stmt_Expression(
110+
expr: Scalar_DNumber(
111+
value: 1.844674407371E+19
112+
)
113+
)
114+
)

0 commit comments

Comments
 (0)