mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-7.1'
* PHP-7.1: Fixed behavior of failing compound assignments (they shouldn't change the source value).
This commit is contained in:
commit
0314958a43
2 changed files with 64 additions and 20 deletions
24
Zend/tests/compound_assign_failure.phpt
Normal file
24
Zend/tests/compound_assign_failure.phpt
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
Behavior of failing compound assignment
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
try {
|
||||
$a = 1;
|
||||
$a %= 0;
|
||||
} catch (Error $e) { var_dump($a); }
|
||||
|
||||
try {
|
||||
$a = 1;
|
||||
$a >>= -1;
|
||||
} catch (Error $e) { var_dump($a); }
|
||||
|
||||
try {
|
||||
$a = 1;
|
||||
$a <<= -1;
|
||||
} catch (Error $e) { var_dump($a); }
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(1)
|
||||
int(1)
|
|
@ -1182,10 +1182,6 @@ ZEND_API int ZEND_FASTCALL mod_function(zval *result, zval *op1, zval *op2) /* {
|
|||
|
||||
convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_MOD, mod_function);
|
||||
|
||||
if (op1 == result) {
|
||||
zval_dtor(result);
|
||||
}
|
||||
|
||||
if (op2_lval == 0) {
|
||||
/* modulus by zero */
|
||||
if (EG(current_execute_data) && !CG(in_compilation)) {
|
||||
|
@ -1193,10 +1189,16 @@ ZEND_API int ZEND_FASTCALL mod_function(zval *result, zval *op1, zval *op2) /* {
|
|||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Modulo by zero");
|
||||
}
|
||||
ZVAL_UNDEF(result);
|
||||
if (op1 != result) {
|
||||
ZVAL_UNDEF(result);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (op1 == result) {
|
||||
zval_dtor(result);
|
||||
}
|
||||
|
||||
if (op2_lval == -1) {
|
||||
/* Prevent overflow error/crash if op1==LONG_MIN */
|
||||
ZVAL_LONG(result, 0);
|
||||
|
@ -1540,13 +1542,12 @@ ZEND_API int ZEND_FASTCALL shift_left_function(zval *result, zval *op1, zval *op
|
|||
|
||||
convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SL, shift_left_function);
|
||||
|
||||
if (op1 == result) {
|
||||
zval_dtor(result);
|
||||
}
|
||||
|
||||
/* prevent wrapping quirkiness on some processors where << 64 + x == << x */
|
||||
if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
|
||||
if (EXPECTED(op2_lval > 0)) {
|
||||
if (op1 == result) {
|
||||
zval_dtor(result);
|
||||
}
|
||||
ZVAL_LONG(result, 0);
|
||||
return SUCCESS;
|
||||
} else {
|
||||
|
@ -1555,11 +1556,17 @@ ZEND_API int ZEND_FASTCALL shift_left_function(zval *result, zval *op1, zval *op
|
|||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Bit shift by negative number");
|
||||
}
|
||||
ZVAL_UNDEF(result);
|
||||
if (op1 != result) {
|
||||
ZVAL_UNDEF(result);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (op1 == result) {
|
||||
zval_dtor(result);
|
||||
}
|
||||
|
||||
ZVAL_LONG(result, op1_lval << op2_lval);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -1571,14 +1578,13 @@ ZEND_API int ZEND_FASTCALL shift_right_function(zval *result, zval *op1, zval *o
|
|||
|
||||
convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SR, shift_right_function);
|
||||
|
||||
if (op1 == result) {
|
||||
zval_dtor(result);
|
||||
}
|
||||
|
||||
/* prevent wrapping quirkiness on some processors where >> 64 + x == >> x */
|
||||
if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
|
||||
if (EXPECTED(op2_lval > 0)) {
|
||||
ZVAL_LONG(result, (op1_lval < 0) ? -1 : 0);
|
||||
if (op1 == result) {
|
||||
zval_dtor(result);
|
||||
}
|
||||
return SUCCESS;
|
||||
} else {
|
||||
if (EG(current_execute_data) && !CG(in_compilation)) {
|
||||
|
@ -1586,11 +1592,17 @@ ZEND_API int ZEND_FASTCALL shift_right_function(zval *result, zval *op1, zval *o
|
|||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Bit shift by negative number");
|
||||
}
|
||||
ZVAL_UNDEF(result);
|
||||
if (op1 != result) {
|
||||
ZVAL_UNDEF(result);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (op1 == result) {
|
||||
zval_dtor(result);
|
||||
}
|
||||
|
||||
ZVAL_LONG(result, op1_lval >> op2_lval);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -1598,6 +1610,7 @@ ZEND_API int ZEND_FASTCALL shift_right_function(zval *result, zval *op1, zval *o
|
|||
|
||||
ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /* {{{ */
|
||||
{
|
||||
zval *orig_op1 = op1;
|
||||
zval op1_copy, op2_copy;
|
||||
int use_copy1 = 0, use_copy2 = 0;
|
||||
|
||||
|
@ -1610,11 +1623,7 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
|
|||
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT, concat_function);
|
||||
use_copy1 = zend_make_printable_zval(op1, &op1_copy);
|
||||
if (use_copy1) {
|
||||
/* We have created a converted copy of op1. Therefore, op1 won't become the result so
|
||||
* we have to free it.
|
||||
*/
|
||||
if (result == op1) {
|
||||
zval_dtor(op1);
|
||||
if (UNEXPECTED(op1 == op2)) {
|
||||
op2 = &op1_copy;
|
||||
}
|
||||
|
@ -1645,7 +1654,15 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
|
|||
|
||||
if (UNEXPECTED(op1_len > SIZE_MAX - op2_len)) {
|
||||
zend_throw_error(NULL, "String size overflow");
|
||||
ZVAL_FALSE(result);
|
||||
if (UNEXPECTED(use_copy1)) {
|
||||
zval_dtor(op1);
|
||||
}
|
||||
if (UNEXPECTED(use_copy2)) {
|
||||
zval_dtor(op2);
|
||||
}
|
||||
if (orig_op1 != result) {
|
||||
ZVAL_UNDEF(result);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
|
@ -1655,6 +1672,9 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
|
|||
} else {
|
||||
result_str = zend_string_alloc(result_len, 0);
|
||||
memcpy(ZSTR_VAL(result_str), Z_STRVAL_P(op1), op1_len);
|
||||
if (result == orig_op1) {
|
||||
zval_dtor(orig_op1);
|
||||
}
|
||||
}
|
||||
|
||||
/* This has to happen first to account for the cases where result == op1 == op2 and
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue