diff --git a/Zend/tests/bug68118.phpt b/Zend/tests/bug68118.phpt new file mode 100644 index 00000000000..c56e70a112d --- /dev/null +++ b/Zend/tests/bug68118.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #68118: $a->foo .= 'test'; can leave $a->foo undefined +--FILE-- +test = 'meow'; + return true; +}); + +$a = new stdClass; +$a->undefined .= 'test'; +var_dump($a); + +?> +--EXPECT-- +object(stdClass)#2 (1) { + ["undefined"]=> + string(4) "test" +} diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index c2377e75124..5ee9847b6ce 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -815,10 +815,6 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type, (guard = zend_get_property_guard(zobj, property_info, member)) == NULL || (property_info && ((*guard) & IN_GET))) { - /* we don't have access controls - will just add it */ - 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) { @@ -830,6 +826,12 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type, } retval = zend_hash_update(zobj->properties, property_info->name, &tmp); } + + /* Notice is thrown after creation of the property, to avoid EG(std_property_info) + * being overwritten in an error handler. */ + 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)); + } } else { /* we do have getter - fail and let it try again with usual get/set */ retval = NULL;