]> granicus.if.org Git - php/commitdiff
Permit trailing whitespace in numeric strings
authorAndrea Faulds <ajf@ajf.me>
Wed, 24 Jun 2020 13:05:58 +0000 (15:05 +0200)
committerGeorge Peter Banyard <girgias@php.net>
Wed, 29 Jul 2020 01:22:38 +0000 (02:22 +0100)
This is part 1 of the 'Saner Numeric Strings' RFC:
https://wiki.php.net/rfc/saner-numeric-strings

Zend/tests/numeric_strings/trailling_whitespaces.phpt [new file with mode: 0644]
Zend/tests/string_to_number_comparison.phpt
Zend/zend_operators.c
ext/standard/tests/general_functions/is_numeric.phpt
tests/lang/operators/operator_equals_basic.phpt
tests/lang/operators/operator_gt_basic.phpt
tests/lang/operators/operator_lt_basic.phpt
tests/lang/operators/operator_notequals_basic.phpt
tests/lang/operators/operator_spaceship_basic.phpt

diff --git a/Zend/tests/numeric_strings/trailling_whitespaces.phpt b/Zend/tests/numeric_strings/trailling_whitespaces.phpt
new file mode 100644 (file)
index 0000000..431a3f6
--- /dev/null
@@ -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!
index a64b1c4ff2cbae6df06c7164aab79f6219658ab9..86ba8a7a8b765799f6a51e1bcb710b521cc21fc3 100644 (file)
@@ -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
index a468962491568022b69cbe970e91512c982a8dca..f0c17ea0d3d08dd94512c08f75c12cc03a91628e 100644 (file)
@@ -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;
                        }
index bf09a8134830a82b742cb9bf8b83690d0af67017..a4f7b79f79b9f201209d3f139aec936316f33e54 100644 (file)
@@ -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
index 3f179a0a4c284effd467e58955ea655e3bbc8617..63ab1ac68d62686e2bbe279f589b4f55ed88a823 100644 (file)
@@ -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;
index 70b8fbcdd987c31f5cb2cd8e933a616464a97d91..bb13bd959948a0ae661a2bd0031929df4bd1ed5c 100644 (file)
@@ -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;
index 98685506c7ebe9daef33b9d5183f009f97c9a3c5..e3fedddf831cc151431f75cd316afdc87f2324f6 100644 (file)
@@ -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;
index b254e6e90ce5fe8ec37658f931d47b042ddd96b6..156c60d6da8b0fa63f114667f730c7b1fd44b258 100644 (file)
@@ -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;
index 1014c46191f124c3937b1bb71c90eb44255facdb..f74201bc5f8e394b89daf5a02b416dca3f2d3056 100644 (file)
@@ -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;