summaryrefslogtreecommitdiff
path: root/Zend/zend_operators.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2016-12-07 00:41:07 +0300
committerDmitry Stogov <dmitry@zend.com>2016-12-07 00:41:07 +0300
commite8109e09aaca9617806f41ae4d5b92460e077769 (patch)
tree56b10cff677d0b95a671101c18e4492ac17fb907 /Zend/zend_operators.c
parent6c614cb14cb8ee52106e5bbb1d680073d7b6de11 (diff)
downloadphp-git-e8109e09aaca9617806f41ae4d5b92460e077769.tar.gz
Fixed memory leaks caused by exceptions thrown from destructors.
Diffstat (limited to 'Zend/zend_operators.c')
-rw-r--r--Zend/zend_operators.c59
1 files changed, 55 insertions, 4 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 2d6df66a68..9f62db9aaa 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -217,6 +217,9 @@ ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */
ZVAL_COPY(&(holder), op); \
convert_to_long_base(&(holder), 10); \
if (UNEXPECTED(EG(exception))) { \
+ if (result != op1) { \
+ ZVAL_UNDEF(result); \
+ } \
return FAILURE; \
} \
if (Z_TYPE(holder) == IS_LONG) { \
@@ -252,7 +255,7 @@ ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */
/* }}} */
-#define convert_op1_op2_long(op1, op1_lval, op2, op2_lval, op, op_func) \
+#define convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, op, op_func) \
do { \
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) { \
if (Z_ISREF_P(op1)) { \
@@ -265,6 +268,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))) { \
+ if (result != op1) { \
+ ZVAL_UNDEF(result); \
+ } \
return FAILURE; \
} \
} else { \
@@ -283,6 +289,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))) { \
+ if (result != op1) { \
+ ZVAL_UNDEF(result); \
+ } \
return FAILURE; \
} \
} else { \
@@ -936,6 +945,9 @@ ZEND_API int ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2) /* {
zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
converted = 1;
} else {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
zend_throw_error(NULL, "Unsupported operand types");
return FAILURE; /* unknown datatype */
}
@@ -978,6 +990,9 @@ ZEND_API int ZEND_FASTCALL sub_function(zval *result, zval *op1, zval *op2) /* {
zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
converted = 1;
} else {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
zend_throw_error(NULL, "Unsupported operand types");
return FAILURE; /* unknown datatype */
}
@@ -1025,6 +1040,9 @@ ZEND_API int ZEND_FASTCALL mul_function(zval *result, zval *op1, zval *op2) /* {
zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
converted = 1;
} else {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
zend_throw_error(NULL, "Unsupported operand types");
return FAILURE; /* unknown datatype */
}
@@ -1113,6 +1131,9 @@ ZEND_API int ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *op2) /* {
}
converted = 1;
} else {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
zend_throw_error(NULL, "Unsupported operand types");
return FAILURE;
}
@@ -1178,6 +1199,9 @@ ZEND_API int ZEND_FASTCALL div_function(zval *result, zval *op1, zval *op2) /* {
zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
converted = 1;
} else {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
zend_throw_error(NULL, "Unsupported operand types");
return FAILURE; /* unknown datatype */
}
@@ -1190,7 +1214,7 @@ ZEND_API int ZEND_FASTCALL mod_function(zval *result, zval *op1, zval *op2) /* {
{
zend_long op1_lval, op2_lval;
- convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_MOD, mod_function);
+ convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, ZEND_MOD, mod_function);
if (op2_lval == 0) {
/* modulus by zero */
@@ -1330,6 +1354,9 @@ try_again:
default:
ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BW_NOT);
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
zend_throw_error(NULL, "Unsupported operand types");
return FAILURE;
}
@@ -1389,6 +1416,9 @@ ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_OR, bitwise_or_function);
op1_lval = _zval_get_long_func_noisy(op1);
if (UNEXPECTED(EG(exception))) {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
return FAILURE;
}
} else {
@@ -1398,6 +1428,9 @@ ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_OR);
op2_lval = _zval_get_long_func_noisy(op2);
if (UNEXPECTED(EG(exception))) {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
return FAILURE;
}
} else {
@@ -1465,6 +1498,9 @@ ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *o
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_AND, bitwise_and_function);
op1_lval = _zval_get_long_func_noisy(op1);
if (UNEXPECTED(EG(exception))) {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
return FAILURE;
}
} else {
@@ -1474,6 +1510,9 @@ ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *o
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_AND);
op2_lval = _zval_get_long_func_noisy(op2);
if (UNEXPECTED(EG(exception))) {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
return FAILURE;
}
} else {
@@ -1541,6 +1580,9 @@ ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *o
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_XOR, bitwise_xor_function);
op1_lval = _zval_get_long_func_noisy(op1);
if (UNEXPECTED(EG(exception))) {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
return FAILURE;
}
} else {
@@ -1550,6 +1592,9 @@ ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *o
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_XOR);
op2_lval = _zval_get_long_func_noisy(op2);
if (UNEXPECTED(EG(exception))) {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
return FAILURE;
}
} else {
@@ -1568,7 +1613,7 @@ ZEND_API int ZEND_FASTCALL shift_left_function(zval *result, zval *op1, zval *op
{
zend_long op1_lval, op2_lval;
- convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SL, shift_left_function);
+ convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, ZEND_SL, shift_left_function);
/* prevent wrapping quirkiness on some processors where << 64 + x == << x */
if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
@@ -1604,7 +1649,7 @@ ZEND_API int ZEND_FASTCALL shift_right_function(zval *result, zval *op1, zval *o
{
zend_long op1_lval, op2_lval;
- convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SR, shift_right_function);
+ convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, ZEND_SR, shift_right_function);
/* prevent wrapping quirkiness on some processors where >> 64 + x == >> x */
if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
@@ -1653,6 +1698,9 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
if (use_copy1) {
if (UNEXPECTED(EG(exception))) {
zval_dtor(&op1_copy);
+ if (orig_op1 != result) {
+ ZVAL_UNDEF(result);
+ }
return FAILURE;
}
if (result == op1) {
@@ -1678,6 +1726,9 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
zval_dtor(op1);
}
zval_dtor(&op2_copy);
+ if (orig_op1 != result) {
+ ZVAL_UNDEF(result);
+ }
return FAILURE;
}
op2 = &op2_copy;