Skip to content

Commit 69131b4

Browse files
hikari-no-yumeGirgias
authored andcommitted
Permit trailing whitespace in numeric strings
1 parent 4730b06 commit 69131b4

File tree

3 files changed

+77
-7
lines changed

3 files changed

+77
-7
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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!
60+

Zend/zend_operators.c

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

29852985
if (ptr != str + length) {
2986-
if (!allow_errors) {
2987-
return 0;
2986+
const char *endptr = ptr;
2987+
while (*endptr == ' ' || *endptr == '\t' || *endptr == '\n' || *endptr == '\r' || *endptr == '\v' || *endptr == '\f') {
2988+
endptr++;
2989+
length--;
29882990
}
2989-
if (allow_errors == -1) {
2990-
zend_error(E_NOTICE, "A non well formed numeric value encountered");
2991+
if (ptr != str + length) {
2992+
if (!allow_errors) {
2993+
return 0;
2994+
}
2995+
if (allow_errors == -1) {
2996+
zend_error(E_NOTICE, "A non well formed numeric value encountered");
2997+
}
29912998
if (EG(exception)) {
29922999
return 0;
29933000
}

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

0 commit comments

Comments
 (0)