diff options
39 files changed, 816 insertions, 103 deletions
@@ -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). @@ -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 diff --git a/Zend/tests/add_006.phpt b/Zend/tests/add_006.phpt index d56df2f329..fe1c0830e2 100644 --- a/Zend/tests/add_006.phpt +++ b/Zend/tests/add_006.phpt @@ -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) diff --git a/Zend/tests/add_007.phpt b/Zend/tests/add_007.phpt index 66f5405706..089b24ae0b 100644 --- a/Zend/tests/add_007.phpt +++ b/Zend/tests/add_007.phpt @@ -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} diff --git a/Zend/tests/constant_expressions_dynamic.phpt b/Zend/tests/constant_expressions_dynamic.phpt index d4e06ee258..b0ba3a5b19 100644 --- a/Zend/tests/constant_expressions_dynamic.phpt +++ b/Zend/tests/constant_expressions_dynamic.phpt @@ -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 index 0000000000..d924cb7b81 --- /dev/null +++ b/Zend/tests/int_conversion_exponents.phpt @@ -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 index 0000000000..26ceea7dee --- /dev/null +++ b/Zend/tests/numeric_string_errors.phpt @@ -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 index 0000000000..7fb8898fc9 --- /dev/null +++ b/Zend/tests/numeric_string_errors_assign.phpt @@ -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) diff --git a/Zend/tests/self_and.phpt b/Zend/tests/self_and.phpt index cdcde77992..44db877e92 100644 --- a/Zend/tests/self_and.phpt +++ b/Zend/tests/self_and.phpt @@ -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 diff --git a/Zend/tests/self_mod.phpt b/Zend/tests/self_mod.phpt index 19e45d88fc..0b10987aeb 100644 --- a/Zend/tests/self_mod.phpt +++ b/Zend/tests/self_mod.phpt @@ -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 diff --git a/Zend/tests/self_or.phpt b/Zend/tests/self_or.phpt index ae667bff16..8ace518bde 100644 --- a/Zend/tests/self_or.phpt +++ b/Zend/tests/self_or.phpt @@ -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 diff --git a/Zend/tests/self_xor.phpt b/Zend/tests/self_xor.phpt index a7e43f539d..c097930d6d 100644 --- a/Zend/tests/self_xor.phpt +++ b/Zend/tests/self_xor.phpt @@ -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 diff --git a/Zend/tests/shift_001.phpt b/Zend/tests/shift_001.phpt index aeb399452d..7546f1a6d8 100644 --- a/Zend/tests/shift_001.phpt +++ b/Zend/tests/shift_001.phpt @@ -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 diff --git a/Zend/tests/shift_002.phpt b/Zend/tests/shift_002.phpt index 4d8421a566..6288152585 100644 --- a/Zend/tests/shift_002.phpt +++ b/Zend/tests/shift_002.phpt @@ -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 diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 5ebfe2cb17..18e6e0f4f4 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -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; } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2e1ce9ba44..1401a6e051 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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: { diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index f3dc8081b8..b3ba352df8 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -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 */ /* diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 50557e56d8..1710ba44dd 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -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) { diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index b0b167bd74..db6162a4e5 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -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') diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 52a440fba0..0ecb57e2b9 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -685,7 +685,12 @@ optimize_constant_binary_op: 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) { diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index ae31504f4c..71f879e958 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -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; diff --git a/ext/opcache/Optimizer/pass2.c b/ext/opcache/Optimizer/pass2.c index d2a2064a78..2be97ed938 100644 --- a/ext/opcache/Optimizer/pass2.c +++ b/ext/opcache/Optimizer/pass2.c @@ -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; diff --git a/ext/standard/tests/file/file_put_contents_variation7.phpt b/ext/standard/tests/file/file_put_contents_variation7.phpt index 5c8e5f3602..b1b2face60 100644 --- a/ext/standard/tests/file/file_put_contents_variation7.phpt +++ b/ext/standard/tests/file/file_put_contents_variation7.phpt @@ -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 *** diff --git a/ext/standard/tests/general_functions/floatval.phpt b/ext/standard/tests/general_functions/floatval.phpt index 9b7a3281e4..d7bdffd6ae 100644 --- a/ext/standard/tests/general_functions/floatval.phpt +++ b/ext/standard/tests/general_functions/floatval.phpt @@ -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) diff --git a/ext/standard/tests/general_functions/floatval_variation1.phpt b/ext/standard/tests/general_functions/floatval_variation1.phpt index 83925b89b0..aa808cfba1 100644 --- a/ext/standard/tests/general_functions/floatval_variation1.phpt +++ b/ext/standard/tests/general_functions/floatval_variation1.phpt @@ -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=== diff --git a/ext/standard/tests/general_functions/gettype_settype_variation2.phpt b/ext/standard/tests/general_functions/gettype_settype_variation2.phpt index 2242952769..18b05b6a97 100644 --- a/ext/standard/tests/general_functions/gettype_settype_variation2.phpt +++ b/ext/standard/tests/general_functions/gettype_settype_variation2.phpt @@ -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" diff --git a/ext/standard/tests/math/decbin_basic.phpt b/ext/standard/tests/math/decbin_basic.phpt index b4389956f4..572a04245e 100644 --- a/ext/standard/tests/math/decbin_basic.phpt +++ b/ext/standard/tests/math/decbin_basic.phpt @@ -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" diff --git a/ext/standard/tests/math/dechex_basic.phpt b/ext/standard/tests/math/dechex_basic.phpt index 2423d8e748..ac53a97b34 100644 --- a/ext/standard/tests/math/dechex_basic.phpt +++ b/ext/standard/tests/math/dechex_basic.phpt @@ -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" diff --git a/ext/standard/tests/math/decoct_basic.phpt b/ext/standard/tests/math/decoct_basic.phpt index cc1f0a899a..3a5011b973 100644 --- a/ext/standard/tests/math/decoct_basic.phpt +++ b/ext/standard/tests/math/decoct_basic.phpt @@ -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" diff --git a/ext/standard/tests/math/pow_variation1.phpt b/ext/standard/tests/math/pow_variation1.phpt index 5576e5b493..c744c4eb9d 100644 --- a/ext/standard/tests/math/pow_variation1.phpt +++ b/ext/standard/tests/math/pow_variation1.phpt @@ -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 -- diff --git a/ext/standard/tests/math/pow_variation1_64bit.phpt b/ext/standard/tests/math/pow_variation1_64bit.phpt index e1986ba858..ea2ae45d18 100644 --- a/ext/standard/tests/math/pow_variation1_64bit.phpt +++ b/ext/standard/tests/math/pow_variation1_64bit.phpt @@ -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 -- diff --git a/ext/standard/tests/math/pow_variation2.phpt b/ext/standard/tests/math/pow_variation2.phpt index f571936727..36b085b647 100644 --- a/ext/standard/tests/math/pow_variation2.phpt +++ b/ext/standard/tests/math/pow_variation2.phpt @@ -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 -- diff --git a/ext/standard/tests/strings/bug55871.phpt b/ext/standard/tests/strings/bug55871.phpt index 249d1bd3a3..0044f50ce7 100644 --- a/ext/standard/tests/strings/bug55871.phpt +++ b/ext/standard/tests/strings/bug55871.phpt @@ -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" diff --git a/ext/standard/type.c b/ext/standard/type.c index d6a412f4ec..529d666d02 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -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)); diff --git a/tests/lang/bug28800.phpt b/tests/lang/bug28800.phpt index f81ad7fec9..8bd2c306e1 100644 --- a/tests/lang/bug28800.phpt +++ b/tests/lang/bug28800.phpt @@ -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 diff --git a/tests/lang/operators/bitwiseShiftLeft_variationStr_64bit.phpt b/tests/lang/operators/bitwiseShiftLeft_variationStr_64bit.phpt index d5888d837f..69fd90f1c8 100644 --- a/tests/lang/operators/bitwiseShiftLeft_variationStr_64bit.phpt +++ b/tests/lang/operators/bitwiseShiftLeft_variationStr_64bit.phpt @@ -226,17 +226,17 @@ int(984) --- 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(246)
+int(24600000)
--- 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' ---
@@ -250,21 +250,21 @@ int(0) --- testing: '123e5' << '123abc ' ---
int(0)
--- testing: '123e5' << '3.4a' ---
-int(984)
+int(98400000)
--- 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(246)
+int(24600000)
--- 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' ---
@@ -278,9 +278,9 @@ int(0) --- testing: '123e5xyz' << '123abc ' ---
int(0)
--- testing: '123e5xyz' << '3.4a' ---
-int(984)
+int(98400000)
--- testing: '123e5xyz' << 'a5.9' ---
-int(123)
+int(12300000)
--- testing: ' 123abc' << '0' ---
int(123)
--- testing: ' 123abc' << '65' ---
diff --git a/tests/lang/operators/bitwiseShiftRight_variationStr.phpt b/tests/lang/operators/bitwiseShiftRight_variationStr.phpt index a86d0cfddb..a4c425aab3 100644 --- a/tests/lang/operators/bitwiseShiftRight_variationStr.phpt +++ b/tests/lang/operators/bitwiseShiftRight_variationStr.phpt @@ -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' --- diff --git a/tests/lang/operators/modulus_variationStr.phpt b/tests/lang/operators/modulus_variationStr.phpt index c647ecd380..4cfd7768ff 100644 --- a/tests/lang/operators/modulus_variationStr.phpt +++ b/tests/lang/operators/modulus_variationStr.phpt @@ -208,9 +208,9 @@ Exception: Modulo by zero --- testing: '123abc' % '123abc' ---
int(0)
--- testing: '123abc' % '123e5' ---
-int(0)
+int(123)
--- testing: '123abc' % '123e5xyz' ---
-int(0)
+int(123)
--- testing: '123abc' % ' 123abc' ---
int(0)
--- testing: '123abc' % '123 abc' ---
@@ -224,13 +224,13 @@ Exception: Modulo by zero --- testing: '123e5' % '0' ---
Exception: Modulo by zero
--- testing: '123e5' % '65' ---
-int(58)
+int(50)
--- testing: '123e5' % '-44' ---
-int(35)
+int(20)
--- testing: '123e5' % '1.2' ---
int(0)
--- testing: '123e5' % '-7.7' ---
-int(4)
+int(6)
--- testing: '123e5' % 'abc' ---
Exception: Modulo by zero
--- testing: '123e5' % '123abc' ---
@@ -252,13 +252,13 @@ Exception: Modulo by zero --- testing: '123e5xyz' % '0' ---
Exception: Modulo by zero
--- testing: '123e5xyz' % '65' ---
-int(58)
+int(50)
--- testing: '123e5xyz' % '-44' ---
-int(35)
+int(20)
--- testing: '123e5xyz' % '1.2' ---
int(0)
--- testing: '123e5xyz' % '-7.7' ---
-int(4)
+int(6)
--- testing: '123e5xyz' % 'abc' ---
Exception: Modulo by zero
--- testing: '123e5xyz' % '123abc' ---
@@ -292,9 +292,9 @@ Exception: Modulo by zero --- testing: ' 123abc' % '123abc' ---
int(0)
--- testing: ' 123abc' % '123e5' ---
-int(0)
+int(123)
--- testing: ' 123abc' % '123e5xyz' ---
-int(0)
+int(123)
--- testing: ' 123abc' % ' 123abc' ---
int(0)
--- testing: ' 123abc' % '123 abc' ---
@@ -320,9 +320,9 @@ Exception: Modulo by zero --- testing: '123 abc' % '123abc' ---
int(0)
--- testing: '123 abc' % '123e5' ---
-int(0)
+int(123)
--- testing: '123 abc' % '123e5xyz' ---
-int(0)
+int(123)
--- testing: '123 abc' % ' 123abc' ---
int(0)
--- testing: '123 abc' % '123 abc' ---
@@ -348,9 +348,9 @@ Exception: Modulo by zero --- testing: '123abc ' % '123abc' ---
int(0)
--- testing: '123abc ' % '123e5' ---
-int(0)
+int(123)
--- testing: '123abc ' % '123e5xyz' ---
-int(0)
+int(123)
--- testing: '123abc ' % ' 123abc' ---
int(0)
--- testing: '123abc ' % '123 abc' ---
diff --git a/tests/lang/operators/negate_variationStr.phpt b/tests/lang/operators/negate_variationStr.phpt index a25bdda7f5..7405d42882 100644 --- a/tests/lang/operators/negate_variationStr.phpt +++ b/tests/lang/operators/negate_variationStr.phpt @@ -16,7 +16,7 @@ foreach ($strVals as $strVal) { ?>
===DONE===
---EXPECT--
+--EXPECTF--
--- 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)
===DONE===
|