@@ -880,6 +880,55 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt
880
880
}
881
881
/* }}} */
882
882
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
+
883
932
static void php_var_serialize_intern (smart_str * buf , zval * struc , php_serialize_data_t var_hash ) /* {{{ */
884
933
{
885
934
zend_long var_already ;
@@ -940,6 +989,8 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_
940
989
941
990
case IS_OBJECT : {
942
991
zend_class_entry * ce = Z_OBJCE_P (struc );
992
+ zend_bool incomplete_class ;
993
+ uint32_t count ;
943
994
944
995
if (zend_hash_str_exists (& ce -> function_table , "__serialize" , sizeof ("__serialize" )- 1 )) {
945
996
zval retval , obj ;
@@ -1030,75 +1081,24 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_
1030
1081
return ;
1031
1082
}
1032
1083
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 {
1043
1084
incomplete_class = php_var_serialize_class_name (buf , struc );
1044
1085
myht = zend_get_properties_for (struc , ZEND_PROP_PURPOSE_SERIALIZE );
1045
1086
/* count after serializing name, since php_var_serialize_class_name
1046
1087
* 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 ;
1050
1091
}
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 );
1098
1093
zend_release_properties (myht );
1094
+ return ;
1099
1095
}
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 );
1100
1101
return ;
1101
- }
1102
1102
case IS_REFERENCE :
1103
1103
struc = Z_REFVAL_P (struc );
1104
1104
goto again ;
0 commit comments