Skip to content

Commit 04bb7cd

Browse files
Fix GH-14402: Additional safety checks
1 parent 5f5c0d9 commit 04bb7cd

File tree

3 files changed

+17
-30
lines changed

3 files changed

+17
-30
lines changed

ext/spl/spl_heap.c

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,14 +1075,6 @@ PHP_METHOD(SplPriorityQueue, __debugInfo)
10751075
RETURN_ARR(spl_heap_object_get_debug_info(spl_ce_SplPriorityQueue, Z_OBJ_P(ZEND_THIS)));
10761076
} /* }}} */
10771077

1078-
static void spl_heap_serialize_properties(zval *return_value, spl_heap_object *intern)
1079-
{
1080-
HashTable *props = zend_std_get_properties(&intern->std);
1081-
1082-
ZVAL_ARR(return_value, props);
1083-
GC_ADDREF(props);
1084-
}
1085-
10861078
static void spl_heap_serialize_internal_state(zval *return_value, spl_heap_object *intern, bool is_pqueue)
10871079
{
10881080
zval heap_elements;
@@ -1113,16 +1105,6 @@ static void spl_heap_serialize_internal_state(zval *return_value, spl_heap_objec
11131105
add_assoc_zval(return_value, "heap_elements", &heap_elements);
11141106
}
11151107

1116-
static void spl_heap_unserialize_properties(HashTable *props_ht, spl_heap_object *intern)
1117-
{
1118-
object_properties_load(&intern->std, props_ht);
1119-
if (!EG(exception)) {
1120-
return;
1121-
}
1122-
1123-
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
1124-
}
1125-
11261108
static void spl_heap_unserialize_internal_state(HashTable *state_ht, spl_heap_object *intern, zval *this_ptr, bool is_pqueue)
11271109
{
11281110
zval *flags_val = zend_hash_str_find(state_ht, "flags", strlen("flags"));
@@ -1132,7 +1114,7 @@ static void spl_heap_unserialize_internal_state(HashTable *state_ht, spl_heap_ob
11321114
}
11331115

11341116
zend_long flags_value = Z_LVAL_P(flags_val);
1135-
1117+
11361118
if (is_pqueue) {
11371119
flags_value &= SPL_PQUEUE_EXTR_MASK;
11381120
if (!flags_value) {
@@ -1148,27 +1130,28 @@ static void spl_heap_unserialize_internal_state(HashTable *state_ht, spl_heap_ob
11481130
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
11491131
return;
11501132
}
1151-
1133+
11521134
if (Z_TYPE_P(heap_elements) != IS_ARRAY) {
11531135
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
11541136
return;
11551137
}
1156-
1138+
11571139
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(heap_elements), zval *val) {
11581140
if (is_pqueue) {
1159-
if (Z_TYPE_P(val) != IS_ARRAY) {
1141+
/* PriorityQueue elements are serialized as arrays with 'data' and 'priority' keys */
1142+
if (Z_TYPE_P(val) != IS_ARRAY || zend_hash_num_elements(Z_ARRVAL_P(val)) != 2) {
11601143
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
11611144
return;
11621145
}
1163-
1146+
11641147
zval *data_val = zend_hash_str_find(Z_ARRVAL_P(val), "data", strlen("data") );
11651148
zval *priority_val = zend_hash_str_find(Z_ARRVAL_P(val), "priority", strlen("priority"));
1166-
1149+
11671150
if (!data_val || !priority_val) {
11681151
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
11691152
return;
11701153
}
1171-
1154+
11721155
spl_pqueue_elem elem;
11731156
ZVAL_COPY(&elem.data, data_val);
11741157
ZVAL_COPY(&elem.priority, priority_val);
@@ -1193,7 +1176,8 @@ PHP_METHOD(SplPriorityQueue, __serialize)
11931176

11941177
array_init(return_value);
11951178

1196-
spl_heap_serialize_properties(&props, intern);
1179+
ZVAL_ARR(&props, zend_std_get_properties(&intern->std));
1180+
Z_TRY_ADDREF(props);
11971181
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &props);
11981182

11991183
spl_heap_serialize_internal_state(&state, intern, true);
@@ -1220,8 +1204,9 @@ PHP_METHOD(SplPriorityQueue, __unserialize)
12201204
RETURN_THROWS();
12211205
}
12221206

1223-
spl_heap_unserialize_properties(Z_ARRVAL_P(props), intern);
1207+
object_properties_load(&intern->std, Z_ARRVAL_P(props));
12241208
if (EG(exception)) {
1209+
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
12251210
RETURN_THROWS();
12261211
}
12271212

@@ -1250,7 +1235,8 @@ PHP_METHOD(SplHeap, __serialize)
12501235

12511236
array_init(return_value);
12521237

1253-
spl_heap_serialize_properties(&props, intern);
1238+
ZVAL_ARR(&props, zend_std_get_properties(&intern->std));
1239+
Z_TRY_ADDREF(props);
12541240
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &props);
12551241

12561242
spl_heap_serialize_internal_state(&state, intern, false);
@@ -1277,8 +1263,9 @@ PHP_METHOD(SplHeap, __unserialize)
12771263
RETURN_THROWS();
12781264
}
12791265

1280-
spl_heap_unserialize_properties(Z_ARRVAL_P(props), intern);
1266+
object_properties_load(&intern->std, Z_ARRVAL_P(props));
12811267
if (EG(exception)) {
1268+
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
12821269
RETURN_THROWS();
12831270
}
12841271

ext/spl/tests/SplHeap_serialize_format.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,4 @@ object(SplPriorityQueue)#4 (3) {
128128
int(5)
129129
}
130130
}
131-
}
131+
}
Binary file not shown.

0 commit comments

Comments
 (0)