From 844887ed566b264a3654d9cfa90c32c0368a4092 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 24 Feb 2014 13:12:53 +0400 Subject: [PATCH 1/6] Fixed IS_RESOURCE handling --- Zend/zend_API.c | 5 +++-- Zend/zend_execute.c | 5 +++-- Zend/zend_operators.c | 17 ++++++++++++++--- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 23a9139c8e2..00672c4564e 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1619,8 +1619,9 @@ ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value) /* {{{ */ result = zend_symtable_update(ht, STR_EMPTY_ALLOC(), value); break; case IS_RESOURCE: - zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(key), Z_LVAL_P(key)); - /* break missing intentionally */ + zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_RES_HANDLE_P(key), Z_RES_HANDLE_P(key)); + result = zend_hash_index_update(ht, Z_RES_HANDLE_P(key), value); + break; case IS_BOOL: case IS_LONG: result = zend_hash_index_update(ht, Z_LVAL_P(key), value); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 2c20fb329eb..8d27453229f 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1088,8 +1088,9 @@ fetch_string_dim: hval = zend_dval_to_lval(Z_DVAL_P(dim)); goto num_index; case IS_RESOURCE: - zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(dim), Z_LVAL_P(dim)); - /* Fall Through */ + zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_RES_HANDLE_P(dim), Z_RES_HANDLE_P(dim)); + hval = Z_RES_HANDLE_P(dim); + goto num_index; case IS_BOOL: case IS_LONG: hval = Z_LVAL_P(dim); diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index e81b997af73..7a66f9f38a9 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -232,10 +232,14 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */ break; \ } \ case IS_BOOL: \ - case IS_RESOURCE: \ ZVAL_LONG(&(holder), Z_LVAL_P(op)); \ (op) = &(holder); \ break; \ + case IS_RESOURCE: \ + /* ??? delete old resource ??? */ \ + ZVAL_LONG(&(holder), Z_RES_HANDLE_P(op)); \ + (op) = &(holder); \ + break; \ case IS_NULL: \ ZVAL_LONG(&(holder), 0); \ (op) = &(holder); \ @@ -275,9 +279,12 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */ convert_to_long_base(&(holder), 10); \ break; \ case IS_BOOL: \ - case IS_RESOURCE: \ Z_LVAL(holder) = Z_LVAL_P(op); \ break; \ + case IS_RESOURCE: \ + /* ??? delete old resource ??? */ \ + ZVAL_LONG(&holder, Z_RES_HANDLE_P(op)); \ + break; \ default: \ zend_error(E_WARNING, "Cannot convert to ordinal value"); \ Z_LVAL(holder) = 0; \ @@ -299,6 +306,8 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */ Z_LVAL(holder) = 0; \ break; \ case IS_RESOURCE: \ + Z_LVAL(holder) = (Z_RES_HANDLE_P(op) ? 1 : 0); \ + break; \ case IS_LONG: \ Z_LVAL(holder) = (Z_LVAL_P(op) ? 1 : 0); \ break; \ @@ -1728,9 +1737,11 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) break; case IS_BOOL: case IS_LONG: - case IS_RESOURCE: Z_LVAL_P(result) = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); break; + case IS_RESOURCE: + Z_LVAL_P(result) = (Z_RES_P(op1) == Z_RES_P(op2)); + break; case IS_DOUBLE: Z_LVAL_P(result) = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); break; From fd87bde4d64bae9e268d0f5b7f1977ec83af77e9 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 24 Feb 2014 13:19:32 +0400 Subject: [PATCH 2/6] Fixed error messages --- Zend/zend_object_handlers.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 8a461ff21fd..276f47efaec 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -332,7 +332,7 @@ static zend_always_inline struct _zend_property_info *zend_get_property_info_qui if (UNEXPECTED(denied_access != 0)) { /* Information was available, but we were denied access. Error out. */ if (!silent) { - zend_error_noreturn(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name, Z_STRVAL_P(member)); + zend_error_noreturn(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name->val, Z_STRVAL_P(member)); } return NULL; } else { @@ -485,7 +485,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type, const zend_li Z_SET_REFCOUNT_P(rv, 0); } if (UNEXPECTED(Z_TYPE_P(rv) != IS_OBJECT)) { - zend_error(E_NOTICE, "Indirect modification of overloaded property %s::$%s has no effect", zobj->ce->name, Z_STRVAL_P(member)); + zend_error(E_NOTICE, "Indirect modification of overloaded property %s::$%s has no effect", zobj->ce->name->val, Z_STRVAL_P(member)); } } } else { @@ -1202,7 +1202,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st /* right now this function is used for non static method lookup too */ /* Is the function static */ if (UNEXPECTED(!(fbc->common.fn_flags & ZEND_ACC_STATIC))) { - zend_error_noreturn(E_ERROR, "Cannot call non static method %s::%s() without object", ZEND_FN_SCOPE_NAME(fbc), fbc->common.function_name); + zend_error_noreturn(E_ERROR, "Cannot call non static method %s::%s() without object", ZEND_FN_SCOPE_NAME(fbc), fbc->common.function_name->val); } #endif if (fbc->op_array.fn_flags & ZEND_ACC_PUBLIC) { @@ -1258,14 +1258,14 @@ ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *p if (UNEXPECTED(!zend_verify_property_access(property_info, ce TSRMLS_CC))) { if (!silent) { - zend_error_noreturn(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name, property_name); + zend_error_noreturn(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name->val, property_name->val); } return NULL; } if (UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { if (!silent) { - zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name, property_name); + zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, property_name->val); } return NULL; } From 62e7ac77e5ba89b624be6af4f2311e1d1fc4f582 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 24 Feb 2014 13:33:30 +0400 Subject: [PATCH 3/6] Fixed arg_info[].class_name destruction --- Zend/zend_compile.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index a54aee86c8f..5c39e6f0b79 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1936,8 +1936,15 @@ void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initializ zend_resolve_class_name(class_type TSRMLS_CC); } Z_STR(class_type->u.constant) = zend_new_interned_string(Z_STR(class_type->u.constant) TSRMLS_CC); +//???: for now we have to copy it :( +#if 1 + cur_arg_info->class_name = estrndup(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant)); + cur_arg_info->class_name_len = Z_STRLEN(class_type->u.constant); + STR_RELEASE(Z_STR(class_type->u.constant)); +#else cur_arg_info->class_name = Z_STRVAL(class_type->u.constant); cur_arg_info->class_name_len = Z_STRLEN(class_type->u.constant); +#endif if (op == ZEND_RECV_INIT) { if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) { cur_arg_info->allow_null = 1; @@ -3284,13 +3291,9 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c zend_string *fe_class_name, *proto_class_name; if (!strcasecmp(fe_arg_info->class_name, "parent") && proto->common.scope) { - fe_class_name = STR_INIT( - proto->common.scope->name->val, - proto->common.scope->name->len, 0); + fe_class_name = STR_COPY(proto->common.scope->name); } else if (!strcasecmp(fe_arg_info->class_name, "self") && fe->common.scope) { - fe_class_name = STR_INIT( - fe->common.scope->name->val, - fe->common.scope->name->len, 0); + fe_class_name = STR_COPY(fe->common.scope->name); } else { fe_class_name = STR_INIT( fe_arg_info->class_name, @@ -3298,13 +3301,9 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c } if (!strcasecmp(proto_arg_info->class_name, "parent") && proto->common.scope && proto->common.scope->parent) { - proto_class_name = STR_INIT( - proto->common.scope->parent->name->val, - proto->common.scope->parent->name->len, 0); + proto_class_name = STR_COPY(proto->common.scope->parent->name); } else if (!strcasecmp(proto_arg_info->class_name, "self") && proto->common.scope) { - proto_class_name = STR_INIT( - proto->common.scope->name->val, - proto->common.scope->name->len, 0); + proto_class_name = STR_COPY(proto->common.scope->name); } else { proto_class_name = STR_INIT( proto_arg_info->class_name, @@ -3315,6 +3314,8 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c const char *colon; if (fe->common.type != ZEND_USER_FUNCTION) { + STR_RELEASE(proto_class_name); + STR_RELEASE(fe_class_name); return 0; } else if (strchr(proto_class_name->val, '\\') != NULL || (colon = zend_memrchr(fe_class_name->val, '\\', fe_class_name->len)) == NULL || @@ -3329,10 +3330,14 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c fe_ce->type == ZEND_INTERNAL_CLASS || proto_ce->type == ZEND_INTERNAL_CLASS || fe_ce != proto_ce) { + STR_RELEASE(proto_class_name); + STR_RELEASE(fe_class_name); return 0; } } } + STR_RELEASE(proto_class_name); + STR_RELEASE(fe_class_name); } if (fe_arg_info->type_hint != proto_arg_info->type_hint) { /* Incompatible type hint */ From 1770ace2497aefa73b972aa9876cbc9a551bbb45 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 24 Feb 2014 13:49:53 +0400 Subject: [PATCH 4/6] Fixed object to string conversion --- Zend/zend_object_handlers.c | 6 ++---- Zend/zend_operators.c | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 276f47efaec..11b16e14727 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1534,14 +1534,12 @@ ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int ty switch (type) { case IS_STRING: - ZVAL_UNDEF(&retval); + ZVAL_UNDEF(&retval); ce = Z_OBJCE_P(readobj); if (ce->__tostring && (zend_call_method_with_0_params(readobj, ce, &ce->__tostring, "__tostring", &retval) || EG(exception))) { if (UNEXPECTED(EG(exception) != NULL)) { - if (Z_TYPE(retval) != IS_UNDEF) { - zval_ptr_dtor(&retval); - } + zval_ptr_dtor(&retval); EG(exception) = NULL; zend_error_noreturn(E_ERROR, "Method %s::__toString() must not throw an exception", ce->name->val); return FAILURE; diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 7a66f9f38a9..8504ca5aaf0 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -343,6 +343,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */ #define convert_object_to_type(op, ctype, conv_func) \ if (Z_OBJ_HT_P(op)->cast_object) { \ zval dst; \ + ZVAL_UNDEF(&dst); \ if (Z_OBJ_HT_P(op)->cast_object(op, &dst, ctype TSRMLS_CC) == FAILURE) { \ zend_error(E_RECOVERABLE_ERROR, \ "Object of class %s could not be converted to %s", Z_OBJCE_P(op)->name->val,\ @@ -1634,6 +1635,7 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* { zend_free_obj_get_result(op_free TSRMLS_CC); return ret; } else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) { + ZVAL_UNDEF(&tmp_free); if (Z_OBJ_HT_P(op1)->cast_object(op1, &tmp_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) { ZVAL_LONG(result, 1); zend_free_obj_get_result(&tmp_free TSRMLS_CC); @@ -1651,6 +1653,7 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* { zend_free_obj_get_result(op_free TSRMLS_CC); return ret; } else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) { + ZVAL_UNDEF(&tmp_free); if (Z_OBJ_HT_P(op2)->cast_object(op2, &tmp_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) { ZVAL_LONG(result, -1); zend_free_obj_get_result(&tmp_free TSRMLS_CC); From 454e9911ad664c1fb51e663c001137ef1dcd4762 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 24 Feb 2014 14:00:52 +0400 Subject: [PATCH 5/6] Fixed new dynamic propery creation --- Zend/zend_object_handlers.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 11b16e14727..eb7d86ff6e0 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -736,7 +736,7 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type, { zend_object *zobj; zval tmp_member; - zval *retval; + zval *retval, tmp; zend_property_info *property_info; long *guard; @@ -766,7 +766,7 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type, } goto exit; } - if (UNEXPECTED(!zobj->properties)) { + if (UNEXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, property_info->name); if (retval) goto exit; } @@ -780,12 +780,10 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type, if(UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) { zend_error(E_NOTICE, "Undefined property: %s::$%s", zobj->ce->name->val, Z_STRVAL_P(member)); } + ZVAL_NULL(&tmp); if (EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) && property_info->offset >= 0) { if (zobj->properties) { - zval tmp; - - ZVAL_NULL(&tmp); retval = zend_hash_update(zobj->properties, property_info->name, &tmp); ZVAL_INDIRECT(&zobj->properties_table[property_info->offset], retval); } else { @@ -796,7 +794,7 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type, if (!zobj->properties) { rebuild_object_properties(zobj); } - zend_hash_update(zobj->properties, property_info->name, retval); + retval = zend_hash_update(zobj->properties, property_info->name, &tmp); } } else { /* we do have getter - fail and let it try again with usual get/set */ From 73b8e9aef4206fdbd31c7df9da52b96ae78a9a1e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 24 Feb 2014 14:06:39 +0400 Subject: [PATCH 6/6] Fixed wrong condition --- Zend/zend_object_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index eb7d86ff6e0..5f68520644d 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -452,7 +452,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type, const zend_li } goto exit; } - if (UNEXPECTED(!zobj->properties)) { + if (UNEXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, property_info->name); if (retval) goto exit; }