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 when exception thrown during type converion).
This commit is contained in:
commit
7d86ed1852
2 changed files with 209 additions and 38 deletions
|
@ -20,7 +20,7 @@ try {
|
|||
$a <<= -1;
|
||||
} catch (Error $e) { var_dump($a); }
|
||||
|
||||
set_error_handler(function() { throw new Exception; });
|
||||
set_error_handler(function($type, $msg) { throw new Exception($msg); });
|
||||
|
||||
try {
|
||||
$a = [];
|
||||
|
@ -31,11 +31,154 @@ try {
|
|||
$a = "foo";
|
||||
$a .= [];
|
||||
} catch (Throwable $e) { var_dump($a); }
|
||||
|
||||
$x = new stdClass;
|
||||
try { $x += 1; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = 1;
|
||||
try { $x += new stdClass; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = new stdClass;
|
||||
try { $x -= 1; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = 1;
|
||||
try { $x -= new stdClass; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = new stdClass;
|
||||
try { $x *= 1; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = 1;
|
||||
try { $x *= new stdClass; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = new stdClass;
|
||||
try { $x /= 1; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = 1;
|
||||
try { $x /= new stdClass; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = new stdClass;
|
||||
try { $x %= 1; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = 1;
|
||||
try { $x %= new stdClass; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = new stdClass;
|
||||
try { $x **= 1; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = 1;
|
||||
try { $x **= new stdClass; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = new stdClass;
|
||||
try { $x ^= 1; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = 1;
|
||||
try { $x ^= new stdClass; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = new stdClass;
|
||||
try { $x &= 1; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = 1;
|
||||
try { $x &= new stdClass; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = new stdClass;
|
||||
try { $x |= 1; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = 1;
|
||||
try { $x |= new stdClass; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = new stdClass;
|
||||
try { $x <<= 1; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = 1;
|
||||
try { $x <<= new stdClass; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = new stdClass;
|
||||
try { $x >>= 1; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
|
||||
$x = 1;
|
||||
try { $x >>= new stdClass; }
|
||||
catch (Exception $e) {}
|
||||
var_dump($x);
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
int(1)
|
||||
int(1)
|
||||
int(1)
|
||||
array(0) {
|
||||
}
|
||||
string(3) "foo"
|
||||
object(stdClass)#%d (0) {
|
||||
}
|
||||
int(1)
|
||||
object(stdClass)#%d (0) {
|
||||
}
|
||||
int(1)
|
||||
object(stdClass)#%d (0) {
|
||||
}
|
||||
int(1)
|
||||
object(stdClass)#%d (0) {
|
||||
}
|
||||
int(1)
|
||||
object(stdClass)#%d (0) {
|
||||
}
|
||||
int(1)
|
||||
object(stdClass)#%d (0) {
|
||||
}
|
||||
int(1)
|
||||
object(stdClass)#%d (0) {
|
||||
}
|
||||
int(1)
|
||||
object(stdClass)#%d (0) {
|
||||
}
|
||||
int(1)
|
||||
object(stdClass)#%d (0) {
|
||||
}
|
||||
int(1)
|
||||
object(stdClass)#%d (0) {
|
||||
}
|
||||
int(1)
|
||||
object(stdClass)#%d (0) {
|
||||
}
|
||||
int(1)
|
||||
|
|
|
@ -186,44 +186,48 @@ ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */
|
|||
|
||||
/* {{{ zendi_convert_scalar_to_number */
|
||||
#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, silent); \
|
||||
} \
|
||||
} else { \
|
||||
switch (Z_TYPE_P(op)) { \
|
||||
case IS_STRING: \
|
||||
{ \
|
||||
if (Z_TYPE_P(op) != IS_LONG) { \
|
||||
if (op==result && Z_TYPE_P(op) != IS_OBJECT) { \
|
||||
_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), silent ? 1 : -1)) == 0) { \
|
||||
ZVAL_LONG(&(holder), 0); \
|
||||
if (!silent) { \
|
||||
ZVAL_LONG(&(holder), 0); \
|
||||
if (!silent) { \
|
||||
zend_error(E_WARNING, "A non-numeric value encountered"); \
|
||||
} \
|
||||
} \
|
||||
(op) = &(holder); \
|
||||
break; \
|
||||
} \
|
||||
case IS_NULL: \
|
||||
case IS_FALSE: \
|
||||
ZVAL_LONG(&(holder), 0); \
|
||||
(op) = &(holder); \
|
||||
break; \
|
||||
case IS_TRUE: \
|
||||
ZVAL_LONG(&(holder), 1); \
|
||||
(op) = &(holder); \
|
||||
break; \
|
||||
case IS_RESOURCE: \
|
||||
ZVAL_LONG(&(holder), Z_RES_HANDLE_P(op)); \
|
||||
(op) = &(holder); \
|
||||
break; \
|
||||
case IS_OBJECT: \
|
||||
ZVAL_COPY(&(holder), op); \
|
||||
convert_to_long_base(&(holder), 10); \
|
||||
if (Z_TYPE(holder) == IS_LONG) { \
|
||||
(op) = &(holder); \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
(op) = &(holder); \
|
||||
break; \
|
||||
case IS_NULL: \
|
||||
case IS_FALSE: \
|
||||
ZVAL_LONG(&(holder), 0); \
|
||||
(op) = &(holder); \
|
||||
break; \
|
||||
case IS_TRUE: \
|
||||
ZVAL_LONG(&(holder), 1); \
|
||||
(op) = &(holder); \
|
||||
break; \
|
||||
case IS_RESOURCE: \
|
||||
ZVAL_LONG(&(holder), Z_RES_HANDLE_P(op)); \
|
||||
(op) = &(holder); \
|
||||
break; \
|
||||
case IS_OBJECT: \
|
||||
ZVAL_COPY(&(holder), op); \
|
||||
convert_to_long_base(&(holder), 10); \
|
||||
if (UNEXPECTED(EG(exception))) { \
|
||||
return FAILURE; \
|
||||
} \
|
||||
if (Z_TYPE(holder) == IS_LONG) { \
|
||||
if (op == result) { \
|
||||
zval_ptr_dtor(op); \
|
||||
} \
|
||||
(op) = &(holder); \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
@ -260,6 +264,9 @@ ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */
|
|||
} \
|
||||
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(op, op_func); \
|
||||
op1_lval = _zval_get_long_func_noisy(op1); \
|
||||
if (UNEXPECTED(EG(exception))) { \
|
||||
return FAILURE; \
|
||||
} \
|
||||
} else { \
|
||||
op1_lval = Z_LVAL_P(op1); \
|
||||
} \
|
||||
|
@ -275,6 +282,9 @@ ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */
|
|||
} \
|
||||
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(op); \
|
||||
op2_lval = _zval_get_long_func_noisy(op2); \
|
||||
if (UNEXPECTED(EG(exception))) { \
|
||||
return FAILURE; \
|
||||
} \
|
||||
} else { \
|
||||
op2_lval = Z_LVAL_P(op2); \
|
||||
} \
|
||||
|
@ -1378,12 +1388,18 @@ 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_noisy(op1);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
return FAILURE;
|
||||
}
|
||||
} 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_noisy(op2);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
return FAILURE;
|
||||
}
|
||||
} else {
|
||||
op2_lval = Z_LVAL_P(op2);
|
||||
}
|
||||
|
@ -1448,12 +1464,18 @@ 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_noisy(op1);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
return FAILURE;
|
||||
}
|
||||
} 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_noisy(op2);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
return FAILURE;
|
||||
}
|
||||
} else {
|
||||
op2_lval = Z_LVAL_P(op2);
|
||||
}
|
||||
|
@ -1518,12 +1540,18 @@ 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_noisy(op1);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
return FAILURE;
|
||||
}
|
||||
} 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_noisy(op2);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
return FAILURE;
|
||||
}
|
||||
} else {
|
||||
op2_lval = Z_LVAL_P(op2);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue