summaryrefslogtreecommitdiff
path: root/Zend/zend_operators.c
diff options
context:
space:
mode:
authorZeev Suraski <zeev@php.net>1999-07-26 21:56:45 +0000
committerZeev Suraski <zeev@php.net>1999-07-26 21:56:45 +0000
commit09628fd51e56a9156ba3041b452bb8293bf2e936 (patch)
tree4d0d254ded643d30166ec0bd25ee868e27ff2706 /Zend/zend_operators.c
parent4215a176397445bed390c373c1c73293f2cf42b2 (diff)
downloadphp-git-09628fd51e56a9156ba3041b452bb8293bf2e936.tar.gz
- Fixed a memory leak when using assignment-op operators with lvalue of type
string (or array/object)
Diffstat (limited to 'Zend/zend_operators.c')
-rw-r--r--Zend/zend_operators.c83
1 files changed, 45 insertions, 38 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index a8bd01892e..743b8a6fa0 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -64,8 +64,10 @@ ZEND_API void convert_scalar_to_number(zval *op)
}
}
-#define zendi_convert_scalar_to_number(op, holder) \
- if ((op)->type == IS_STRING) { \
+#define zendi_convert_scalar_to_number(op, holder, result) \
+ if (op==result) { \
+ convert_scalar_to_number(op); \
+ } else if ((op)->type == IS_STRING) { \
switch (((holder).type=is_numeric_string((op)->value.str.val, (op)->value.str.len, &(holder).value.lval, &(holder).value.dval))) { \
case IS_DOUBLE: \
case IS_LONG: \
@@ -86,8 +88,10 @@ ZEND_API void convert_scalar_to_number(zval *op)
}
-#define zendi_convert_to_long(op, holder) \
- if ((op)->type != IS_LONG) { \
+#define zendi_convert_to_long(op, holder, result) \
+ if (op==result) { \
+ convert_to_long(op); \
+ } else if ((op)->type != IS_LONG) { \
switch ((op)->type) { \
case IS_BOOL: \
case IS_RESOURCE: \
@@ -114,8 +118,10 @@ ZEND_API void convert_scalar_to_number(zval *op)
}
-#define zendi_convert_to_boolean(op, holder) \
- if ((op)->type != IS_BOOL) { \
+#define zendi_convert_to_boolean(op, holder, result) \
+ if (op==result) { \
+ convert_to_boolean(op); \
+ } else if ((op)->type != IS_BOOL) { \
switch ((op)->type) { \
case IS_LONG: \
case IS_RESOURCE: \
@@ -404,8 +410,9 @@ ZEND_API int add_function(zval *result, zval *op1, zval *op2)
zend_hash_merge(result->value.ht, op2->value.ht, (void (*)(void *pData)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0);
return SUCCESS;
}
- zendi_convert_scalar_to_number(op1, op1_copy);
- zendi_convert_scalar_to_number(op2, op2_copy);
+ zendi_convert_scalar_to_number(op1, op1_copy, result);
+ zendi_convert_scalar_to_number(op2, op2_copy, result);
+
if (op1->type == IS_LONG && op2->type == IS_LONG) {
double dval = (double) op1->value.lval + (double) op2->value.lval;
@@ -441,8 +448,8 @@ ZEND_API int sub_function(zval *result, zval *op1, zval *op2)
{
zval op1_copy, op2_copy;
- zendi_convert_scalar_to_number(op1, op1_copy);
- zendi_convert_scalar_to_number(op2, op2_copy);
+ zendi_convert_scalar_to_number(op1, op1_copy, result);
+ zendi_convert_scalar_to_number(op2, op2_copy, result);
if (op1->type == IS_LONG && op2->type == IS_LONG) {
double dval = (double) op1->value.lval - (double) op2->value.lval;
@@ -478,8 +485,8 @@ ZEND_API int mul_function(zval *result, zval *op1, zval *op2)
{
zval op1_copy, op2_copy;
- zendi_convert_scalar_to_number(op1, op1_copy);
- zendi_convert_scalar_to_number(op2, op2_copy);
+ zendi_convert_scalar_to_number(op1, op1_copy, result);
+ zendi_convert_scalar_to_number(op2, op2_copy, result);
if (op1->type == IS_LONG && op2->type == IS_LONG) {
double dval = (double) op1->value.lval * (double) op2->value.lval;
@@ -514,8 +521,8 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2)
{
zval op1_copy, op2_copy;
- zendi_convert_scalar_to_number(op1, op1_copy);
- zendi_convert_scalar_to_number(op2, op2_copy);
+ zendi_convert_scalar_to_number(op1, op1_copy, result);
+ zendi_convert_scalar_to_number(op2, op2_copy, result);
if ((op2->type == IS_LONG && op2->value.lval == 0) || (op2->type == IS_DOUBLE && op2->value.dval == 0.0)) {
zend_error(E_WARNING, "Division by zero");
@@ -554,8 +561,8 @@ ZEND_API int mod_function(zval *result, zval *op1, zval *op2)
{
zval op1_copy, op2_copy;
- zendi_convert_to_long(op1, op1_copy);
- zendi_convert_to_long(op2, op2_copy);
+ zendi_convert_to_long(op1, op1_copy, result);
+ zendi_convert_to_long(op2, op2_copy, result);
if (op2->value.lval == 0) {
var_reset(result);
@@ -574,12 +581,12 @@ ZEND_API int boolean_or_function(zval *result, zval *op1, zval *op2)
result->type = IS_BOOL;
- zendi_convert_to_boolean(op1, op1_copy);
+ zendi_convert_to_boolean(op1, op1_copy, result);
if (op1->value.lval) {
result->value.lval = 1;
return SUCCESS;
}
- zendi_convert_to_boolean(op2, op2_copy);
+ zendi_convert_to_boolean(op2, op2_copy, result);
if (op2->value.lval) {
result->value.lval = 1;
return SUCCESS;
@@ -595,12 +602,12 @@ ZEND_API int boolean_and_function(zval *result, zval *op1, zval *op2)
result->type = IS_BOOL;
- zendi_convert_to_boolean(op1, op1_copy);
+ zendi_convert_to_boolean(op1, op1_copy, result);
if (!op1->value.lval) {
result->value.lval = 0;
return SUCCESS;
}
- zendi_convert_to_boolean(op2, op2_copy);
+ zendi_convert_to_boolean(op2, op2_copy, result);
if (!op2->value.lval) {
result->value.lval = 0;
return SUCCESS;
@@ -616,8 +623,8 @@ ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2)
result->type = IS_BOOL;
- zendi_convert_to_boolean(op1, op1_copy);
- zendi_convert_to_boolean(op2, op2_copy);
+ zendi_convert_to_boolean(op1, op1_copy, result);
+ zendi_convert_to_boolean(op2, op2_copy, result);
result->value.lval = op1->value.lval ^ op2->value.lval;
return SUCCESS;
}
@@ -627,7 +634,7 @@ ZEND_API int boolean_not_function(zval *result, zval *op1)
{
zval op1_copy;
- zendi_convert_to_boolean(op1, op1_copy);
+ zendi_convert_to_boolean(op1, op1_copy, result);
result->type = IS_BOOL;
result->value.lval = !op1->value.lval;
@@ -689,8 +696,8 @@ ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2)
}
return SUCCESS;
}
- zendi_convert_to_long(op1, op1_copy);
- zendi_convert_to_long(op2, op2_copy);
+ zendi_convert_to_long(op1, op1_copy, result);
+ zendi_convert_to_long(op2, op2_copy, result);
result->type = IS_LONG;
result->value.lval = op1->value.lval | op2->value.lval;
@@ -723,8 +730,8 @@ ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2)
}
- zendi_convert_to_long(op1, op1_copy);
- zendi_convert_to_long(op2, op2_copy);
+ zendi_convert_to_long(op1, op1_copy, result);
+ zendi_convert_to_long(op2, op2_copy, result);
result->type = IS_LONG;
result->value.lval = op1->value.lval & op2->value.lval;
@@ -756,8 +763,8 @@ ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2)
return SUCCESS;
}
- zendi_convert_to_long(op1, op1_copy);
- zendi_convert_to_long(op2, op2_copy);
+ zendi_convert_to_long(op1, op1_copy, result);
+ zendi_convert_to_long(op2, op2_copy, result);
result->type = IS_LONG;
result->value.lval = op1->value.lval ^ op2->value.lval;
@@ -769,8 +776,8 @@ ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2)
{
zval op1_copy, op2_copy;
- zendi_convert_to_long(op1, op1_copy);
- zendi_convert_to_long(op2, op2_copy);
+ zendi_convert_to_long(op1, op1_copy, result);
+ zendi_convert_to_long(op2, op2_copy, result);
result->value.lval = op1->value.lval << op2->value.lval;
result->type = IS_LONG;
return SUCCESS;
@@ -781,8 +788,8 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2)
{
zval op1_copy, op2_copy;
- zendi_convert_to_long(op1, op1_copy);
- zendi_convert_to_long(op2, op2_copy);
+ zendi_convert_to_long(op1, op1_copy, result);
+ zendi_convert_to_long(op2, op2_copy, result);
result->value.lval = op1->value.lval >> op2->value.lval;
result->type = IS_LONG;
return SUCCESS;
@@ -865,19 +872,19 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2)
zval op1_copy, op2_copy;
if (op1->type == IS_STRING && op2->type == IS_STRING) {
- zendi_smart_strcmp(result,op1,op2);
+ zendi_smart_strcmp(result, op1, op2);
return SUCCESS;
}
if (op1->type == IS_BOOL || op2->type == IS_BOOL) {
- zendi_convert_to_boolean(op1, op1_copy);
- zendi_convert_to_boolean(op2, op2_copy);
+ zendi_convert_to_boolean(op1, op1_copy, result);
+ zendi_convert_to_boolean(op2, op2_copy, result);
result->type = IS_LONG;
result->value.lval = op1->value.lval - op2->value.lval;
return SUCCESS;
}
- zendi_convert_scalar_to_number(op1, op1_copy);
- zendi_convert_scalar_to_number(op2, op2_copy);
+ zendi_convert_scalar_to_number(op1, op1_copy, result);
+ zendi_convert_scalar_to_number(op2, op2_copy, result);
if (op1->type == IS_LONG && op2->type == IS_LONG) {
result->type = IS_LONG;