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)
/* {{{ 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;
if (nlen)
*nlen = Z_STRLEN_PP(val);
-
- if (del)
- zend_hash_del(object_properties, MAGIC_MEMBER, sizeof(MAGIC_MEMBER));
}
return (retval);
#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; \
#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"
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
--- /dev/null
+--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"
+}
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;
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);
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);
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) {
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);
}
smart_str_appendc(buf, '}');
return;
+ }
default:
smart_str_appendl(buf, "i:0;", 4);
return;