Skip to content

Commit 5091647

Browse files
Address Arnaud's comments
1 parent 04bb7cd commit 5091647

File tree

1 file changed

+50
-16
lines changed

1 file changed

+50
-16
lines changed

ext/spl/spl_heap.c

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

11661175
PHP_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

12251246
PHP_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

Comments
 (0)