summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Faulds <ajf@ajf.me>2020-06-24 15:05:58 +0200
committerGeorge Peter Banyard <girgias@php.net>2020-07-29 02:22:38 +0100
commitf759936591c08d9bff6ab707f2f8c192f61b5bf1 (patch)
tree9955533f54b7246cd2c4fd250050ea0f509e4c1f
parent99ee73e6a94c847cee7130928cc3b6acddece904 (diff)
downloadphp-git-f759936591c08d9bff6ab707f2f8c192f61b5bf1.tar.gz
Permit trailing whitespace in numeric strings
This is part 1 of the 'Saner Numeric Strings' RFC: https://wiki.php.net/rfc/saner-numeric-strings
-rw-r--r--Zend/tests/numeric_strings/trailling_whitespaces.phpt59
-rw-r--r--Zend/tests/string_to_number_comparison.phpt6
-rw-r--r--Zend/zend_operators.c15
-rw-r--r--ext/standard/tests/general_functions/is_numeric.phpt9
-rw-r--r--tests/lang/operators/operator_equals_basic.phpt8
-rw-r--r--tests/lang/operators/operator_gt_basic.phpt4
-rw-r--r--tests/lang/operators/operator_lt_basic.phpt4
-rw-r--r--tests/lang/operators/operator_notequals_basic.phpt8
-rw-r--r--tests/lang/operators/operator_spaceship_basic.phpt4
9 files changed, 93 insertions, 24 deletions
diff --git a/Zend/tests/numeric_strings/trailling_whitespaces.phpt b/Zend/tests/numeric_strings/trailling_whitespaces.phpt
new file mode 100644
index 0000000000..431a3f6691
--- /dev/null
+++ b/Zend/tests/numeric_strings/trailling_whitespaces.phpt
@@ -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!
diff --git a/Zend/tests/string_to_number_comparison.phpt b/Zend/tests/string_to_number_comparison.phpt
index a64b1c4ff2..86ba8a7a8b 100644
--- a/Zend/tests/string_to_number_comparison.phpt
+++ b/Zend/tests/string_to_number_comparison.phpt
@@ -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");
@@ -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
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index a468962491..f0c17ea0d3 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -3052,11 +3052,18 @@ process_double:
}
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;
}
diff --git a/ext/standard/tests/general_functions/is_numeric.phpt b/ext/standard/tests/general_functions/is_numeric.phpt
index bf09a81348..a4f7b79f79 100644
--- a/ext/standard/tests/general_functions/is_numeric.phpt
+++ b/ext/standard/tests/general_functions/is_numeric.phpt
@@ -68,12 +68,14 @@ $numerics = array(
"-1",
"1e2",
" 1",
+ "1 ",
"2974394749328742328432",
"-1e-2",
'1',
'-1',
'1e2',
' 1',
+ '1 ',
'2974394749328742328432',
'-1e-2',
"0123",
@@ -114,7 +116,6 @@ $not_numerics = array(
array(),
array("string"),
"",
- "1 ",
"- 1",
"1.2.4",
"1e7.6",
@@ -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 --
@@ -360,6 +365,4 @@ bool(false)
bool(false)
-- Iteration 28 --
bool(false)
--- Iteration 29 --
-bool(false)
Done
diff --git a/tests/lang/operators/operator_equals_basic.phpt b/tests/lang/operators/operator_equals_basic.phpt
index 3f179a0a4c..63ab1ac68d 100644
--- a/tests/lang/operators/operator_equals_basic.phpt
+++ b/tests/lang/operators/operator_equals_basic.phpt
@@ -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;
diff --git a/tests/lang/operators/operator_gt_basic.phpt b/tests/lang/operators/operator_gt_basic.phpt
index 70b8fbcdd9..bb13bd9599 100644
--- a/tests/lang/operators/operator_gt_basic.phpt
+++ b/tests/lang/operators/operator_gt_basic.phpt
@@ -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;
diff --git a/tests/lang/operators/operator_lt_basic.phpt b/tests/lang/operators/operator_lt_basic.phpt
index 98685506c7..e3fedddf83 100644
--- a/tests/lang/operators/operator_lt_basic.phpt
+++ b/tests/lang/operators/operator_lt_basic.phpt
@@ -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;
diff --git a/tests/lang/operators/operator_notequals_basic.phpt b/tests/lang/operators/operator_notequals_basic.phpt
index b254e6e90c..156c60d6da 100644
--- a/tests/lang/operators/operator_notequals_basic.phpt
+++ b/tests/lang/operators/operator_notequals_basic.phpt
@@ -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;
diff --git a/tests/lang/operators/operator_spaceship_basic.phpt b/tests/lang/operators/operator_spaceship_basic.phpt
index 1014c46191..f74201bc5f 100644
--- a/tests/lang/operators/operator_spaceship_basic.phpt
+++ b/tests/lang/operators/operator_spaceship_basic.phpt
@@ -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;