Skip to content

Commit f759936

Browse files
hikari-no-yumeGirgias
authored andcommitted
Permit trailing whitespace in numeric strings
This is part 1 of the 'Saner Numeric Strings' RFC: https://wiki.php.net/rfc/saner-numeric-strings
1 parent 99ee73e commit f759936

File tree

9 files changed

+93
-24
lines changed

9 files changed

+93
-24
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
--TEST--
2+
Acceptance of whitespace in numeric strings
3+
--FILE--
4+
<?php
5+
6+
$strings = [
7+
"123",
8+
"123 ",
9+
"123 \t\n\r\v\f",
10+
" 123",
11+
" \t\n\r\v\f123",
12+
" 123 ",
13+
" \t\n\r\v\f123 \t\n\r\v\f",
14+
"123.0",
15+
"123.0 ",
16+
"123.0 \t\n\r\v\f",
17+
" 123.0",
18+
" \t\n\r\v\f123.0",
19+
" 123.0 ",
20+
" \t\n\r\v\f123 \t\n\r\v\f",
21+
"123e0",
22+
"123e0 ",
23+
"123e0 \t\n\r\v\f",
24+
" 123e0",
25+
" \t\n\r\v\f123e0",
26+
" 123e0 ",
27+
" \t\n\r\v\f123e0 \t\n\r\v\f"
28+
];
29+
30+
function takes_integer(int $i) {
31+
\assert($i === 123);
32+
}
33+
function takes_float(float $f) {
34+
\assert($f === 123.0);
35+
}
36+
37+
foreach ($strings as $string) {
38+
\assert($string == 123);
39+
$num = +$string;
40+
\assert($num == 123);
41+
takes_integer($string);
42+
takes_float($string);
43+
\assert(\intdiv($string, 1) === 123);
44+
\assert(\is_numeric($string));
45+
$incremented = $string;
46+
++$incremented;
47+
\assert(\is_int($incremented) || \is_float($incremented));
48+
\assert($incremented == 124);
49+
$decremented = $string;
50+
--$decremented;
51+
\assert(\is_int($decremented) || \is_float($decremented));
52+
\assert($decremented == 122);
53+
}
54+
55+
echo "OK!", PHP_EOL;
56+
57+
?>
58+
--EXPECT--
59+
OK!

Zend/tests/string_to_number_comparison.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ compare_eq(-INF, "-1e1000");
4949
echo "\n";
5050

5151
$float = 1.75;
52-
52+
5353
echo "precision=14:\n";
5454
ini_set('precision', 14);
5555
compare_3way($float, "1.75abc");
5656
compare_3way((string) $float, "1.75abc");
57-
57+
5858
echo "precision=0:\n";
5959
ini_set('precision', 0);
6060
compare_3way($float, "1.75abc");
@@ -73,7 +73,7 @@ compare_3way((string) $float, "1.75abc");
7373
"0" == "0e214987142012": true
7474

7575
42 == " 42": true
76-
42 == "42 ": false
76+
42 == "42 ": true
7777
42 == "42abc": false
7878
42 == "abc42": false
7979
0 == "abc42": false

Zend/zend_operators.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3052,11 +3052,18 @@ ZEND_API zend_uchar ZEND_FASTCALL _is_numeric_string_ex(const char *str, size_t
30523052
}
30533053

30543054
if (ptr != str + length) {
3055-
if (!allow_errors) {
3056-
return 0;
3055+
const char *endptr = ptr;
3056+
while (*endptr == ' ' || *endptr == '\t' || *endptr == '\n' || *endptr == '\r' || *endptr == '\v' || *endptr == '\f') {
3057+
endptr++;
3058+
length--;
30573059
}
3058-
if (allow_errors == -1) {
3059-
zend_error(E_NOTICE, "A non well formed numeric value encountered");
3060+
if (ptr != str + length) {
3061+
if (!allow_errors) {
3062+
return 0;
3063+
}
3064+
if (allow_errors == -1) {
3065+
zend_error(E_NOTICE, "A non well formed numeric value encountered");
3066+
}
30603067
if (EG(exception)) {
30613068
return 0;
30623069
}

ext/standard/tests/general_functions/is_numeric.phpt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,14 @@ $numerics = array(
6868
"-1",
6969
"1e2",
7070
" 1",
71+
"1 ",
7172
"2974394749328742328432",
7273
"-1e-2",
7374
'1',
7475
'-1',
7576
'1e2',
7677
' 1',
78+
'1 ',
7779
'2974394749328742328432',
7880
'-1e-2',
7981
"0123",
@@ -114,7 +116,6 @@ $not_numerics = array(
114116
array(),
115117
array("string"),
116118
"",
117-
"1 ",
118119
"- 1",
119120
"1.2.4",
120121
"1e7.6",
@@ -302,6 +303,10 @@ bool(true)
302303
bool(true)
303304
-- Iteration 76 --
304305
bool(true)
306+
-- Iteration 77 --
307+
bool(true)
308+
-- Iteration 78 --
309+
bool(true)
305310

306311
*** Testing is_numeric() on non numeric types ***
307312
-- Iteration 1 --
@@ -360,6 +365,4 @@ bool(false)
360365
bool(false)
361366
-- Iteration 28 --
362367
bool(false)
363-
-- Iteration 29 --
364-
bool(false)
365368
Done

tests/lang/operators/operator_equals_basic.phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ $valid_false = array(0, "", 0.0, array(), NULL);
88

99
$int1 = 679;
1010
$int2 = -67835;
11-
$valid_int1 = array("679", " 679", 679.0, 6.79E2, "+679", +679);
12-
$valid_int2 = array("-67835", " -67835", -67835.000, -6.7835E4);
13-
$invalid_int1 = array("679abc", "679 ", "6 7 9", "6y79", 678);
14-
$invalid_int2 = array("-67835abc", "-67835 ", "- 67835", "-67,835", "-67 835", "-678y35", -76834);
11+
$valid_int1 = array("679", " 679", "679 ", 679.0, 6.79E2, "+679", +679);
12+
$valid_int2 = array("-67835", " -67835", "-67835 ", -67835.000, -6.7835E4);
13+
$invalid_int1 = array("679abc", "6 7 9", "6y79", 678);
14+
$invalid_int2 = array("-67835abc", "- 67835", "-67,835", "-67 835", "-678y35", -76834);
1515

1616
$float1 = 57385.45835;
1717
$float2 = -67345.76567;

tests/lang/operators/operator_gt_basic.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ $valid_false = array(0, "", 0.0, array(), NULL);
88
$int1 = 679;
99
$int2 = -67835;
1010
$valid_int1 = array("678", "678abc", " 678", "678 ", 678.0, 6.789E2, "+678", +678);
11-
$valid_int2 = array("-67836", " -67836", -67835.0001, -6.78351E4);
11+
$valid_int2 = array("-67836", " -67836", -67835.0001, -6.78351E4, "-67836 ");
1212
$invalid_int1 = array(679, "679");
13-
$invalid_int2 = array(-67835, "-67835", "-67836abc", "-67836 ");
13+
$invalid_int2 = array(-67835, "-67835", "-67836abc");
1414

1515
$float1 = 57385.45835;
1616
$float2 = -67345.76567;

tests/lang/operators/operator_lt_basic.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ $valid_false = array(0, "", 0.0, array(), NULL);
88
$int1 = 677;
99
$int2 = -67837;
1010
$valid_int1 = array("678", "678abc", " 678", "678 ", 678.0, 6.789E2, "+678", +678);
11-
$valid_int2 = array("-67836", " -67836", -67835.0001, -6.78351E4);
11+
$valid_int2 = array("-67836", " -67836", -67835.0001, -6.78351E4, "-67836 ");
1212
$invalid_int1 = array(676, "676");
13-
$invalid_int2 = array(-67837, "-67837", "-67836abc", "-67836 ");
13+
$invalid_int2 = array(-67837, "-67837", "-67836abc");
1414

1515
$float1 = 57385.45835;
1616
$float2 = -67345.76567;

tests/lang/operators/operator_notequals_basic.phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ $valid_false = array(0, "", 0.0, array(), NULL);
88

99
$int1 = 679;
1010
$int2 = -67835;
11-
$valid_int1 = array("679abc", "679 ", "6 7 9", "6y79", 678);
12-
$valid_int2 = array("-67835abc", "-67835 ", "- 67835", "-67,835", "-67 835", "-678y35", -76834);
13-
$invalid_int1 = array("679", " 679", 679.0, 6.79E2, "+679", +679);
14-
$invalid_int2 = array("-67835", " -67835", -67835.000, -6.7835E4);
11+
$valid_int1 = array("679abc", "6 7 9", "6y79", 678);
12+
$valid_int2 = array("-67835abc", "- 67835", "-67,835", "-67 835", "-678y35", -76834);
13+
$invalid_int1 = array("679", " 679", "679 ", 679.0, 6.79E2, "+679", +679);
14+
$invalid_int2 = array("-67835", " -67835", "-67835 ", -67835.000, -6.7835E4);
1515

1616
$float1 = 57385.45835;
1717
$float2 = -67345.76567;

tests/lang/operators/operator_spaceship_basic.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ $valid_false = array(0, "", 0.0, array(), NULL);
88
$int1 = 679;
99
$int2 = -67835;
1010
$valid_int1 = array("678", "678abc", " 678", "678 ", 678.0, 6.789E2, "+678", +678);
11-
$valid_int2 = array("-67836", " -67836", -67835.0001, -6.78351E4);
11+
$valid_int2 = array("-67836", " -67836", "-67836 ", -67835.0001, -6.78351E4);
1212
$invalid_int1 = array(679, "679");
13-
$invalid_int2 = array(-67835, "-67835", "-67836abc", "-67836 ");
13+
$invalid_int2 = array(-67835, "-67835", "-67836abc");
1414

1515
$float1 = 57385.45835;
1616
$float2 = -67345.76567;

0 commit comments

Comments
 (0)