]> granicus.if.org Git - php/commitdiff
Warn about invalid strings in arithmetic
authorAndrea Faulds <ajf@ajf.me>
Wed, 30 Mar 2016 00:44:27 +0000 (01:44 +0100)
committerAndrea Faulds <ajf@ajf.me>
Wed, 30 Mar 2016 00:44:27 +0000 (01:44 +0100)
Squashed commit of the following:

commit e05d3b67325d4521418483ed924ac9211a188919
Author: Andrea Faulds <ajf@ajf.me>
Date:   Wed Mar 30 01:43:35 2016 +0100

    UPGRADING and NEWS

commit 6caf1d4585207d1b02fb06a216cd7da1a1f5e12d
Author: Andrea Faulds <ajf@ajf.me>
Date:   Sun Mar 20 21:18:33 2016 +0000

    Fixes

commit 6dadb1b0efe5e2ed071e95a55c806519e61377ac
Author: Andrea Faulds <ajf@ajf.me>
Date:   Sun Feb 14 02:15:01 2016 +0000

    Add test for numeric string errors in assignment

commit bd5f04e8dd576f92a48d25546f4f9a0f57f374de
Author: Andrea Faulds <ajf@ajf.me>
Date:   Sat Feb 13 23:53:05 2016 +0000

    Add test for numeric string errors

commit c72e92f16d512bcae30cc9639c89bcb08d971742
Author: Andrea Faulds <ajf@ajf.me>
Date:   Tue Jan 26 23:28:33 2016 +0000

    Add test for scientific notation in integer operations

commit d94c08852d405b3a7ef6c84d24bf7915c890ce78
Author: Andrea Faulds <ajf@ajf.me>
Date:   Sun Feb 14 01:25:57 2016 +0000

    Disable optimiser evaluation for numeric string errors

commit 30ee954ed13d933e766c68605d683c8ebae3d8ee
Author: Andrea Faulds <ajf@ajf.me>
Date:   Sun Feb 14 01:46:25 2016 +0000

    fixup

commit a6403b79e054c95e2b7345d787f3092b261eed27
Author: Andrea Faulds <ajf@ajf.me>
Date:   Sat Feb 13 22:00:27 2016 +0000

    Do not convert error-causing numeric strings ahead-of-time

commit f9dc35401471ef3035954cb6f171826769297548
Author: Andrea Faulds <ajf@ajf.me>
Date:   Sat Feb 13 19:15:38 2016 +0000

    Disable compile-time evaluation for numeric string errors

commit e05b0cc8496ea082c6db27efd8b8277ef1f785b5
Author: Andrea Faulds <ajf@ajf.me>
Date:   Fri Feb 5 11:42:26 2016 +0000

    Make _zval_get_long_func_noisy function for inlining

commit 84d66321a57e579759109650c8bb7e3d5002854a
Author: Andrea Faulds <ajf@ajf.me>
Date:   Tue Jan 26 23:10:00 2016 +0000

    Update tests

commit 5ac4a0cc4bff282e3a15eaa8ab44b67391881a6d
Author: Andrea Faulds <ajf@ajf.me>
Date:   Tue Jan 26 22:08:19 2016 +0000

    Use is_numeric_string_ex for zval_get_long etc.

commit c21f08848533723331012a62a153de3577731d6a
Author: Andrea Faulds <ajf@ajf.me>
Date:   Thu Jan 7 21:13:04 2016 +0000

    Update tests

commit 63e214cf8160420bfc51c6a2b4ae32f09ad8e8af
Author: Andrea Faulds <ajf@ajf.me>
Date:   Wed Jan 6 00:28:01 2016 +0000

    Warn on non-/bad numeric strings in arithmetic

39 files changed:
NEWS
UPGRADING
Zend/tests/add_006.phpt
Zend/tests/add_007.phpt
Zend/tests/constant_expressions_dynamic.phpt
Zend/tests/int_conversion_exponents.phpt [new file with mode: 0644]
Zend/tests/numeric_string_errors.phpt [new file with mode: 0644]
Zend/tests/numeric_string_errors_assign.phpt [new file with mode: 0644]
Zend/tests/self_and.phpt
Zend/tests/self_mod.phpt
Zend/tests/self_or.phpt
Zend/tests/self_xor.phpt
Zend/tests/shift_001.phpt
Zend/tests/shift_002.phpt
Zend/zend_API.c
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_operators.c
Zend/zend_operators.h
ext/opcache/Optimizer/block_pass.c
ext/opcache/Optimizer/pass1_5.c
ext/opcache/Optimizer/pass2.c
ext/standard/tests/file/file_put_contents_variation7.phpt
ext/standard/tests/general_functions/floatval.phpt
ext/standard/tests/general_functions/floatval_variation1.phpt
ext/standard/tests/general_functions/gettype_settype_variation2.phpt
ext/standard/tests/math/decbin_basic.phpt
ext/standard/tests/math/dechex_basic.phpt
ext/standard/tests/math/decoct_basic.phpt
ext/standard/tests/math/pow_variation1.phpt
ext/standard/tests/math/pow_variation1_64bit.phpt
ext/standard/tests/math/pow_variation2.phpt
ext/standard/tests/strings/bug55871.phpt
ext/standard/type.c
tests/lang/bug28800.phpt
tests/lang/operators/bitwiseShiftLeft_variationStr_64bit.phpt
tests/lang/operators/bitwiseShiftRight_variationStr.phpt
tests/lang/operators/modulus_variationStr.phpt
tests/lang/operators/negate_variationStr.phpt

diff --git a/NEWS b/NEWS
index f677f0a0d3710ad9d04c5318a479765166e665cc..af7a2afe12cf6e688c72a6387731b5f33f665aac 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,11 @@ PHP                                                                        NEWS
   . Added support for negative string offsets in string offset syntax and
     various string functions. (Francois)
   . Added a form of the list() construct where keys can be specified. (Andrea)
+  . Number operators taking numeric strings now emit E_NOTICEs or E_WARNINGs
+    when given malformed numeric strings. (Andrea)
+  . (int), intval() where $base is 10 or unspecified, settype(), integer
+    operators and other conversions now always respect scientific notation in
+    numeric strings. (Andrea)
 
 - FTP:
   . Implemented FR #55651 (Option to ignore the returned FTP PASV address).
index a938978d7bf7fbd181646fb8e50ace03bfdf3c1e..bda00da7db7f45a3ed7032b58ea3ea1d6088803b 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -21,6 +21,10 @@ PHP 7.1 UPGRADE NOTES
 - Core:
   . 'void' can no longer be used as the name of a class, interface, or trait.
     This applies to declarations, class_alias() and use statements.
+  . (int), intval() where $base is 10 or unspecified, settype(), integer
+    operators and other conversions now always respect scientific notation in
+    numeric strings.
+    (RFC: https://wiki.php.net/rfc/invalid_strings_in_arithmetic)
 
 - JSON:
   . When calling json_encode with JSON_UNESCAPED_UNICODE option, U+2028 and
@@ -37,6 +41,10 @@ PHP 7.1 UPGRADE NOTES
     (RFC: https://wiki.php.net/rfc/negative-string-offsets)
   . Added a form of the list() construct where keys can be specified.
     (RFC: https://wiki.php.net/rfc/list_keys)
+  . Number operators taking numeric strings now emit "A non well formed numeric
+    string encountered" E_NOTICEs for leading-numeric strings, and "A
+    non-numeric string encountered" E_WARNINGs for non-numeric strings.
+    (RFC: https://wiki.php.net/rfc/invalid_strings_in_arithmetic)
 
 ========================================
 3. Changes in SAPI modules
index d56df2f329cd3fba8faa0037d06f4696b92b5402..fe1c0830e2584caaecd8be3684d74d7532250db5 100644 (file)
@@ -38,11 +38,19 @@ var_dump($c);
 echo "Done\n";
 ?>
 --EXPECTF--    
+
+Warning: A non-numeric value encountered in %s on line %d
 int(75636)
+
+Notice: A non well formed numeric value encountered in %s on line %d
 int(951858)
 int(48550510)
 float(75661.68)
+
+Warning: A non-numeric value encountered in %s on line %d
 int(75636)
+
+Notice: A non well formed numeric value encountered in %s on line %d
 int(951858)
 int(48550510)
 float(75661.68)
index 66f54057060309051693bd17bb88c775a14da8de..089b24ae0b5276b65b74dbf66a4c624a4e8341d3 100644 (file)
@@ -19,8 +19,13 @@ var_dump($c);
 echo "Done\n";
 ?>
 --EXPECTF--    
+
+Warning: A non-numeric value encountered in %s on line %d
+
 Exception: Unsupported operand types
 
+Warning: A non-numeric value encountered in %s on line %d
+
 Fatal error: Uncaught Error: Unsupported operand types in %s:%d
 Stack trace:
 #0 {main}
index d4e06ee258bcf38373e4f860e500ff6aa1ab6784..b0ba3a5b19431a134862c1fe52817834d4e8ef8f 100644 (file)
@@ -42,7 +42,9 @@ var_dump(
 );
 
 ?>
---EXPECT--
+--EXPECTF--
+
+Warning: A non-numeric value encountered in %s on line %d
 int(3)
 string(4) "1foo"
 bool(false)
diff --git a/Zend/tests/int_conversion_exponents.phpt b/Zend/tests/int_conversion_exponents.phpt
new file mode 100644 (file)
index 0000000..d924cb7
--- /dev/null
@@ -0,0 +1,52 @@
+--TEST--
+Integer conversion from scientific notation
+--FILE--
+<?php
+
+var_dump((int)"1.2345e9");
+var_dump((int)"-1.2345e9");
+var_dump(intval("1.2345e9"));
+var_dump(intval("-1.2345e9"));
+var_dump("1.2345e9" % PHP_INT_MAX);
+var_dump("-1.2345e9" % PHP_INT_MIN);
+var_dump("1.2345e9" | 0);
+var_dump("-1.2345e9" | 0);
+
+echo PHP_EOL;
+
+var_dump((int)" 1.2345e9  abc");
+var_dump((int)" -1.2345e9  abc");
+var_dump(intval(" 1.2345e9  abc"));
+var_dump(intval(" -1.2345e9  abc"));
+var_dump(" 1.2345e9  abc" % PHP_INT_MAX);
+var_dump(" -1.2345e9  abc" % PHP_INT_MIN);
+var_dump(" 1.2345e9  abc" | 0);
+var_dump(" -1.2345e9  abc" | 0);
+
+?>
+--EXPECTF--
+int(1234500000)
+int(-1234500000)
+int(1234500000)
+int(-1234500000)
+int(1234500000)
+int(-1234500000)
+int(1234500000)
+int(-1234500000)
+
+int(1234500000)
+int(-1234500000)
+int(1234500000)
+int(-1234500000)
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(1234500000)
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(-1234500000)
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(1234500000)
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(-1234500000)
diff --git a/Zend/tests/numeric_string_errors.phpt b/Zend/tests/numeric_string_errors.phpt
new file mode 100644 (file)
index 0000000..26ceea7
--- /dev/null
@@ -0,0 +1,195 @@
+--TEST--
+Invalid numeric string E_WARNINGs and E_NOTICEs
+--FILE--
+<?php
+
+var_dump("2 Lorem" + "3 ipsum");
+var_dump("dolor" + "sit");
+echo "---", PHP_EOL;
+var_dump("5 amet," - "7 consectetur");
+var_dump("adipiscing" - "elit,");
+echo "---", PHP_EOL;
+var_dump("11 sed" * "13 do");
+var_dump("eiusmod" * "tempor");
+echo "---", PHP_EOL;
+var_dump("17 incididunt" / "19 ut");
+var_dump("labore" / "et");
+echo "---", PHP_EOL;
+var_dump("23 dolore" ** "29 magna");
+var_dump("aliqua." ** "Ut");
+echo "---", PHP_EOL;
+var_dump("31 enim" % "37 ad");
+try {
+    var_dump("minim" % "veniam,");
+} catch (DivisionByZeroError $e) {
+}
+echo "---", PHP_EOL;
+var_dump("41 minim" << "43 veniam,");
+var_dump("quis" << "nostrud");
+echo "---", PHP_EOL;
+var_dump("47 exercitation" >> "53 ullamco");
+var_dump("laboris" >> "nisi");
+echo "---", PHP_EOL;
+var_dump("59 ut" | 61);
+var_dump(67 | "71 aliquip");
+var_dump("ex" | 73);
+var_dump(79 | "ea");
+echo "---", PHP_EOL;
+var_dump("83 commodo" & 89);
+var_dump(97 & "101 consequat.");
+var_dump("Duis" & 103);
+var_dump(107 & "aute");
+echo "---", PHP_EOL;
+var_dump("109 irure" ^ 113);
+var_dump(127 ^ "131 dolor");
+var_dump("in" ^ 137);
+var_dump(139 ^ "reprehenderit");
+echo "---", PHP_EOL;
+var_dump(+"149 in");
+var_dump(+"voluptate");
+echo "---", PHP_EOL;
+var_dump(-"151 velit");
+var_dump(-"esse");
+?>
+--EXPECTF--
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(5)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(-2)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(143)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+float(0.89473684210526)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: Division by zero in %s on line %d
+float(NAN)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+float(3.0910586430935E+39)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+int(1)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(31)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(360639813910528)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(0)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(63)
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(71)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(73)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(79)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(81)
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(97)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(28)
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(252)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(137)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(139)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(149)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(-151)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
diff --git a/Zend/tests/numeric_string_errors_assign.phpt b/Zend/tests/numeric_string_errors_assign.phpt
new file mode 100644 (file)
index 0000000..7fb8898
--- /dev/null
@@ -0,0 +1,236 @@
+--TEST--
+Invalid numeric string E_WARNINGs and E_NOTICEs, combined assignment operations
+--FILE--
+<?php
+
+// prevents CT eval
+function foxcache($val) {
+    return [$val][0];
+}
+
+$a = foxcache("2 Lorem");
+$a += "3 ipsum";
+var_dump($a);
+$a = foxcache("dolor");
+$a += "sit";
+var_dump($a);
+echo "---", PHP_EOL;
+$a = foxcache("5 amet,");
+$a -= "7 consectetur";
+var_dump($a);
+$a = foxcache("adipiscing");
+$a -= "elit,";
+var_dump($a);
+echo "---", PHP_EOL;
+$a = foxcache("11 sed");
+$a *= "13 do";
+var_dump($a);
+$a = foxcache("eiusmod"); 
+$a *= "tempor";
+var_dump($a);
+echo "---", PHP_EOL;
+$a = foxcache("17 incididunt");
+$a /= "19 ut";
+var_dump($a);
+$a = foxcache("labore");
+$a /= "et";
+var_dump($a);
+echo "---", PHP_EOL;
+$a = foxcache("23 dolore");
+$a **= "29 magna";
+var_dump($a);
+$a = foxcache("aliqua.");
+$a **= "Ut";
+var_dump($a);
+echo "---", PHP_EOL;
+$a = foxcache("31 enim");
+$a %= "37 ad";
+var_dump($a);
+try {
+    $a = foxcache("minim");
+    $a %= "veniam,";
+    var_dump($a);
+} catch (DivisionByZeroError $e) {
+}
+echo "---", PHP_EOL;
+$a = foxcache("41 minim");
+$a <<= "43 veniam,";
+var_dump($a);
+$a = foxcache("quis");
+$a <<= "nostrud";
+var_dump($a);
+echo "---", PHP_EOL;
+$a = foxcache("47 exercitation");
+$a >>= "53 ullamco";
+var_dump($a);
+$a = foxcache("laboris");
+$a >>= "nisi";
+var_dump($a);
+echo "---", PHP_EOL;
+$a = foxcache("59 ut");
+$a |= 61;
+var_dump($a);
+$a = foxcache(67);
+$a |= "71 aliquip";
+var_dump($a);
+$a = foxcache("ex");
+$a |= 73;
+var_dump($a);
+$a = foxcache(79);
+$a |= "ea";
+var_dump($a);
+echo "---", PHP_EOL;
+$a = foxcache("83 commodo");
+$a &= 89;
+var_dump($a);
+$a = foxcache(97);
+$a &= "101 consequat.";
+var_dump($a);
+$a = foxcache("Duis");
+$a &= 103;
+var_dump($a);
+$a = foxcache(107);
+$a &= "aute";
+var_dump($a);
+echo "---", PHP_EOL;
+$a = foxcache("109 irure");
+$a ^= 113;
+var_dump($a);
+$a = foxcache(127);
+$a ^= "131 dolor";
+var_dump($a);
+$a = foxcache("in");
+$a ^= 137;
+var_dump($a);
+$a = foxcache(139);
+$a ^= "reprehenderit";
+var_dump($a);
+?>
+--EXPECTF--
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(5)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(-2)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(143)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+float(0.89473684210526)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: Division by zero in %s on line %d
+float(NAN)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+float(3.0910586430935E+39)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+int(1)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(31)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(360639813910528)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(0)
+
+Warning: A non-numeric value encountered in %s on line %d
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(63)
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(71)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(73)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(79)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(81)
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(97)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(0)
+---
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(28)
+
+Notice: A non well formed numeric value encountered in %s on line %d
+int(252)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(137)
+
+Warning: A non-numeric value encountered in %s on line %d
+int(139)
index cdcde77992b06b51f3bdb0ebe8f5015f60c5fe9c..44db877e929afdd2bbc40627722391d5fbaa97e2 100644 (file)
@@ -20,6 +20,10 @@ echo "Done\n";
 ?>
 --EXPECTF--    
 int(18)
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
+
+Notice: A non well formed numeric value encountered in %s on line %d
 int(33)
 Done
index 19e45d88fc4466ac5117294167e50a8b7b5f5550..0b10987aeb86cadeb0bdb9a0d2363639fa87bc24 100644 (file)
@@ -20,6 +20,10 @@ echo "Done\n";
 ?>
 --EXPECTF--
 int(13)
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
+
+Notice: A non well formed numeric value encountered in %s on line %d
 int(3)
 Done
index ae667bff16af85ce613bed45f137ab2e62c08216..8ace518bde58ceefbdf89908f92795bd5ff2d582 100644 (file)
@@ -20,6 +20,10 @@ echo "Done\n";
 ?>
 --EXPECTF--
 int(127)
+
+Warning: A non-numeric value encountered in %s on line %d
 int(11)
+
+Notice: A non well formed numeric value encountered in %s on line %d
 int(45345)
 Done
index a7e43f539d6ecef52df1429f78395eef09886f88..c097930d6ddce2758b2c126d69922d0ee0058647 100644 (file)
@@ -20,6 +20,10 @@ echo "Done\n";
 ?>
 --EXPECTF--
 int(109)
+
+Warning: A non-numeric value encountered in %s on line %d
 int(11)
+
+Notice: A non well formed numeric value encountered in %s on line %d
 int(45312)
 Done
index aeb399452d50b7fd98ece1d88b3536ca839a4660..7546f1a6d8f5e6f1c3d285d2b047716f1c7feae4 100644 (file)
@@ -20,6 +20,10 @@ echo "Done\n";
 ?>
 --EXPECTF--    
 int(492)
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
+
+Notice: A non well formed numeric value encountered in %s on line %d
 int(362760)
 Done
index 4d8421a5666c0a143f4beff0a7acd5b5ce167a56..6288152585f2076e7584b6d49ac0a872a338742f 100644 (file)
@@ -20,6 +20,10 @@ echo "Done\n";
 ?>
 --EXPECTF--    
 int(30)
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
+
+Notice: A non well formed numeric value encountered in %s on line %d
 int(5668)
 Done
index 5ebfe2cb178226371db1a5d8211dfef558201000..18e6e0f4f4a2e285d62069ad54f9edeecb9a90ce 100644 (file)
@@ -370,11 +370,7 @@ ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_weak(zval *arg, zend_long *de
                if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) {
                        return 0;
                }
-               if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) {
-                       *dest = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
-               } else {
-                       *dest = zend_dval_to_lval(Z_DVAL_P(arg));
-               }
+               *dest = zend_dval_to_lval_cap(Z_DVAL_P(arg));
        } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
                double d;
                int type;
@@ -384,11 +380,7 @@ ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_weak(zval *arg, zend_long *de
                                if (UNEXPECTED(zend_isnan(d))) {
                                        return 0;
                                }
-                               if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) {
-                                       *dest = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
-                               } else {
-                                       *dest = zend_dval_to_lval(d);
-                               }
+                               *dest = zend_dval_to_lval_cap(d);
                        } else {
                                return 0;
                        }
index 2e1ce9ba4482122ea38a42be7dc432c60ba8a99a..1401a6e051a44742ee561ed0bd6f378f3f213c51 100644 (file)
@@ -6237,6 +6237,35 @@ static zend_bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */
 }
 /* }}} */
 
+ZEND_API zend_bool zend_binary_op_produces_numeric_string_error(uint32_t opcode, zval *op1, zval *op2) /* {{{ */
+{
+       if (!(opcode == ZEND_ADD || opcode == ZEND_SUB || opcode == ZEND_MUL || opcode == ZEND_DIV
+               || opcode == ZEND_POW || opcode == ZEND_MOD || opcode == ZEND_SL || opcode == ZEND_SR
+               || opcode == ZEND_BW_OR || opcode == ZEND_BW_AND || opcode == ZEND_BW_XOR)) {
+               return 0;
+       }
+
+       /* While basic arithmetic operators always produce numeric string errors,
+        * bitwise operators don't produce errors if both operands are strings */
+       if ((opcode == ZEND_BW_OR || opcode == ZEND_BW_AND || opcode == ZEND_BW_XOR)
+               && Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
+               return 0;
+       }
+
+       if (Z_TYPE_P(op1) == IS_STRING
+               && !is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), NULL, NULL, 0)) {
+               return 1;
+       }
+
+       if (Z_TYPE_P(op2) == IS_STRING
+               && !is_numeric_string(Z_STRVAL_P(op2), Z_STRLEN_P(op2), NULL, NULL, 0)) {
+               return 1;
+       }
+
+       return 0;
+}
+/* }}} */
+
 static inline zend_bool zend_try_ct_eval_binary_op(zval *result, uint32_t opcode, zval *op1, zval *op2) /* {{{ */
 {
        binary_op_type fn = get_binary_op(opcode);
@@ -6250,6 +6279,11 @@ static inline zend_bool zend_try_ct_eval_binary_op(zval *result, uint32_t opcode
                return 0;
        }
 
+       /* don't evaluate numeric string error-producing operations at compile-time */
+       if (zend_binary_op_produces_numeric_string_error(opcode, op1, op2)) {
+               return 0;
+       }
+
        fn(result, op1, op2);
        return 1;
 }
@@ -6262,11 +6296,11 @@ static inline void zend_ct_eval_unary_op(zval *result, uint32_t opcode, zval *op
 }
 /* }}} */
 
-static inline void zend_ct_eval_unary_pm(zval *result, zend_ast_kind kind, zval *op) /* {{{ */
+static inline zend_bool zend_try_ct_eval_unary_pm(zval *result, zend_ast_kind kind, zval *op) /* {{{ */
 {
        zval left;
        ZVAL_LONG(&left, (kind == ZEND_AST_UNARY_PLUS) ? 1 : -1);
-       mul_function(result, &left, op);
+       return zend_try_ct_eval_binary_op(result, ZEND_MUL, &left, op);
 }
 /* }}} */
 
@@ -6464,10 +6498,11 @@ void zend_compile_unary_pm(znode *result, zend_ast *ast) /* {{{ */
        zend_compile_expr(&expr_node, expr_ast);
 
        if (expr_node.op_type == IS_CONST) {
-               result->op_type = IS_CONST;
-               zend_ct_eval_unary_pm(&result->u.constant, ast->kind, &expr_node.u.constant);
-               zval_ptr_dtor(&expr_node.u.constant);
-               return;
+               if (zend_try_ct_eval_unary_pm(&result->u.constant, ast->kind, &expr_node.u.constant)) {
+                       result->op_type = IS_CONST;
+                       zval_ptr_dtor(&expr_node.u.constant);
+                       return;
+               }
        }
 
        lefthand_node.op_type = IS_CONST;
@@ -7802,7 +7837,9 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
                                return;
                        }
 
-                       zend_ct_eval_unary_pm(&result, ast->kind, zend_ast_get_zval(ast->child[0]));
+                       if (!zend_try_ct_eval_unary_pm(&result, ast->kind, zend_ast_get_zval(ast->child[0]))) {
+                               return;
+                       }
                        break;
                case ZEND_AST_CONDITIONAL:
                {
index f3dc8081b8a7b63d930962697a82ddfc3282109e..b3ba352df88ea2de5c8eb7c55fdca18c1490014e 100644 (file)
@@ -1023,6 +1023,8 @@ END_EXTERN_C()
 /* The default value for CG(compiler_options) during eval() */
 #define ZEND_COMPILE_DEFAULT_FOR_EVAL                  0
 
+ZEND_API zend_bool zend_binary_op_produces_numeric_string_error(uint32_t opcode, zval *op1, zval *op2);
+
 #endif /* ZEND_COMPILE_H */
 
 /*
index 50557e56d80dbd97fd46f2e347e157f266e85498..1710ba44dd109659c3002f63136e73dba1d737a0 100644 (file)
@@ -147,7 +147,7 @@ static zend_always_inline void zend_unwrap_reference(zval *op) /* {{{ */
 }
 /* }}} */
 
-ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */
+void ZEND_FASTCALL _convert_scalar_to_number(zval *op, zend_bool silent) /* {{{ */
 {
 try_again:
        switch (Z_TYPE_P(op)) {
@@ -159,8 +159,11 @@ try_again:
                                zend_string *str;
 
                                str = Z_STR_P(op);
-                               if ((Z_TYPE_INFO_P(op)=is_numeric_string(ZSTR_VAL(str), ZSTR_LEN(str), &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) {
+                               if ((Z_TYPE_INFO_P(op)=is_numeric_string(ZSTR_VAL(str), ZSTR_LEN(str), &Z_LVAL_P(op), &Z_DVAL_P(op), silent ? 1 : -1)) == 0) {
                                        ZVAL_LONG(op, 0);
+                                       if (!silent) {
+                                               zend_error(E_WARNING, "A non-numeric value encountered");
+                                       }
                                }
                                zend_string_release(str);
                                break;
@@ -186,18 +189,27 @@ try_again:
 }
 /* }}} */
 
+ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */
+{
+       _convert_scalar_to_number(op, 1);
+}
+/* }}} */
+
 /* {{{ zendi_convert_scalar_to_number */
-#define zendi_convert_scalar_to_number(op, holder, result)                     \
+#define zendi_convert_scalar_to_number(op, holder, result, silent)     \
        if (op==result) {                                                                                               \
                if (Z_TYPE_P(op) != IS_LONG) {                                                          \
-                       convert_scalar_to_number(op);                                   \
+                       _convert_scalar_to_number(op, silent);                          \
                }                                                                                                                       \
        } else {                                                                                                                \
                switch (Z_TYPE_P(op)) {                                                                         \
                        case IS_STRING:                                                                                 \
                                {                                                                                                       \
-                                       if ((Z_TYPE_INFO(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1)) == 0) {        \
+                                       if ((Z_TYPE_INFO(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), silent ? 1 : -1)) == 0) {  \
                                                ZVAL_LONG(&(holder), 0);                                                        \
+                                               if (!silent) {                                                                          \
+                                                       zend_error(E_WARNING, "A non-numeric value encountered");       \
+                                               }                                                                                                       \
                                        }                                                                                                               \
                                        (op) = &(holder);                                                                               \
                                        break;                                                                                                  \
@@ -258,7 +270,7 @@ try_again:
                                }                                                                                                               \
                        }                                                                                                                       \
                        ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(op, op_func);                      \
-                       op1_lval = _zval_get_long_func(op1);                                            \
+                       op1_lval = _zval_get_long_func_noisy(op1);                                      \
                } else {                                                                                                                \
                        op1_lval = Z_LVAL_P(op1);                                                                       \
                }                                                                                                                               \
@@ -273,7 +285,7 @@ try_again:
                                }                                                                                                               \
                        }                                                                                                                       \
                        ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(op);                                       \
-                       op2_lval = _zval_get_long_func(op2);                                            \
+                       op2_lval = _zval_get_long_func_noisy(op2);                                      \
                } else {                                                                                                                \
                        op2_lval = Z_LVAL_P(op2);                                                                       \
                }                                                                                                                               \
@@ -313,8 +325,11 @@ try_again:
                case IS_STRING:
                        {
                                zend_string *str = Z_STR_P(op);
-
-                               ZVAL_LONG(op, ZEND_STRTOL(ZSTR_VAL(str), NULL, base));
+                               if (base == 10) {
+                                       ZVAL_LONG(op, zval_get_long(op));
+                               } else {
+                                       ZVAL_LONG(op, ZEND_STRTOL(ZSTR_VAL(str), NULL, base));
+                               }
                                zend_string_release(str);
                        }
                        break;
@@ -728,7 +743,7 @@ ZEND_API void multi_convert_to_string_ex(int argc, ...) /* {{{ */
 }
 /* }}} */
 
-ZEND_API zend_long ZEND_FASTCALL _zval_get_long_func(zval *op) /* {{{ */
+static zend_always_inline zend_long ZEND_FASTCALL _zval_get_long_func_ex(zval *op, zend_bool silent) /* {{{ */
 {
 try_again:
        switch (Z_TYPE_P(op)) {
@@ -744,7 +759,26 @@ try_again:
                case IS_DOUBLE:
                        return zend_dval_to_lval(Z_DVAL_P(op));
                case IS_STRING:
-                       return ZEND_STRTOL(Z_STRVAL_P(op), NULL, 10);
+                       {
+                               zend_uchar type;
+                               zend_long lval;
+                               double dval;
+                               if (0 == (type = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &lval, &dval, silent ? 1 : -1))) {
+                                       if (!silent) {
+                                               zend_error(E_WARNING, "A non-numeric value encountered");
+                                       }
+                                       return 0;
+                               } else if (EXPECTED(type == IS_LONG)) {
+                                       return lval;
+                               } else {
+                                       /* Previously we used strtol here, not is_numeric_string,
+                                        * and strtol gives you LONG_MAX/_MIN on overflow.
+                                        * We use use saturating conversion to emulate strtol()'s
+                                        * behaviour.
+                                        */
+                                        return zend_dval_to_lval_cap(dval);
+                               }
+                       }
                case IS_ARRAY:
                        return zend_hash_num_elements(Z_ARRVAL_P(op)) ? 1 : 0;
                case IS_OBJECT:
@@ -766,6 +800,18 @@ try_again:
 }
 /* }}} */
 
+ZEND_API zend_long ZEND_FASTCALL _zval_get_long_func(zval *op) /* {{{ */
+{
+       return _zval_get_long_func_ex(op, 1);
+}
+/* }}} */
+
+static zend_long ZEND_FASTCALL _zval_get_long_func_noisy(zval *op) /* {{{ */
+{
+       return _zval_get_long_func_ex(op, 0);
+}
+/* }}} */
+
 ZEND_API double ZEND_FASTCALL _zval_get_double_func(zval *op) /* {{{ */
 {
 try_again:
@@ -916,8 +962,8 @@ ZEND_API int ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2) /* {
                                } else if (!converted) {
                                        ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD, add_function);
 
-                                       zendi_convert_scalar_to_number(op1, op1_copy, result);
-                                       zendi_convert_scalar_to_number(op2, op2_copy, result);
+                                       zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
+                                       zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
                                        converted = 1;
                                } else {
                                        zend_throw_error(NULL, "Unsupported operand types");
@@ -969,8 +1015,8 @@ ZEND_API int ZEND_FASTCALL sub_function(zval *result, zval *op1, zval *op2) /* {
                                } else if (!converted) {
                                        ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB, sub_function);
 
-                                       zendi_convert_scalar_to_number(op1, op1_copy, result);
-                                       zendi_convert_scalar_to_number(op2, op2_copy, result);
+                                       zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
+                                       zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
                                        converted = 1;
                                } else {
                                        zend_throw_error(NULL, "Unsupported operand types");
@@ -1016,8 +1062,8 @@ ZEND_API int ZEND_FASTCALL mul_function(zval *result, zval *op1, zval *op2) /* {
                                } else if (!converted) {
                                        ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL, mul_function);
 
-                                       zendi_convert_scalar_to_number(op1, op1_copy, result);
-                                       zendi_convert_scalar_to_number(op2, op2_copy, result);
+                                       zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
+                                       zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
                                        converted = 1;
                                } else {
                                        zend_throw_error(NULL, "Unsupported operand types");
@@ -1098,13 +1144,13 @@ ZEND_API int ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *op2) /* {
                                                ZVAL_LONG(result, 0);
                                                return SUCCESS;
                                        } else {
-                                               zendi_convert_scalar_to_number(op1, op1_copy, result);
+                                               zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
                                        }
                                        if (Z_TYPE_P(op2) == IS_ARRAY) {
                                                ZVAL_LONG(result, 1L);
                                                return SUCCESS;
                                        } else {
-                                               zendi_convert_scalar_to_number(op2, op2_copy, result);
+                                               zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
                                        }
                                        converted = 1;
                                } else {
@@ -1169,8 +1215,8 @@ ZEND_API int ZEND_FASTCALL div_function(zval *result, zval *op1, zval *op2) /* {
                                } else if (!converted) {
                                        ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV, div_function);
 
-                                       zendi_convert_scalar_to_number(op1, op1_copy, result);
-                                       zendi_convert_scalar_to_number(op2, op2_copy, result);
+                                       zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
+                                       zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
                                        converted = 1;
                                } else {
                                        zend_throw_error(NULL, "Unsupported operand types");
@@ -1377,13 +1423,13 @@ ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op
 
        if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
                ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_OR, bitwise_or_function);
-               op1_lval = _zval_get_long_func(op1);
+               op1_lval = _zval_get_long_func_noisy(op1);
        } else {
                op1_lval = Z_LVAL_P(op1);
        }
        if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
                ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_OR);
-               op2_lval = _zval_get_long_func(op2);
+               op2_lval = _zval_get_long_func_noisy(op2);
        } else {
                op2_lval = Z_LVAL_P(op2);
        }
@@ -1444,13 +1490,13 @@ ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *o
 
        if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
                ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_AND, bitwise_and_function);
-               op1_lval = _zval_get_long_func(op1);
+               op1_lval = _zval_get_long_func_noisy(op1);
        } else {
                op1_lval = Z_LVAL_P(op1);
        }
        if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
                ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_AND);
-               op2_lval = _zval_get_long_func(op2);
+               op2_lval = _zval_get_long_func_noisy(op2);
        } else {
                op2_lval = Z_LVAL_P(op2);
        }
@@ -1511,13 +1557,13 @@ ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *o
 
        if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
                ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_XOR, bitwise_xor_function);
-               op1_lval = _zval_get_long_func(op1);
+               op1_lval = _zval_get_long_func_noisy(op1);
        } else {
                op1_lval = Z_LVAL_P(op1);
        }
        if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
                ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_XOR);
-               op2_lval = _zval_get_long_func(op2);
+               op2_lval = _zval_get_long_func_noisy(op2);
        } else {
                op2_lval = Z_LVAL_P(op2);
        }
@@ -1944,8 +1990,8 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
                                                ZVAL_LONG(result, zval_is_true(op1) ? 0 : -1);
                                                return SUCCESS;
                                        } else {
-                                               zendi_convert_scalar_to_number(op1, op1_copy, result);
-                                               zendi_convert_scalar_to_number(op2, op2_copy, result);
+                                               zendi_convert_scalar_to_number(op1, op1_copy, result, 1);
+                                               zendi_convert_scalar_to_number(op2, op2_copy, result, 1);
                                                converted = 1;
                                        }
                                } else if (Z_TYPE_P(op1)==IS_ARRAY) {
index b0b167bd7477683bcd7c6a551d70cbd7cdc46476..db6162a4e52b3c8a4a3cef03b925078322aa7068 100644 (file)
@@ -122,6 +122,16 @@ static zend_always_inline zend_long zend_dval_to_lval(double d)
        return (zend_long)d;
 }
 #endif
+
+static zend_always_inline zend_long zend_dval_to_lval_cap(double d)
+{
+       if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) {
+               return 0;
+       } else if (!ZEND_DOUBLE_FITS_LONG(d)) {
+               return (d > 0 ? ZEND_LONG_MAX : ZEND_LONG_MIN);
+       }
+       return (zend_long)d;
+}
 /* }}} */
 
 #define ZEND_IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
index 52a440fba07368a63c4967aeefd4c5615857c904..0ecb57e2b90f9725bb9c782435b4db6665b51d1c 100644 (file)
@@ -683,9 +683,14 @@ optimize_constant_binary_op:
                            } else if ((opline->opcode == ZEND_SL || opline->opcode == ZEND_SR) &&
                                zval_get_long(&ZEND_OP2_LITERAL(opline)) < 0) {
                                                SET_VAR_SOURCE(opline);
+                               opline++;
+                                               continue;
+                                       } else if (zend_binary_op_produces_numeric_string_error(opline->opcode, &ZEND_OP1_LITERAL(opline), &ZEND_OP2_LITERAL(opline))) {
+                                               SET_VAR_SOURCE(opline);
                                opline++;
                                                continue;
                                        }
+                                       printf("%d\n", opline->opcode);
                                        er = EG(error_reporting);
                                        EG(error_reporting) = 0;
                                        if (binary_op(&result, &ZEND_OP1_LITERAL(opline), &ZEND_OP2_LITERAL(opline)) == SUCCESS) {
index ae31504f4c08053a62a4fd4ccac8c132af1d23ac..71f879e958a8aa422536428754eb3033ad8cfd8c 100644 (file)
@@ -84,6 +84,9 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
                                        zval_get_long(&ZEND_OP2_LITERAL(opline)) < 0) {
                                        /* shift by negative number */
                                        break;
+                               } else if (zend_binary_op_produces_numeric_string_error(opline->opcode, &ZEND_OP1_LITERAL(opline), &ZEND_OP2_LITERAL(opline))) {
+                                       /* produces numeric string E_NOTICE/E_WARNING */
+                                       break;
                                }
                                er = EG(error_reporting);
                                EG(error_reporting) = 0;
index d2a2064a7877d22231f369e71e2aa661556497f7..2be97ed9382e78d8ab7979a54d849a2fc74f5428 100644 (file)
@@ -48,7 +48,10 @@ void zend_optimizer_pass2(zend_op_array *op_array)
                        case ZEND_POW:
                                if (ZEND_OP1_TYPE(opline) == IS_CONST) {
                                        if (Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING) {
-                                               convert_scalar_to_number(&ZEND_OP1_LITERAL(opline));
+                                               /* don't optimise if it should produce a runtime numeric string error */
+                                               if (is_numeric_string(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)), NULL, NULL, 0)) {
+                                                       convert_scalar_to_number(&ZEND_OP1_LITERAL(opline));
+                                               }
                                        }
                                }
                                /* break missing *intentionally* - the assign_op's may only optimize op2 */
@@ -63,7 +66,10 @@ void zend_optimizer_pass2(zend_op_array *op_array)
                                }
                                if (ZEND_OP2_TYPE(opline) == IS_CONST) {
                                        if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
-                                               convert_scalar_to_number(&ZEND_OP2_LITERAL(opline));
+                                               /* don't optimise if it should produce a runtime numeric string error */
+                                               if (is_numeric_string(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), NULL, NULL, 0)) {
+                                                       convert_scalar_to_number(&ZEND_OP2_LITERAL(opline));
+                                               }
                                        }
                                }
                                break;
@@ -73,7 +79,11 @@ void zend_optimizer_pass2(zend_op_array *op_array)
                        case ZEND_SR:
                                if (ZEND_OP1_TYPE(opline) == IS_CONST) {
                                        if (Z_TYPE(ZEND_OP1_LITERAL(opline)) != IS_LONG) {
-                                               convert_to_long(&ZEND_OP1_LITERAL(opline));
+                                               /* don't optimise if it should produce a runtime numeric string error */
+                                               if (!(Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING
+                                                       && !is_numeric_string(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)), NULL, NULL, 0))) {
+                                                       convert_to_long(&ZEND_OP1_LITERAL(opline));
+                                               }
                                        }
                                }
                                /* break missing *intentionally - the assign_op's may only optimize op2 */
@@ -86,7 +96,11 @@ void zend_optimizer_pass2(zend_op_array *op_array)
                                }
                                if (ZEND_OP2_TYPE(opline) == IS_CONST) {
                                        if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_LONG) {
-                                               convert_to_long(&ZEND_OP2_LITERAL(opline));
+                                               /* don't optimise if it should produce a runtime numeric string error */
+                                               if (!(Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING
+                                                       && !is_numeric_string(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), NULL, NULL, 0))) {
+                                                       convert_to_long(&ZEND_OP2_LITERAL(opline));
+                                               }
                                        }
                                }
                                break;
index 5c8e5f36023d8bd63b58de0a1e1ea00141797e09..b1b2face6077e2a3c766ee3ae433496486777836 100644 (file)
@@ -51,10 +51,10 @@ for($i = 0; $i<count($allDirs); $i++) {
   $j = $i+1;
   $dir = $allDirs[$i];
   echo "\n-- Iteration $j --\n";
-  $res = file_put_contents($dir."/".$filename, ($data + $i));
+  $res = file_put_contents($dir."/".$filename, ($data . $i));
   if ($res !== false) {
       $in = file_get_contents($absFile);
-      if ($in == ($data + $i)) {
+      if ($in == ($data . $i)) {
          echo "Data written correctly\n";
       }
       else {
@@ -116,4 +116,4 @@ Data written correctly
 Warning: file_put_contents(BADDIR/FileGetContentsVar7.tmp): failed to open stream: %s in %s on line %d
 No data written
 
-*** Done ***
\ No newline at end of file
+*** Done ***
index 9b7a3281e44369055b94c2aa984d924276b20d5e..d7bdffd6ae0b4c34c05f71ef8f98d7c675e6f81c 100644 (file)
@@ -155,6 +155,10 @@ float(5000000)
 float(-5000000)
 
 *** Testing floatval() on non floating types ***
+
+Notice: A non well formed numeric value encountered in %s on line 69
+
+Notice: A non well formed numeric value encountered in %s on line 70
 float(-2147483648)
 float(2147483648)
 float(%d)
index 83925b89b0ececa3d57e1bfcbf07c4fd60acd75e..aa808cfba1da17cee1fb0296d0d2fc83e7cd2765 100644 (file)
@@ -52,6 +52,11 @@ foreach ($not_float_types as $key => $type ) {
 ?>
 ===DONE===
 --EXPECTF--
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
+Notice: A non well formed numeric value encountered in %s on line %d
+
 *** Testing floatval() on non floating types ***
 
 -- Iteration : -2147483648 --
@@ -151,4 +156,4 @@ float(0)
 
 -- Iteration : null --
 float(0)
-===DONE===
\ No newline at end of file
+===DONE===
index 2242952769cc1375e48cdee2c142da6b1ef9ffcb..18b05b6a972d4e3ca989af9e05c915977de50315 100644 (file)
@@ -282,7 +282,7 @@ string(7) "integer"
 -- Iteration 18 --
 string(6) "string"
 bool(true)
-int(1)
+int(100)
 string(7) "integer"
 -- Iteration 19 --
 string(6) "string"
@@ -297,7 +297,7 @@ string(7) "integer"
 -- Iteration 21 --
 string(6) "string"
 bool(true)
-int(-1)
+int(0)
 string(7) "integer"
 -- Iteration 22 --
 string(6) "string"
@@ -312,7 +312,7 @@ string(7) "integer"
 -- Iteration 24 --
 string(6) "string"
 bool(true)
-int(1)
+int(100)
 string(7) "integer"
 -- Iteration 25 --
 string(6) "string"
@@ -327,7 +327,7 @@ string(7) "integer"
 -- Iteration 27 --
 string(6) "string"
 bool(true)
-int(-1)
+int(0)
 string(7) "integer"
 -- Iteration 28 --
 string(6) "string"
@@ -687,7 +687,7 @@ string(7) "integer"
 -- Iteration 18 --
 string(6) "string"
 bool(true)
-int(1)
+int(100)
 string(7) "integer"
 -- Iteration 19 --
 string(6) "string"
@@ -702,7 +702,7 @@ string(7) "integer"
 -- Iteration 21 --
 string(6) "string"
 bool(true)
-int(-1)
+int(0)
 string(7) "integer"
 -- Iteration 22 --
 string(6) "string"
@@ -717,7 +717,7 @@ string(7) "integer"
 -- Iteration 24 --
 string(6) "string"
 bool(true)
-int(1)
+int(100)
 string(7) "integer"
 -- Iteration 25 --
 string(6) "string"
@@ -732,7 +732,7 @@ string(7) "integer"
 -- Iteration 27 --
 string(6) "string"
 bool(true)
-int(-1)
+int(0)
 string(7) "integer"
 -- Iteration 28 --
 string(6) "string"
index b4389956f42699bf98d5f44ec235e71ca70bed65..572a04245e9b8caea8f071223e40214df86af1b0 100644 (file)
@@ -31,7 +31,7 @@ string(2) "11"
 string(7) "1011111"
 string(4) "1010"
 string(12) "111101101110"
-string(2) "11"
+string(12) "111101101110"
 string(6) "100111"
 string(1) "0"
 string(1) "1"
index 2423d8e748fb53672e1721092d98d5442471dfd3..ac53a97b34f75031739c36f68109cdb543d7fd4b 100644 (file)
@@ -30,7 +30,7 @@ string(1) "3"
 string(2) "5f"
 string(1) "a"
 string(3) "f6e"
-string(1) "3"
+string(3) "f6e"
 string(2) "27"
 string(1) "0"
 string(1) "1"
index cc1f0a899ac7bdc6959d5ecc14bffbb711c2b1cf..3a5011b973e65fca07ce3764aac334f0a9868710 100644 (file)
@@ -30,7 +30,7 @@ string(1) "3"
 string(3) "137"
 string(2) "12"
 string(4) "7556"
-string(1) "3"
+string(4) "7556"
 string(2) "47"
 string(1) "0"
 string(1) "1"
index 5576e5b49332ccf06e366cd5c23db50b6d338ab7..c744c4eb9d48f9293edc66dba5da420e6cec92e3 100644 (file)
@@ -143,21 +143,31 @@ int(1)
 int(0)
 
 -- Iteration 17 --
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
 
 -- Iteration 18 --
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
 
 -- Iteration 19 --
 int(0)
 
 -- Iteration 20 --
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
 
 -- Iteration 21 --
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
 
 -- Iteration 22 --
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
 
 -- Iteration 23 --
index e1986ba8582b863ecba3136bfd557e8bc1dad663..ea2ae45d18a6add99a868f09ebf1810286168ebf 100644 (file)
@@ -143,21 +143,31 @@ int(1)
 int(0)
 
 -- Iteration 17 --
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
 
 -- Iteration 18 --
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
 
 -- Iteration 19 --
 int(0)
 
 -- Iteration 20 --
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
 
 -- Iteration 21 --
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
 
 -- Iteration 22 --
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
 
 -- Iteration 23 --
index f571936727a808df24cdfea051166591aaa21066..36b085b647434788e9428418c6a9ef41533942e9 100644 (file)
@@ -139,21 +139,31 @@ float(20.3)
 float(1)
 
 -- Iteration 17 --
+
+Warning: A non-numeric value encountered in %s on line %d
 float(1)
 
 -- Iteration 18 --
+
+Warning: A non-numeric value encountered in %s on line %d
 float(1)
 
 -- Iteration 19 --
 int(1)
 
 -- Iteration 20 --
+
+Warning: A non-numeric value encountered in %s on line %d
 float(1)
 
 -- Iteration 21 --
+
+Warning: A non-numeric value encountered in %s on line %d
 float(1)
 
 -- Iteration 22 --
+
+Warning: A non-numeric value encountered in %s on line %d
 float(1)
 
 -- Iteration 23 --
index 249d1bd3a326f50184147f757c5630cd86145f65..0044f50ce70fb9d9a535acef935f89721572c5ed 100644 (file)
@@ -41,6 +41,8 @@ array(1) {
   [0]=>
   string(0) ""
 }
+
+Warning: A non-numeric value encountered in %s on line %d
 array(1) {
   [0]=>
   string(40) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
index d6a412f4ec443dd682fef0c7cef3836b5d1c9495..529d666d02db5cf1090a334a14ea732198f3d350 100644 (file)
@@ -154,7 +154,7 @@ PHP_FUNCTION(intval)
        ZEND_PARSE_PARAMETERS_END();
 #endif
 
-       if (Z_TYPE_P(num) != IS_STRING) {
+       if (Z_TYPE_P(num) != IS_STRING || base == 10) {
                RETVAL_LONG(zval_get_long(num));
        } else {
                RETVAL_LONG(ZEND_STRTOL(Z_STRVAL_P(num), NULL, base));
index f81ad7fec982a25be56e2aed94b30c912f5ac305..8bd2c306e1b583f8529dca94784f944318ce5d2a 100644 (file)
@@ -7,11 +7,23 @@ Bug #28800 (Incorrect string to number conversion for strings starting with 'inf
                echo ($v+0)."\n";
        }
 ?>
---EXPECT--
+--EXPECTF--
+
+Warning: A non-numeric value encountered in %s on line %d
 0
+
+Warning: A non-numeric value encountered in %s on line %d
 0
+
+Warning: A non-numeric value encountered in %s on line %d
 0
+
+Warning: A non-numeric value encountered in %s on line %d
 0
+
+Warning: A non-numeric value encountered in %s on line %d
 0
+
+Warning: A non-numeric value encountered in %s on line %d
 0
 
index d5888d837f98f7d4dd863a7911c26780c51f04b8..69fd90f1c8cd652ec36cc828549a0901e8bfb18a 100644 (file)
@@ -226,17 +226,17 @@ int(984)
 --- testing: '123abc' << 'a5.9' ---\r
 int(123)\r
 --- testing: '123e5' << '0' ---\r
-int(123)\r
+int(12300000)\r
 --- testing: '123e5' << '65' ---\r
 int(0)\r
 --- testing: '123e5' << '-44' ---\r
 Exception: Bit shift by negative number\r
 --- testing: '123e5' << '1.2' ---\r
-int(246)\r
+int(24600000)\r
 --- testing: '123e5' << '-7.7' ---\r
 Exception: Bit shift by negative number\r
 --- testing: '123e5' << 'abc' ---\r
-int(123)\r
+int(12300000)\r
 --- testing: '123e5' << '123abc' ---\r
 int(0)\r
 --- testing: '123e5' << '123e5' ---\r
@@ -250,21 +250,21 @@ int(0)
 --- testing: '123e5' << '123abc ' ---\r
 int(0)\r
 --- testing: '123e5' << '3.4a' ---\r
-int(984)\r
+int(98400000)\r
 --- testing: '123e5' << 'a5.9' ---\r
-int(123)\r
+int(12300000)\r
 --- testing: '123e5xyz' << '0' ---\r
-int(123)\r
+int(12300000)\r
 --- testing: '123e5xyz' << '65' ---\r
 int(0)\r
 --- testing: '123e5xyz' << '-44' ---\r
 Exception: Bit shift by negative number\r
 --- testing: '123e5xyz' << '1.2' ---\r
-int(246)\r
+int(24600000)\r
 --- testing: '123e5xyz' << '-7.7' ---\r
 Exception: Bit shift by negative number\r
 --- testing: '123e5xyz' << 'abc' ---\r
-int(123)\r
+int(12300000)\r
 --- testing: '123e5xyz' << '123abc' ---\r
 int(0)\r
 --- testing: '123e5xyz' << '123e5' ---\r
@@ -278,9 +278,9 @@ int(0)
 --- testing: '123e5xyz' << '123abc ' ---\r
 int(0)\r
 --- testing: '123e5xyz' << '3.4a' ---\r
-int(984)\r
+int(98400000)\r
 --- testing: '123e5xyz' << 'a5.9' ---\r
-int(123)\r
+int(12300000)\r
 --- testing: ' 123abc' << '0' ---\r
 int(123)\r
 --- testing: ' 123abc' << '65' ---\r
index a86d0cfddb21b4874cde746c569c3b2d3db6396d..a4c425aab3e2baf45b097939f17e3e6ffc386c20 100644 (file)
@@ -222,17 +222,17 @@ int(15)
 --- testing: '123abc' >> 'a5.9' ---
 int(123)
 --- testing: '123e5' >> '0' ---
-int(123)
+int(12300000)
 --- testing: '123e5' >> '65' ---
 int(0)
 --- testing: '123e5' >> '-44' ---
 Exception: Bit shift by negative number
 --- testing: '123e5' >> '1.2' ---
-int(61)
+int(6150000)
 --- testing: '123e5' >> '-7.7' ---
 Exception: Bit shift by negative number
 --- testing: '123e5' >> 'abc' ---
-int(123)
+int(12300000)
 --- testing: '123e5' >> '123abc' ---
 int(0)
 --- testing: '123e5' >> '123e5' ---
@@ -246,21 +246,21 @@ int(0)
 --- testing: '123e5' >> '123abc ' ---
 int(0)
 --- testing: '123e5' >> '3.4a' ---
-int(15)
+int(1537500)
 --- testing: '123e5' >> 'a5.9' ---
-int(123)
+int(12300000)
 --- testing: '123e5xyz' >> '0' ---
-int(123)
+int(12300000)
 --- testing: '123e5xyz' >> '65' ---
 int(0)
 --- testing: '123e5xyz' >> '-44' ---
 Exception: Bit shift by negative number
 --- testing: '123e5xyz' >> '1.2' ---
-int(61)
+int(6150000)
 --- testing: '123e5xyz' >> '-7.7' ---
 Exception: Bit shift by negative number
 --- testing: '123e5xyz' >> 'abc' ---
-int(123)
+int(12300000)
 --- testing: '123e5xyz' >> '123abc' ---
 int(0)
 --- testing: '123e5xyz' >> '123e5' ---
@@ -274,9 +274,9 @@ int(0)
 --- testing: '123e5xyz' >> '123abc ' ---
 int(0)
 --- testing: '123e5xyz' >> '3.4a' ---
-int(15)
+int(1537500)
 --- testing: '123e5xyz' >> 'a5.9' ---
-int(123)
+int(12300000)
 --- testing: ' 123abc' >> '0' ---
 int(123)
 --- testing: ' 123abc' >> '65' ---
index c647ecd38057e512e6397e823df520379f2b3cf4..4cfd7768ffe2e6b75ef1d3ebcd5013d65c1daa0e 100644 (file)
@@ -208,9 +208,9 @@ Exception: Modulo by zero
 --- testing: '123abc' % '123abc' ---\r
 int(0)\r
 --- testing: '123abc' % '123e5' ---\r
-int(0)\r
+int(123)\r
 --- testing: '123abc' % '123e5xyz' ---\r
-int(0)\r
+int(123)\r
 --- testing: '123abc' % ' 123abc' ---\r
 int(0)\r
 --- testing: '123abc' % '123 abc' ---\r
@@ -224,13 +224,13 @@ Exception: Modulo by zero
 --- testing: '123e5' % '0' ---\r
 Exception: Modulo by zero\r
 --- testing: '123e5' % '65' ---\r
-int(58)\r
+int(50)\r
 --- testing: '123e5' % '-44' ---\r
-int(35)\r
+int(20)\r
 --- testing: '123e5' % '1.2' ---\r
 int(0)\r
 --- testing: '123e5' % '-7.7' ---\r
-int(4)\r
+int(6)\r
 --- testing: '123e5' % 'abc' ---\r
 Exception: Modulo by zero\r
 --- testing: '123e5' % '123abc' ---\r
@@ -252,13 +252,13 @@ Exception: Modulo by zero
 --- testing: '123e5xyz' % '0' ---\r
 Exception: Modulo by zero\r
 --- testing: '123e5xyz' % '65' ---\r
-int(58)\r
+int(50)\r
 --- testing: '123e5xyz' % '-44' ---\r
-int(35)\r
+int(20)\r
 --- testing: '123e5xyz' % '1.2' ---\r
 int(0)\r
 --- testing: '123e5xyz' % '-7.7' ---\r
-int(4)\r
+int(6)\r
 --- testing: '123e5xyz' % 'abc' ---\r
 Exception: Modulo by zero\r
 --- testing: '123e5xyz' % '123abc' ---\r
@@ -292,9 +292,9 @@ Exception: Modulo by zero
 --- testing: ' 123abc' % '123abc' ---\r
 int(0)\r
 --- testing: ' 123abc' % '123e5' ---\r
-int(0)\r
+int(123)\r
 --- testing: ' 123abc' % '123e5xyz' ---\r
-int(0)\r
+int(123)\r
 --- testing: ' 123abc' % ' 123abc' ---\r
 int(0)\r
 --- testing: ' 123abc' % '123 abc' ---\r
@@ -320,9 +320,9 @@ Exception: Modulo by zero
 --- testing: '123 abc' % '123abc' ---\r
 int(0)\r
 --- testing: '123 abc' % '123e5' ---\r
-int(0)\r
+int(123)\r
 --- testing: '123 abc' % '123e5xyz' ---\r
-int(0)\r
+int(123)\r
 --- testing: '123 abc' % ' 123abc' ---\r
 int(0)\r
 --- testing: '123 abc' % '123 abc' ---\r
@@ -348,9 +348,9 @@ Exception: Modulo by zero
 --- testing: '123abc ' % '123abc' ---\r
 int(0)\r
 --- testing: '123abc ' % '123e5' ---\r
-int(0)\r
+int(123)\r
 --- testing: '123abc ' % '123e5xyz' ---\r
-int(0)\r
+int(123)\r
 --- testing: '123abc ' % ' 123abc' ---\r
 int(0)\r
 --- testing: '123abc ' % '123 abc' ---\r
index a25bdda7f5950f625b602893642644964e9db671..7405d42882e93964a2152ca1945f9a220e16825a 100644 (file)
@@ -16,7 +16,7 @@ foreach ($strVals as $strVal) {
    \r
 ?>\r
 ===DONE===\r
---EXPECT--\r
+--EXPECTF--\r
 --- testing: '0' ---
 int(0)
 --- testing: '65' ---
@@ -28,21 +28,37 @@ float(-1.2)
 --- testing: '-7.7' ---
 float(7.7)
 --- testing: 'abc' ---
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)
 --- testing: '123abc' ---
+
+Notice: A non well formed numeric value encountered in %s on line %d
 int(-123)
 --- testing: '123e5' ---
 float(-12300000)
 --- testing: '123e5xyz' ---
+
+Notice: A non well formed numeric value encountered in %s on line %d
 float(-12300000)
 --- testing: ' 123abc' ---
+
+Notice: A non well formed numeric value encountered in %s on line %d
 int(-123)
 --- testing: '123 abc' ---
+
+Notice: A non well formed numeric value encountered in %s on line %d
 int(-123)
 --- testing: '123abc ' ---
+
+Notice: A non well formed numeric value encountered in %s on line %d
 int(-123)
 --- testing: '3.4a' ---
+
+Notice: A non well formed numeric value encountered in %s on line %d
 float(-3.4)
 --- testing: 'a5.9' ---
+
+Warning: A non-numeric value encountered in %s on line %d
 int(0)\r
 ===DONE===\r