Skip to content

Commit

Permalink
Permit trailing whitespace in numeric strings
Browse files Browse the repository at this point in the history
This is part 1 of the 'Saner Numeric Strings' RFC:
https://wiki.php.net/rfc/saner-numeric-strings
  • Loading branch information
hikari-no-yume authored and Girgias committed Jul 29, 2020
1 parent 99ee73e commit f759936
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 24 deletions.
59 changes: 59 additions & 0 deletions Zend/tests/numeric_strings/trailling_whitespaces.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
--TEST--
Acceptance of whitespace in numeric strings
--FILE--
<?php

$strings = [
"123",
"123 ",
"123 \t\n\r\v\f",
" 123",
" \t\n\r\v\f123",
" 123 ",
" \t\n\r\v\f123 \t\n\r\v\f",
"123.0",
"123.0 ",
"123.0 \t\n\r\v\f",
" 123.0",
" \t\n\r\v\f123.0",
" 123.0 ",
" \t\n\r\v\f123 \t\n\r\v\f",
"123e0",
"123e0 ",
"123e0 \t\n\r\v\f",
" 123e0",
" \t\n\r\v\f123e0",
" 123e0 ",
" \t\n\r\v\f123e0 \t\n\r\v\f"
];

function takes_integer(int $i) {
\assert($i === 123);
}
function takes_float(float $f) {
\assert($f === 123.0);
}

foreach ($strings as $string) {
\assert($string == 123);
$num = +$string;
\assert($num == 123);
takes_integer($string);
takes_float($string);
\assert(\intdiv($string, 1) === 123);
\assert(\is_numeric($string));
$incremented = $string;
++$incremented;
\assert(\is_int($incremented) || \is_float($incremented));
\assert($incremented == 124);
$decremented = $string;
--$decremented;
\assert(\is_int($decremented) || \is_float($decremented));
\assert($decremented == 122);
}

echo "OK!", PHP_EOL;

?>
--EXPECT--
OK!
6 changes: 3 additions & 3 deletions Zend/tests/string_to_number_comparison.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ compare_eq(-INF, "-1e1000");
echo "\n";

$float = 1.75;

echo "precision=14:\n";
ini_set('precision', 14);
compare_3way($float, "1.75abc");
compare_3way((string) $float, "1.75abc");

echo "precision=0:\n";
ini_set('precision', 0);
compare_3way($float, "1.75abc");
Expand All @@ -73,7 +73,7 @@ compare_3way((string) $float, "1.75abc");
"0" == "0e214987142012": true

42 == " 42": true
42 == "42 ": false
42 == "42 ": true
42 == "42abc": false
42 == "abc42": false
0 == "abc42": false
Expand Down
15 changes: 11 additions & 4 deletions Zend/zend_operators.c
Original file line number Diff line number Diff line change
Expand Up @@ -3052,11 +3052,18 @@ ZEND_API zend_uchar ZEND_FASTCALL _is_numeric_string_ex(const char *str, size_t
}

if (ptr != str + length) {
if (!allow_errors) {
return 0;
const char *endptr = ptr;
while (*endptr == ' ' || *endptr == '\t' || *endptr == '\n' || *endptr == '\r' || *endptr == '\v' || *endptr == '\f') {
endptr++;
length--;
}
if (allow_errors == -1) {
zend_error(E_NOTICE, "A non well formed numeric value encountered");
if (ptr != str + length) {
if (!allow_errors) {
return 0;
}
if (allow_errors == -1) {
zend_error(E_NOTICE, "A non well formed numeric value encountered");
}
if (EG(exception)) {
return 0;
}
Expand Down
9 changes: 6 additions & 3 deletions ext/standard/tests/general_functions/is_numeric.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,14 @@ $numerics = array(
"-1",
"1e2",
" 1",
"1 ",
"2974394749328742328432",
"-1e-2",
'1',
'-1',
'1e2',
' 1',
'1 ',
'2974394749328742328432',
'-1e-2',
"0123",
Expand Down Expand Up @@ -114,7 +116,6 @@ $not_numerics = array(
array(),
array("string"),
"",
"1 ",
"- 1",
"1.2.4",
"1e7.6",
Expand Down Expand Up @@ -302,6 +303,10 @@ bool(true)
bool(true)
-- Iteration 76 --
bool(true)
-- Iteration 77 --
bool(true)
-- Iteration 78 --
bool(true)

*** Testing is_numeric() on non numeric types ***
-- Iteration 1 --
Expand Down Expand Up @@ -360,6 +365,4 @@ bool(false)
bool(false)
-- Iteration 28 --
bool(false)
-- Iteration 29 --
bool(false)
Done
8 changes: 4 additions & 4 deletions tests/lang/operators/operator_equals_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ $valid_false = array(0, "", 0.0, array(), NULL);

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

$float1 = 57385.45835;
$float2 = -67345.76567;
Expand Down
4 changes: 2 additions & 2 deletions tests/lang/operators/operator_gt_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ $valid_false = array(0, "", 0.0, array(), NULL);
$int1 = 679;
$int2 = -67835;
$valid_int1 = array("678", "678abc", " 678", "678 ", 678.0, 6.789E2, "+678", +678);
$valid_int2 = array("-67836", " -67836", -67835.0001, -6.78351E4);
$valid_int2 = array("-67836", " -67836", -67835.0001, -6.78351E4, "-67836 ");
$invalid_int1 = array(679, "679");
$invalid_int2 = array(-67835, "-67835", "-67836abc", "-67836 ");
$invalid_int2 = array(-67835, "-67835", "-67836abc");

$float1 = 57385.45835;
$float2 = -67345.76567;
Expand Down
4 changes: 2 additions & 2 deletions tests/lang/operators/operator_lt_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ $valid_false = array(0, "", 0.0, array(), NULL);
$int1 = 677;
$int2 = -67837;
$valid_int1 = array("678", "678abc", " 678", "678 ", 678.0, 6.789E2, "+678", +678);
$valid_int2 = array("-67836", " -67836", -67835.0001, -6.78351E4);
$valid_int2 = array("-67836", " -67836", -67835.0001, -6.78351E4, "-67836 ");
$invalid_int1 = array(676, "676");
$invalid_int2 = array(-67837, "-67837", "-67836abc", "-67836 ");
$invalid_int2 = array(-67837, "-67837", "-67836abc");

$float1 = 57385.45835;
$float2 = -67345.76567;
Expand Down
8 changes: 4 additions & 4 deletions tests/lang/operators/operator_notequals_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ $valid_false = array(0, "", 0.0, array(), NULL);

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

$float1 = 57385.45835;
$float2 = -67345.76567;
Expand Down
4 changes: 2 additions & 2 deletions tests/lang/operators/operator_spaceship_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ $valid_false = array(0, "", 0.0, array(), NULL);
$int1 = 679;
$int2 = -67835;
$valid_int1 = array("678", "678abc", " 678", "678 ", 678.0, 6.789E2, "+678", +678);
$valid_int2 = array("-67836", " -67836", -67835.0001, -6.78351E4);
$valid_int2 = array("-67836", " -67836", "-67836 ", -67835.0001, -6.78351E4);
$invalid_int1 = array(679, "679");
$invalid_int2 = array(-67835, "-67835", "-67836abc", "-67836 ");
$invalid_int2 = array(-67835, "-67835", "-67836abc");

$float1 = 57385.45835;
$float2 = -67345.76567;
Expand Down

0 comments on commit f759936

Please sign in to comment.