@@ -1082,9 +1082,14 @@ static void spl_heap_serialize_internal_state(zval *return_value, spl_heap_objec
10821082
10831083 array_init (return_value );
10841084 add_assoc_long (return_value , "flags" , intern -> flags );
1085-
1085+
10861086 array_init_size (& heap_elements , heap_count );
10871087
1088+ if (heap_count == 0 ) {
1089+ add_assoc_zval (return_value , "heap_elements" , & heap_elements );
1090+ return ;
1091+ }
1092+
10881093 for (int heap_idx = 0 ; heap_idx < heap_count ; ++ heap_idx ) {
10891094 if (is_pqueue ) {
10901095 spl_pqueue_elem * elem = spl_heap_elem (intern -> heap , heap_idx );
@@ -1105,62 +1110,66 @@ static void spl_heap_serialize_internal_state(zval *return_value, spl_heap_objec
11051110 add_assoc_zval (return_value , "heap_elements" , & heap_elements );
11061111}
11071112
1108- static void spl_heap_unserialize_internal_state (HashTable * state_ht , spl_heap_object * intern , zval * this_ptr , bool is_pqueue )
1113+ static zend_result spl_heap_unserialize_internal_state (HashTable * state_ht , spl_heap_object * intern , zval * this_ptr , bool is_pqueue )
11091114{
11101115 zval * flags_val = zend_hash_str_find (state_ht , "flags" , strlen ("flags" ));
11111116 if (!flags_val || Z_TYPE_P (flags_val ) != IS_LONG ) {
1112- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1113- return ;
1117+ return FAILURE ;
11141118 }
11151119
11161120 zend_long flags_value = Z_LVAL_P (flags_val );
11171121
11181122 if (is_pqueue ) {
11191123 flags_value &= SPL_PQUEUE_EXTR_MASK ;
11201124 if (!flags_value ) {
1121- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1122- return ;
1125+ return FAILURE ;
11231126 }
1127+ } else if (flags_value != 0 ) { /* Regular heaps should not have user-visible flags */
1128+ return FAILURE ;
11241129 }
11251130
11261131 intern -> flags = (int ) flags_value ;
11271132
11281133 zval * heap_elements = zend_hash_str_find (state_ht , "heap_elements" , strlen ("heap_elements" ));
11291134 if (!heap_elements ) {
1130- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1131- return ;
1135+ return FAILURE ;
11321136 }
11331137
11341138 if (Z_TYPE_P (heap_elements ) != IS_ARRAY ) {
1135- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1136- return ;
1139+ return FAILURE ;
11371140 }
11381141
11391142 ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (heap_elements ), zval * val ) {
11401143 if (is_pqueue ) {
11411144 /* PriorityQueue elements are serialized as arrays with 'data' and 'priority' keys */
11421145 if (Z_TYPE_P (val ) != IS_ARRAY || zend_hash_num_elements (Z_ARRVAL_P (val )) != 2 ) {
1143- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1144- return ;
1146+ return FAILURE ;
11451147 }
11461148
11471149 zval * data_val = zend_hash_str_find (Z_ARRVAL_P (val ), "data" , strlen ("data" ) );
11481150 zval * priority_val = zend_hash_str_find (Z_ARRVAL_P (val ), "priority" , strlen ("priority" ));
11491151
11501152 if (!data_val || !priority_val ) {
1151- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1152- return ;
1153+ return FAILURE ;
11531154 }
11541155
11551156 spl_pqueue_elem elem ;
11561157 ZVAL_COPY (& elem .data , data_val );
11571158 ZVAL_COPY (& elem .priority , priority_val );
11581159 spl_ptr_heap_insert (intern -> heap , & elem , this_ptr );
1160+ if (EG (exception )) {
1161+ return FAILURE ;
1162+ }
11591163 } else {
11601164 Z_TRY_ADDREF_P (val );
11611165 spl_ptr_heap_insert (intern -> heap , val , this_ptr );
1166+ if (EG (exception )) {
1167+ return FAILURE ;
1168+ }
11621169 }
11631170 } ZEND_HASH_FOREACH_END ();
1171+
1172+ return SUCCESS ;
11641173}
11651174
11661175PHP_METHOD (SplPriorityQueue , __serialize )
@@ -1174,6 +1183,11 @@ PHP_METHOD(SplPriorityQueue, __serialize)
11741183 RETURN_THROWS ();
11751184 }
11761185
1186+ if (intern -> heap -> flags & SPL_HEAP_WRITE_LOCKED ) {
1187+ zend_throw_exception (spl_ce_RuntimeException , "Cannot serialize heap while it is being modified." , 0 );
1188+ RETURN_THROWS ();
1189+ }
1190+
11771191 array_init (return_value );
11781192
11791193 ZVAL_ARR (& props , zend_std_get_properties (& intern -> std ));
@@ -1216,10 +1230,17 @@ PHP_METHOD(SplPriorityQueue, __unserialize)
12161230 RETURN_THROWS ();
12171231 }
12181232
1219- spl_heap_unserialize_internal_state (Z_ARRVAL_P (state ), intern , ZEND_THIS , true);
1233+ if (spl_heap_unserialize_internal_state (Z_ARRVAL_P (state ), intern , ZEND_THIS , true) != SUCCESS ) {
1234+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1235+ RETURN_THROWS ();
1236+ }
12201237 if (EG (exception )) {
12211238 RETURN_THROWS ();
12221239 }
1240+
1241+ if (UNEXPECTED (spl_heap_consistency_validations (intern , false) != SUCCESS )) {
1242+ RETURN_THROWS ();
1243+ }
12231244}
12241245
12251246PHP_METHOD (SplHeap , __serialize )
@@ -1233,6 +1254,11 @@ PHP_METHOD(SplHeap, __serialize)
12331254 RETURN_THROWS ();
12341255 }
12351256
1257+ if (intern -> heap -> flags & SPL_HEAP_WRITE_LOCKED ) {
1258+ zend_throw_exception (spl_ce_RuntimeException , "Cannot serialize heap while it is being modified." , 0 );
1259+ RETURN_THROWS ();
1260+ }
1261+
12361262 array_init (return_value );
12371263
12381264 ZVAL_ARR (& props , zend_std_get_properties (& intern -> std ));
@@ -1275,10 +1301,18 @@ PHP_METHOD(SplHeap, __unserialize)
12751301 RETURN_THROWS ();
12761302 }
12771303
1278- spl_heap_unserialize_internal_state (Z_ARRVAL_P (state ), intern , ZEND_THIS , false);
1304+ if (spl_heap_unserialize_internal_state (Z_ARRVAL_P (state ), intern , ZEND_THIS , false) != SUCCESS ) {
1305+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1306+ RETURN_THROWS ();
1307+ }
1308+
12791309 if (EG (exception )) {
12801310 RETURN_THROWS ();
12811311 }
1312+
1313+ if (UNEXPECTED (spl_heap_consistency_validations (intern , false) != SUCCESS )) {
1314+ RETURN_THROWS ();
1315+ }
12821316}
12831317
12841318/* iterator handler table */
0 commit comments