Skip to content

Commit 6a8cde7

Browse files
Fix GH-14402: Additional safety checks
1 parent 460f967 commit 6a8cde7

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
@@ -1070,14 +1070,6 @@ PHP_METHOD(SplPriorityQueue, __debugInfo)
10701070
RETURN_ARR(spl_heap_object_get_debug_info(spl_ce_SplPriorityQueue, Z_OBJ_P(ZEND_THIS)));
10711071
} /* }}} */
10721072

1073-
static void spl_heap_serialize_properties(zval *return_value, spl_heap_object *intern)
1074-
{
1075-
HashTable *props = zend_std_get_properties(&intern->std);
1076-
1077-
ZVAL_ARR(return_value, props);
1078-
GC_ADDREF(props);
1079-
}
1080-
10811073
static void spl_heap_serialize_internal_state(zval *return_value, spl_heap_object *intern, bool is_pqueue)
10821074
{
10831075
zval heap_elements;
@@ -1108,16 +1100,6 @@ static void spl_heap_serialize_internal_state(zval *return_value, spl_heap_objec
11081100
add_assoc_zval(return_value, "heap_elements", &heap_elements);
11091101
}
11101102

1111-
static void spl_heap_unserialize_properties(HashTable *props_ht, spl_heap_object *intern)
1112-
{
1113-
object_properties_load(&intern->std, props_ht);
1114-
if (!EG(exception)) {
1115-
return;
1116-
}
1117-
1118-
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
1119-
}
1120-
11211103
static void spl_heap_unserialize_internal_state(HashTable *state_ht, spl_heap_object *intern, zval *this_ptr, bool is_pqueue)
11221104
{
11231105
zval *flags_val = zend_hash_str_find(state_ht, "flags", strlen("flags"));
@@ -1127,7 +1109,7 @@ static void spl_heap_unserialize_internal_state(HashTable *state_ht, spl_heap_ob
11271109
}
11281110

11291111
zend_long flags_value = Z_LVAL_P(flags_val);
1130-
1112+
11311113
if (is_pqueue) {
11321114
flags_value &= SPL_PQUEUE_EXTR_MASK;
11331115
if (!flags_value) {
@@ -1143,27 +1125,28 @@ static void spl_heap_unserialize_internal_state(HashTable *state_ht, spl_heap_ob
11431125
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
11441126
return;
11451127
}
1146-
1128+
11471129
if (Z_TYPE_P(heap_elements) != IS_ARRAY) {
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
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(heap_elements), zval *val) {
11531135
if (is_pqueue) {
1154-
if (Z_TYPE_P(val) != IS_ARRAY) {
1136+
/* PriorityQueue elements are serialized as arrays with 'data' and 'priority' keys */
1137+
if (Z_TYPE_P(val) != IS_ARRAY || zend_hash_num_elements(Z_ARRVAL_P(val)) != 2) {
11551138
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
11561139
return;
11571140
}
1158-
1141+
11591142
zval *data_val = zend_hash_str_find(Z_ARRVAL_P(val), "data", strlen("data") );
11601143
zval *priority_val = zend_hash_str_find(Z_ARRVAL_P(val), "priority", strlen("priority"));
1161-
1144+
11621145
if (!data_val || !priority_val) {
11631146
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
11641147
return;
11651148
}
1166-
1149+
11671150
spl_pqueue_elem elem;
11681151
ZVAL_COPY(&elem.data, data_val);
11691152
ZVAL_COPY(&elem.priority, priority_val);
@@ -1188,7 +1171,8 @@ PHP_METHOD(SplPriorityQueue, __serialize)
11881171

11891172
array_init(return_value);
11901173

1191-
spl_heap_serialize_properties(&props, intern);
1174+
ZVAL_ARR(&props, zend_std_get_properties(&intern->std));
1175+
Z_TRY_ADDREF(props);
11921176
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &props);
11931177

11941178
spl_heap_serialize_internal_state(&state, intern, true);
@@ -1215,8 +1199,9 @@ PHP_METHOD(SplPriorityQueue, __unserialize)
12151199
RETURN_THROWS();
12161200
}
12171201

1218-
spl_heap_unserialize_properties(Z_ARRVAL_P(props), intern);
1202+
object_properties_load(&intern->std, Z_ARRVAL_P(props));
12191203
if (EG(exception)) {
1204+
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
12201205
RETURN_THROWS();
12211206
}
12221207

@@ -1245,7 +1230,8 @@ PHP_METHOD(SplHeap, __serialize)
12451230

12461231
array_init(return_value);
12471232

1248-
spl_heap_serialize_properties(&props, intern);
1233+
ZVAL_ARR(&props, zend_std_get_properties(&intern->std));
1234+
Z_TRY_ADDREF(props);
12491235
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &props);
12501236

12511237
spl_heap_serialize_internal_state(&state, intern, false);
@@ -1272,8 +1258,9 @@ PHP_METHOD(SplHeap, __unserialize)
12721258
RETURN_THROWS();
12731259
}
12741260

1275-
spl_heap_unserialize_properties(Z_ARRVAL_P(props), intern);
1261+
object_properties_load(&intern->std, Z_ARRVAL_P(props));
12761262
if (EG(exception)) {
1263+
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
12771264
RETURN_THROWS();
12781265
}
12791266

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+
}
7 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)