From: Dmitry Stogov Date: Thu, 18 Mar 2004 16:54:36 +0000 (+0000) Subject: BUG #27469 was fixed (serialize() objects of incomplete class) X-Git-Tag: php-5.0.0RC2RC1~305 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=deb84befae4bbc3686a4f2ed82b04e2cabae5dc0;p=php BUG #27469 was fixed (serialize() objects of incomplete class) --- diff --git a/ext/standard/incomplete_class.c b/ext/standard/incomplete_class.c index e333173971..9863b8dc33 100644 --- a/ext/standard/incomplete_class.c +++ b/ext/standard/incomplete_class.c @@ -39,7 +39,7 @@ static void incomplete_class_message(int error_type TSRMLS_DC) char *class_name = NULL; if(EG(This)) { - class_name = php_lookup_class_name(EG(This), NULL, 0); + class_name = php_lookup_class_name(EG(This), NULL); } if (!class_name) @@ -114,7 +114,7 @@ zend_class_entry *php_create_incomplete_class(TSRMLS_D) /* {{{ php_lookup_class_name */ -char *php_lookup_class_name(zval *object, size_t *nlen, zend_bool del) +char *php_lookup_class_name(zval *object, size_t *nlen) { zval **val; char *retval = NULL; @@ -128,9 +128,6 @@ char *php_lookup_class_name(zval *object, size_t *nlen, zend_bool del) if (nlen) *nlen = Z_STRLEN_PP(val); - - if (del) - zend_hash_del(object_properties, MAGIC_MEMBER, sizeof(MAGIC_MEMBER)); } return (retval); diff --git a/ext/standard/php_incomplete_class.h b/ext/standard/php_incomplete_class.h index 30ee705255..8c7f68ae15 100644 --- a/ext/standard/php_incomplete_class.h +++ b/ext/standard/php_incomplete_class.h @@ -29,8 +29,9 @@ #define PHP_SET_CLASS_ATTRIBUTES(struc) \ /* OBJECTS_FIXME: Fix for new object model */ \ if (Z_OBJCE_P(struc) == BG(incomplete_class)) { \ - class_name = php_lookup_class_name(struc, &name_len, 1); \ + class_name = php_lookup_class_name(struc, &name_len); \ free_class_name = 1; \ + incomplete_class = 1; \ } else { \ class_name = Z_OBJCE_P(struc)->name; \ name_len = Z_OBJCE_P(struc)->name_length; \ @@ -42,7 +43,8 @@ #define PHP_CLASS_ATTRIBUTES \ char *class_name; \ size_t name_len; \ - zend_bool free_class_name = 0 \ + zend_bool free_class_name = 0; \ + zend_bool incomplete_class = 0 #define INCOMPLETE_CLASS "__PHP_Incomplete_Class" #define MAGIC_MEMBER "__PHP_Incomplete_Class_Name" @@ -53,7 +55,7 @@ extern "C" { zend_class_entry *php_create_incomplete_class(TSRMLS_D); -char *php_lookup_class_name(zval *object, size_t *nlen, zend_bool del); +char *php_lookup_class_name(zval *object, size_t *nlen); void php_store_class_name(zval *object, const char *name, size_t len); #ifdef __cplusplus diff --git a/ext/standard/tests/serialize/bug27469.phpt b/ext/standard/tests/serialize/bug27469.phpt new file mode 100644 index 0000000000..e8d14106a8 --- /dev/null +++ b/ext/standard/tests/serialize/bug27469.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #27469 (serialize() objects of incomplete class) +--FILE-- + +--EXPECT-- +object(__PHP_Incomplete_Class)#1 (1) { + ["__PHP_Incomplete_Class_Name"]=> + string(9) "TestClass" +} +O:9:"TestClass":0:{} +object(__PHP_Incomplete_Class)#1 (1) { + ["__PHP_Incomplete_Class_Name"]=> + string(9) "TestClass" +} +O:9:"TestClass":0:{} +object(__PHP_Incomplete_Class)#1 (1) { + ["__PHP_Incomplete_Class_Name"]=> + string(9) "TestClass" +} diff --git a/ext/standard/var.c b/ext/standard/var.c index f0f5583dca..0cd766d1c8 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -468,7 +468,7 @@ static inline void php_var_serialize_string(smart_str *buf, char *str, int len) smart_str_appendl(buf, "\";", 2); } -static inline void php_var_serialize_class_name(smart_str *buf, zval **struc TSRMLS_DC) +static inline zend_bool php_var_serialize_class_name(smart_str *buf, zval **struc TSRMLS_DC) { PHP_CLASS_ATTRIBUTES; @@ -479,16 +479,21 @@ static inline void php_var_serialize_class_name(smart_str *buf, zval **struc TSR smart_str_appendl(buf, class_name, name_len); smart_str_appendl(buf, "\":", 2); PHP_CLEANUP_CLASS_ATTRIBUTES(); + return incomplete_class; } static void php_var_serialize_class(smart_str *buf, zval **struc, zval *retval_ptr, HashTable *var_hash TSRMLS_DC) { int count; + zend_bool incomplete_class; - php_var_serialize_class_name(buf, struc TSRMLS_CC); + incomplete_class = php_var_serialize_class_name(buf, struc TSRMLS_CC); /* count after serializing name, since php_var_serialize_class_name changes the count if the variable is incomplete class */ count = zend_hash_num_elements(HASH_OF(retval_ptr)); + if (incomplete_class) { + --count; + } smart_str_append_long(buf, count); smart_str_appendl(buf, ":{", 2); @@ -512,6 +517,9 @@ static void php_var_serialize_class(smart_str *buf, zval **struc, zval *retval_p if (i == HASH_KEY_NON_EXISTANT) break; + if (incomplete_class && strcmp(key, MAGIC_MEMBER) == 0) { + continue; + } zend_hash_get_current_data_ex(HASH_OF(retval_ptr), (void **) &name, &pos); @@ -624,17 +632,21 @@ static void php_var_serialize_intern(smart_str *buf, zval **struc, HashTable *va zval_ptr_dtor(&retval_ptr); /* fall-through */ } - case IS_ARRAY: + case IS_ARRAY: { + zend_bool incomplete_class = 0; if (Z_TYPE_PP(struc) == IS_ARRAY) { smart_str_appendl(buf, "a:", 2); myht = HASH_OF(*struc); } else { - php_var_serialize_class_name(buf, struc TSRMLS_CC); + incomplete_class = php_var_serialize_class_name(buf, struc TSRMLS_CC); myht = Z_OBJPROP_PP(struc); } /* count after serializing name, since php_var_serialize_class_name changes the count if the variable is incomplete class */ i = myht ? zend_hash_num_elements(myht) : 0; + if (i > 0 && incomplete_class) { + --i; + } smart_str_append_long(buf, i); smart_str_appendl(buf, ":{", 2); if (i > 0) { @@ -651,6 +663,10 @@ static void php_var_serialize_intern(smart_str *buf, zval **struc, HashTable *va if (i == HASH_KEY_NON_EXISTANT) break; + if (incomplete_class && strcmp(key, MAGIC_MEMBER) == 0) { + continue; + } + switch (i) { case HASH_KEY_IS_LONG: php_var_serialize_long(buf, index); @@ -674,6 +690,7 @@ static void php_var_serialize_intern(smart_str *buf, zval **struc, HashTable *va } smart_str_appendc(buf, '}'); return; + } default: smart_str_appendl(buf, "i:0;", 4); return;