Skip to content

Commit 701e8c6

Browse files
committed
Extract php_var_serialize_nested_data() function
And split code-paths for arrays and objects based on it.
1 parent 8d2b20d commit 701e8c6

File tree

1 file changed

+61
-61
lines changed

1 file changed

+61
-61
lines changed

ext/standard/var.c

Lines changed: 61 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,55 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt
880880
}
881881
/* }}} */
882882

883+
static void php_var_serialize_nested_data(smart_str *buf, zval *struc, HashTable *ht, uint32_t count, zend_bool incomplete_class, php_serialize_data_t var_hash) /* {{{ */
884+
{
885+
smart_str_append_unsigned(buf, count);
886+
smart_str_appendl(buf, ":{", 2);
887+
if (count > 0) {
888+
zend_string *key;
889+
zval *data;
890+
zend_ulong index;
891+
892+
ZEND_HASH_FOREACH_KEY_VAL_IND(ht, index, key, data) {
893+
if (incomplete_class && strcmp(ZSTR_VAL(key), MAGIC_MEMBER) == 0) {
894+
continue;
895+
}
896+
897+
if (!key) {
898+
php_var_serialize_long(buf, index);
899+
} else {
900+
php_var_serialize_string(buf, ZSTR_VAL(key), ZSTR_LEN(key));
901+
}
902+
903+
if (Z_ISREF_P(data) && Z_REFCOUNT_P(data) == 1) {
904+
data = Z_REFVAL_P(data);
905+
}
906+
907+
/* we should still add element even if it's not OK,
908+
* since we already wrote the length of the array before */
909+
if (Z_TYPE_P(data) == IS_ARRAY) {
910+
if (UNEXPECTED(Z_IS_RECURSIVE_P(data))
911+
|| UNEXPECTED(Z_TYPE_P(struc) == IS_ARRAY && Z_ARR_P(data) == Z_ARR_P(struc))) {
912+
php_add_var_hash(var_hash, struc);
913+
smart_str_appendl(buf, "N;", 2);
914+
} else {
915+
if (Z_REFCOUNTED_P(data)) {
916+
Z_PROTECT_RECURSION_P(data);
917+
}
918+
php_var_serialize_intern(buf, data, var_hash);
919+
if (Z_REFCOUNTED_P(data)) {
920+
Z_UNPROTECT_RECURSION_P(data);
921+
}
922+
}
923+
} else {
924+
php_var_serialize_intern(buf, data, var_hash);
925+
}
926+
} ZEND_HASH_FOREACH_END();
927+
}
928+
smart_str_appendc(buf, '}');
929+
}
930+
/* }}} */
931+
883932
static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_data_t var_hash) /* {{{ */
884933
{
885934
zend_long var_already;
@@ -940,6 +989,8 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_
940989

941990
case IS_OBJECT: {
942991
zend_class_entry *ce = Z_OBJCE_P(struc);
992+
zend_bool incomplete_class;
993+
uint32_t count;
943994

944995
if (zend_hash_str_exists(&ce->function_table, "__serialize", sizeof("__serialize")-1)) {
945996
zval retval, obj;
@@ -1030,75 +1081,24 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_
10301081
return;
10311082
}
10321083

1033-
/* fall-through */
1034-
}
1035-
case IS_ARRAY: {
1036-
uint32_t i;
1037-
zend_bool incomplete_class = 0;
1038-
if (Z_TYPE_P(struc) == IS_ARRAY) {
1039-
smart_str_appendl(buf, "a:", 2);
1040-
myht = Z_ARRVAL_P(struc);
1041-
i = zend_array_count(myht);
1042-
} else {
10431084
incomplete_class = php_var_serialize_class_name(buf, struc);
10441085
myht = zend_get_properties_for(struc, ZEND_PROP_PURPOSE_SERIALIZE);
10451086
/* count after serializing name, since php_var_serialize_class_name
10461087
* changes the count if the variable is incomplete class */
1047-
i = zend_array_count(myht);
1048-
if (i > 0 && incomplete_class) {
1049-
--i;
1088+
count = zend_array_count(myht);
1089+
if (count > 0 && incomplete_class) {
1090+
--count;
10501091
}
1051-
}
1052-
smart_str_append_unsigned(buf, i);
1053-
smart_str_appendl(buf, ":{", 2);
1054-
if (i > 0) {
1055-
zend_string *key;
1056-
zval *data;
1057-
zend_ulong index;
1058-
1059-
ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, data) {
1060-
1061-
if (incomplete_class && strcmp(ZSTR_VAL(key), MAGIC_MEMBER) == 0) {
1062-
continue;
1063-
}
1064-
1065-
if (!key) {
1066-
php_var_serialize_long(buf, index);
1067-
} else {
1068-
php_var_serialize_string(buf, ZSTR_VAL(key), ZSTR_LEN(key));
1069-
}
1070-
1071-
if (Z_ISREF_P(data) && Z_REFCOUNT_P(data) == 1) {
1072-
data = Z_REFVAL_P(data);
1073-
}
1074-
1075-
/* we should still add element even if it's not OK,
1076-
* since we already wrote the length of the array before */
1077-
if (Z_TYPE_P(data) == IS_ARRAY) {
1078-
if (UNEXPECTED(Z_IS_RECURSIVE_P(data))
1079-
|| UNEXPECTED(Z_TYPE_P(struc) == IS_ARRAY && Z_ARR_P(data) == Z_ARR_P(struc))) {
1080-
php_add_var_hash(var_hash, struc);
1081-
smart_str_appendl(buf, "N;", 2);
1082-
} else {
1083-
if (Z_REFCOUNTED_P(data)) {
1084-
Z_PROTECT_RECURSION_P(data);
1085-
}
1086-
php_var_serialize_intern(buf, data, var_hash);
1087-
if (Z_REFCOUNTED_P(data)) {
1088-
Z_UNPROTECT_RECURSION_P(data);
1089-
}
1090-
}
1091-
} else {
1092-
php_var_serialize_intern(buf, data, var_hash);
1093-
}
1094-
} ZEND_HASH_FOREACH_END();
1095-
}
1096-
smart_str_appendc(buf, '}');
1097-
if (Z_TYPE_P(struc) == IS_OBJECT) {
1092+
php_var_serialize_nested_data(buf, struc, myht, count, incomplete_class, var_hash);
10981093
zend_release_properties(myht);
1094+
return;
10991095
}
1096+
case IS_ARRAY:
1097+
smart_str_appendl(buf, "a:", 2);
1098+
myht = Z_ARRVAL_P(struc);
1099+
php_var_serialize_nested_data(
1100+
buf, struc, myht, zend_array_count(myht), /* incomplete_class */ 0, var_hash);
11001101
return;
1101-
}
11021102
case IS_REFERENCE:
11031103
struc = Z_REFVAL_P(struc);
11041104
goto again;

0 commit comments

Comments
 (0)