summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2004-03-18 16:54:36 +0000
committerDmitry Stogov <dmitry@php.net>2004-03-18 16:54:36 +0000
commitdeb84befae4bbc3686a4f2ed82b04e2cabae5dc0 (patch)
tree5f918f5692603efac83886bbef185f175875522d
parent814000305a7689355bcb601330147a107fd96d9c (diff)
downloadphp-git-deb84befae4bbc3686a4f2ed82b04e2cabae5dc0.tar.gz
BUG #27469 was fixed (serialize() objects of incomplete class)
-rw-r--r--ext/standard/incomplete_class.c7
-rw-r--r--ext/standard/php_incomplete_class.h8
-rw-r--r--ext/standard/tests/serialize/bug27469.phpt27
-rw-r--r--ext/standard/var.c25
4 files changed, 55 insertions, 12 deletions
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--
+<?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"
+}
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;