diff options
Diffstat (limited to 'Zend')
| -rw-r--r-- | Zend/tests/bug70187.phpt | 19 | ||||
| -rw-r--r-- | Zend/zend_hash.c | 8 | ||||
| -rw-r--r-- | Zend/zend_hash.h | 3 | ||||
| -rw-r--r-- | Zend/zend_object_handlers.c | 17 | ||||
| -rw-r--r-- | Zend/zend_objects.c | 3 |
5 files changed, 41 insertions, 9 deletions
diff --git a/Zend/tests/bug70187.phpt b/Zend/tests/bug70187.phpt new file mode 100644 index 0000000000..a30f13b3ea --- /dev/null +++ b/Zend/tests/bug70187.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #70187 (Notice: unserialize(): Unexpected end of serialized data) +--FILE-- +<?php +class A { + public $b; +} + +$a = new A; +var_dump($a); // force properties HT +unset($a->b); +var_dump(serialize($a)); +?> +--EXPECT-- +object(A)#1 (1) { + ["b"]=> + NULL +} +string(12) "O:1:"A":0:{}" diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index eaade17838..139b0986f1 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -32,12 +32,12 @@ #if ZEND_DEBUG /* -#define HASH_MASK_CONSISTENCY 0x60 +#define HASH_MASK_CONSISTENCY 0xc0 */ #define HT_OK 0x00 -#define HT_IS_DESTROYING 0x20 -#define HT_DESTROYED 0x40 -#define HT_CLEANING 0x60 +#define HT_IS_DESTROYING 0x40 +#define HT_DESTROYED 0x80 +#define HT_CLEANING 0xc0 static void _zend_is_inconsistent(const HashTable *ht, const char *file, int line) { diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 4a33b959cb..cdd635fa19 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -39,8 +39,9 @@ #define HASH_FLAG_PACKED (1<<2) #define HASH_FLAG_INITIALIZED (1<<3) #define HASH_FLAG_STATIC_KEYS (1<<4) +#define HASH_FLAG_HAS_EMPTY_IND (1<<5) -#define HASH_MASK_CONSISTENCY 0x60 +#define HASH_MASK_CONSISTENCY 0xc0 typedef struct _zend_hash_key { zend_ulong h; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 1c06f1ea5e..be9f50bfd4 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -82,8 +82,11 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */ zobj->properties->nInternalPointer = 0; ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) { if (/*prop_info->ce == ce &&*/ - (prop_info->flags & ZEND_ACC_STATIC) == 0 && - Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) != IS_UNDEF) { + (prop_info->flags & ZEND_ACC_STATIC) == 0) { + + if (UNEXPECTED(Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) == IS_UNDEF)) { + zobj->properties->u.v.flags |= HASH_FLAG_HAS_EMPTY_IND; + } _zend_hash_append_ind(zobj->properties, prop_info->name, OBJ_PROP(zobj, prop_info->offset)); @@ -94,10 +97,13 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */ ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) { if (prop_info->ce == ce && (prop_info->flags & ZEND_ACC_STATIC) == 0 && - (prop_info->flags & ZEND_ACC_PRIVATE) != 0 && - Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) != IS_UNDEF) { + (prop_info->flags & ZEND_ACC_PRIVATE) != 0) { zval zv; + if (UNEXPECTED(Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) == IS_UNDEF)) { + zobj->properties->u.v.flags |= HASH_FLAG_HAS_EMPTY_IND; + } + ZVAL_INDIRECT(&zv, OBJ_PROP(zobj, prop_info->offset)); zend_hash_add(zobj->properties, prop_info->name, &zv); } @@ -882,6 +888,9 @@ static void zend_std_unset_property(zval *object, zval *member, void **cache_slo if (Z_TYPE_P(slot) != IS_UNDEF) { zval_ptr_dtor(slot); ZVAL_UNDEF(slot); + if (zobj->properties) { + zobj->properties->u.v.flags |= HASH_FLAG_HAS_EMPTY_IND; + } goto exit; } } else if (EXPECTED(zobj->properties != NULL)) { diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 9694cd6958..ca7ca52d89 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -204,6 +204,9 @@ ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *o zend_hash_extend(new_object->properties, new_object->properties->nNumUsed + zend_hash_num_elements(old_object->properties), 0); } + new_object->properties->u.v.flags |= + old_object->properties->u.v.flags & HASH_FLAG_HAS_EMPTY_IND; + ZEND_HASH_FOREACH_KEY_VAL(old_object->properties, num_key, key, prop) { if (Z_TYPE_P(prop) == IS_INDIRECT) { ZVAL_INDIRECT(&new_prop, new_object->properties_table + (Z_INDIRECT_P(prop) - old_object->properties_table)); |
