]> granicus.if.org Git - php/commitdiff
BUG #27469 was fixed (serialize() objects of incomplete class)
authorDmitry Stogov <dmitry@php.net>
Thu, 18 Mar 2004 16:54:36 +0000 (16:54 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 18 Mar 2004 16:54:36 +0000 (16:54 +0000)
ext/standard/incomplete_class.c
ext/standard/php_incomplete_class.h
ext/standard/tests/serialize/bug27469.phpt [new file with mode: 0644]
ext/standard/var.c

index e333173971f4a3561f76e10dfc2ecdb4a8516425..9863b8dc3368b22681f106ca9d86969620962df2 100644 (file)
@@ -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);
index 30ee705255dd3a6eefe3a8594f31ef37d8cd4e22..8c7f68ae15346387ae4e05e5cab5e86bf60e0112 100644 (file)
@@ -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 (file)
index 0000000..e8d1410
--- /dev/null
@@ -0,0 +1,27 @@
+--TEST--
+Bug #27469 (serialize() objects of incomplete class)
+--FILE--
+<?php
+$str = 'O:9:"TestClass":0:{}';
+$obj = unserialize($str);
+var_dump($obj);
+echo serialize($obj)."\n";
+var_dump($obj);
+echo serialize($obj)."\n";
+var_dump($obj);
+?>
+--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"
+}
index f0f5583dca8bef2f4a06966aea78e5fc17b6efcd..0cd766d1c86989a6415bae846ee7e0154eabc920 100644 (file)
@@ -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;