@@ -1077,9 +1077,14 @@ static void spl_heap_serialize_internal_state(zval *return_value, spl_heap_objec
10771077
10781078 array_init (return_value );
10791079 add_assoc_long (return_value , "flags" , intern -> flags );
1080-
1080+
10811081 array_init_size (& heap_elements , heap_count );
10821082
1083+ if (heap_count == 0 ) {
1084+ add_assoc_zval (return_value , "heap_elements" , & heap_elements );
1085+ return ;
1086+ }
1087+
10831088 for (int heap_idx = 0 ; heap_idx < heap_count ; ++ heap_idx ) {
10841089 if (is_pqueue ) {
10851090 spl_pqueue_elem * elem = spl_heap_elem (intern -> heap , heap_idx );
@@ -1100,62 +1105,66 @@ static void spl_heap_serialize_internal_state(zval *return_value, spl_heap_objec
11001105 add_assoc_zval (return_value , "heap_elements" , & heap_elements );
11011106}
11021107
1103- static void spl_heap_unserialize_internal_state (HashTable * state_ht , spl_heap_object * intern , zval * this_ptr , bool is_pqueue )
1108+ static zend_result spl_heap_unserialize_internal_state (HashTable * state_ht , spl_heap_object * intern , zval * this_ptr , bool is_pqueue )
11041109{
11051110 zval * flags_val = zend_hash_str_find (state_ht , "flags" , strlen ("flags" ));
11061111 if (!flags_val || Z_TYPE_P (flags_val ) != IS_LONG ) {
1107- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1108- return ;
1112+ return FAILURE ;
11091113 }
11101114
11111115 zend_long flags_value = Z_LVAL_P (flags_val );
11121116
11131117 if (is_pqueue ) {
11141118 flags_value &= SPL_PQUEUE_EXTR_MASK ;
11151119 if (!flags_value ) {
1116- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1117- return ;
1120+ return FAILURE ;
11181121 }
1122+ } else if (flags_value != 0 ) { /* Regular heaps should not have user-visible flags */
1123+ return FAILURE ;
11191124 }
11201125
11211126 intern -> flags = (int ) flags_value ;
11221127
11231128 zval * heap_elements = zend_hash_str_find (state_ht , "heap_elements" , strlen ("heap_elements" ));
11241129 if (!heap_elements ) {
1125- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1126- return ;
1130+ return FAILURE ;
11271131 }
11281132
11291133 if (Z_TYPE_P (heap_elements ) != IS_ARRAY ) {
1130- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1131- return ;
1134+ return FAILURE ;
11321135 }
11331136
11341137 ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (heap_elements ), zval * val ) {
11351138 if (is_pqueue ) {
11361139 /* PriorityQueue elements are serialized as arrays with 'data' and 'priority' keys */
11371140 if (Z_TYPE_P (val ) != IS_ARRAY || zend_hash_num_elements (Z_ARRVAL_P (val )) != 2 ) {
1138- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1139- return ;
1141+ return FAILURE ;
11401142 }
11411143
11421144 zval * data_val = zend_hash_str_find (Z_ARRVAL_P (val ), "data" , strlen ("data" ) );
11431145 zval * priority_val = zend_hash_str_find (Z_ARRVAL_P (val ), "priority" , strlen ("priority" ));
11441146
11451147 if (!data_val || !priority_val ) {
1146- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1147- return ;
1148+ return FAILURE ;
11481149 }
11491150
11501151 spl_pqueue_elem elem ;
11511152 ZVAL_COPY (& elem .data , data_val );
11521153 ZVAL_COPY (& elem .priority , priority_val );
11531154 spl_ptr_heap_insert (intern -> heap , & elem , this_ptr );
1155+ if (EG (exception )) {
1156+ return FAILURE ;
1157+ }
11541158 } else {
11551159 Z_TRY_ADDREF_P (val );
11561160 spl_ptr_heap_insert (intern -> heap , val , this_ptr );
1161+ if (EG (exception )) {
1162+ return FAILURE ;
1163+ }
11571164 }
11581165 } ZEND_HASH_FOREACH_END ();
1166+
1167+ return SUCCESS ;
11591168}
11601169
11611170PHP_METHOD (SplPriorityQueue , __serialize )
@@ -1169,6 +1178,11 @@ PHP_METHOD(SplPriorityQueue, __serialize)
11691178 RETURN_THROWS ();
11701179 }
11711180
1181+ if (intern -> heap -> flags & SPL_HEAP_WRITE_LOCKED ) {
1182+ zend_throw_exception (spl_ce_RuntimeException , "Cannot serialize heap while it is being modified." , 0 );
1183+ RETURN_THROWS ();
1184+ }
1185+
11721186 array_init (return_value );
11731187
11741188 ZVAL_ARR (& props , zend_std_get_properties (& intern -> std ));
@@ -1211,10 +1225,18 @@ PHP_METHOD(SplPriorityQueue, __unserialize)
12111225 RETURN_THROWS ();
12121226 }
12131227
1214- spl_heap_unserialize_internal_state (Z_ARRVAL_P (state ), intern , ZEND_THIS , true);
1228+ if (spl_heap_unserialize_internal_state (Z_ARRVAL_P (state ), intern , ZEND_THIS , true) != SUCCESS ) {
1229+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1230+ RETURN_THROWS ();
1231+ }
1232+
12151233 if (EG (exception )) {
12161234 RETURN_THROWS ();
12171235 }
1236+
1237+ if (UNEXPECTED (spl_heap_consistency_validations (intern , false) != SUCCESS )) {
1238+ RETURN_THROWS ();
1239+ }
12181240}
12191241
12201242PHP_METHOD (SplHeap , __serialize )
@@ -1228,6 +1250,11 @@ PHP_METHOD(SplHeap, __serialize)
12281250 RETURN_THROWS ();
12291251 }
12301252
1253+ if (intern -> heap -> flags & SPL_HEAP_WRITE_LOCKED ) {
1254+ zend_throw_exception (spl_ce_RuntimeException , "Cannot serialize heap while it is being modified." , 0 );
1255+ RETURN_THROWS ();
1256+ }
1257+
12311258 array_init (return_value );
12321259
12331260 ZVAL_ARR (& props , zend_std_get_properties (& intern -> std ));
@@ -1270,10 +1297,18 @@ PHP_METHOD(SplHeap, __unserialize)
12701297 RETURN_THROWS ();
12711298 }
12721299
1273- spl_heap_unserialize_internal_state (Z_ARRVAL_P (state ), intern , ZEND_THIS , false);
1300+ if (spl_heap_unserialize_internal_state (Z_ARRVAL_P (state ), intern , ZEND_THIS , false) != SUCCESS ) {
1301+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1302+ RETURN_THROWS ();
1303+ }
1304+
12741305 if (EG (exception )) {
12751306 RETURN_THROWS ();
12761307 }
1308+
1309+ if (UNEXPECTED (spl_heap_consistency_validations (intern , false) != SUCCESS )) {
1310+ RETURN_THROWS ();
1311+ }
12771312}
12781313
12791314/* iterator handler table */
0 commit comments