summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
Diffstat (limited to 'Zend')
-rw-r--r--Zend/tests/bug70187.phpt19
-rw-r--r--Zend/zend_hash.c8
-rw-r--r--Zend/zend_hash.h3
-rw-r--r--Zend/zend_object_handlers.c17
-rw-r--r--Zend/zend_objects.c3
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));