This commit is contained in:
Dmitry Stogov 2014-06-03 00:36:31 +04:00
parent 717b5661e7
commit 0427ae08fb
9 changed files with 253 additions and 229 deletions

View file

@ -249,14 +249,12 @@ again:
TSRMLS_FETCH();
if (Z_OBJ_HANDLER_P(expr, cast_object)) {
zval val;
ZVAL_DUP_DEREF(&val, expr);
if (Z_OBJ_HANDLER_P(expr, cast_object)(&val, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
zval_ptr_dtor(&val);
Z_ADDREF_P(expr);
if (Z_OBJ_HANDLER_P(expr, cast_object)(expr, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
zval_ptr_dtor(expr);
break;
}
zval_ptr_dtor(&val);
zval_ptr_dtor(expr);
}
if (!Z_OBJ_HANDLER_P(expr, cast_object) && Z_OBJ_HANDLER_P(expr, get)) {
zval rv;

View file

@ -707,15 +707,6 @@ END_EXTERN_C()
} \
} while (0)
#define ZVAL_DUP_DEREF(z, v) \
do { \
zval *__z1 = (z); \
zval *__z2 = (v); \
ZVAL_DEREF(__z2); \
ZVAL_COPY_VALUE(__z1, __z2); \
zval_opt_copy_ctor(__z1); \
} while (0)
#define ZVAL_UNREF(z) do { \
zval *_z = (z); \
zend_reference *ref; \

View file

@ -927,15 +927,19 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
}
/* copy: enforce read only access */
ZVAL_DUP_DEREF(&prop_copy, prop);
ZVAL_DEREF(prop);
if (UNEXPECTED(Z_COPYABLE_P(prop))) {
ZVAL_DUP(&prop_copy, prop);
prop = &prop_copy;
}
/* this is necessary to make it able to work with default array
* properties, returned to user */
if (Z_OPT_CONSTANT(prop_copy)) {
zval_update_constant(&prop_copy, 0 TSRMLS_CC);
if (Z_OPT_CONSTANT_P(prop)) {
zval_update_constant(prop, 0 TSRMLS_CC);
}
zend_hash_add_new(Z_ARRVAL_P(return_value), key, &prop_copy);
zend_hash_add_new(Z_ARRVAL_P(return_value), key, prop);
} ZEND_HASH_FOREACH_END();
}
/* }}} */
@ -1904,7 +1908,7 @@ ZEND_FUNCTION(get_defined_constants)
if (categorize) {
zend_constant *val;
int module_number;
zval *modules;
zval *modules, tmp, *const_val;
char **module_names;
zend_module_entry *module;
int i = 1;
@ -1920,8 +1924,6 @@ ZEND_FUNCTION(get_defined_constants)
module_names[i] = "user";
ZEND_HASH_FOREACH_PTR(EG(zend_constants), val) {
zval const_val;
if (!val->name) {
/* skip special constants */
continue;
@ -1941,9 +1943,14 @@ ZEND_FUNCTION(get_defined_constants)
add_assoc_zval(return_value, module_names[module_number], &modules[module_number]);
}
ZVAL_DUP_DEREF(&const_val, &val->value);
if (EXPECTED(!Z_COPYABLE(val->value))) {
const_val = &val->value;
} else {
ZVAL_DUP(&tmp, &val->value);
const_val = &tmp;
}
zend_hash_add_new(Z_ARRVAL(modules[module_number]), val->name, &const_val);
zend_hash_add_new(Z_ARRVAL(modules[module_number]), val->name, const_val);
} ZEND_HASH_FOREACH_END();
efree(module_names);

View file

@ -270,7 +270,11 @@ static void _default_exception_get_entry(zval *object, char *name, int name_len,
value = zend_read_property(default_exception_ce, object, name, name_len, 0 TSRMLS_CC);
ZVAL_DUP_DEREF(return_value, value);
if (UNEXPECTED(Z_ISREF_P(return_value))) {
ZVAL_DUP(return_value, Z_REFVAL_P(value));
} else {
ZVAL_COPY(return_value, value);
}
}
/* }}} */

View file

@ -1648,15 +1648,12 @@ ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 T
ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
{
zval op1_copy, op2_copy;
double d1, d2;
ZVAL_DUP_DEREF(&op1_copy, op1);
ZVAL_DUP_DEREF(&op2_copy, op2);
d1 = zval_get_double(op1);
d2 = zval_get_double(op2);
convert_to_double(&op1_copy);
convert_to_double(&op2_copy);
ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL(op1_copy)-Z_DVAL(op2_copy)));
ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(d1 - d2));
return SUCCESS;
}

View file

@ -1112,17 +1112,19 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
zend_free_op free_op1;
zval *varname;
zval *retval;
zval tmp_varname;
zend_string *name;
HashTable *target_symbol_table;
SAVE_OPLINE();
varname = GET_OP1_ZVAL_PTR(BP_VAR_R);
ZVAL_UNDEF(&tmp_varname);
if (OP1_TYPE != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_DUP_DEREF(&tmp_varname, varname);
convert_to_string(&tmp_varname);
varname = &tmp_varname;
if (OP1_TYPE == IS_CONST) {
name = Z_STR_P(varname);
} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
name = Z_STR_P(varname);
STR_ADDREF(name);
} else {
name = zval_get_string(varname);
}
if (OP2_TYPE != IS_UNUSED) {
@ -1135,7 +1137,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC);
if (UNEXPECTED(ce == NULL)) {
if (OP1_TYPE != IS_CONST) {
zval_dtor(&tmp_varname);
STR_RELEASE(name);
}
FREE_OP1();
CHECK_EXCEPTION();
@ -1146,26 +1148,26 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
} else {
ce = Z_CE_P(EX_VAR(opline->op2.var));
}
retval = zend_std_get_static_property(ce, Z_STR_P(varname), 0, ((OP1_TYPE == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
retval = zend_std_get_static_property(ce, name, 0, ((OP1_TYPE == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
FREE_OP1();
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, Z_STR_P(varname));
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
case BP_VAR_R:
case BP_VAR_UNSET:
zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
zend_error(E_NOTICE,"Undefined variable: %s", name->val);
/* break missing intentionally */
case BP_VAR_IS:
retval = EX_VAR(opline->result.var);
ZVAL_NULL(retval);
break;
case BP_VAR_RW:
zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
zend_error(E_NOTICE,"Undefined variable: %s", name->val);
/* break missing intentionally */
case BP_VAR_W:
retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval));
retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
@ -1176,14 +1178,14 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
switch (type) {
case BP_VAR_R:
case BP_VAR_UNSET:
zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
zend_error(E_NOTICE,"Undefined variable: %s", name->val);
/* break missing intentionally */
case BP_VAR_IS:
retval = EX_VAR(opline->result.var);
ZVAL_NULL(retval);
break;
case BP_VAR_RW:
zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
zend_error(E_NOTICE,"Undefined variable: %s", name->val);
/* break missing intentionally */
case BP_VAR_W:
ZVAL_NULL(retval);
@ -1200,7 +1202,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
}
if (OP1_TYPE != IS_CONST) {
zval_dtor(&tmp_varname);
STR_RELEASE(name);
}
ZEND_ASSERT(retval != NULL);

File diff suppressed because it is too large Load diff

View file

@ -693,7 +693,8 @@ static void php_filter_array_handler(zval *input, zval *op, zval *return_value,
}
} else {
zval nval;
ZVAL_DUP_DEREF(&nval, tmp);
ZVAL_DEREF(tmp);
ZVAL_DUP(&nval, tmp);
php_filter_call(&nval, -1, arg_elm, 0, FILTER_REQUIRE_SCALAR TSRMLS_CC);
zend_hash_update(Z_ARRVAL_P(return_value), arg_key, &nval);
}

View file

@ -1180,7 +1180,7 @@ PHP_FUNCTION(xml_set_object)
zval_add_ref(&parser->object);
#endif */
ZVAL_DUP_DEREF(&parser->object, mythis);
ZVAL_COPY(&parser->object, mythis);
RETVAL_TRUE;
}