mirror of
https://github.com/php/php-src.git
synced 2026-03-24 08:12:21 +01:00
Improve __unserialize() hardening for SplHeap/SplPriorityQueue
It was possible to make the heap accept unserialize data when the heap was corrupted or under modification. This adds the necessary check to prevent that from happening. Also, the exception check at the bottom is pointless, spl_heap_unserialize_internal_state() already returns FAILURE on exception. If it *is* necessary, it should be documented why. Closes GH-20109.
This commit is contained in:
1
NEWS
1
NEWS
@@ -19,6 +19,7 @@ PHP NEWS
|
||||
- SPL:
|
||||
. Fixed bug GH-20101 (SplHeap/SplPriorityQueue serialization
|
||||
exposes INDIRECTs). (nielsdos)
|
||||
. Improve __unserialize() hardening for SplHeap/SplPriorityQueue. (nielsdos)
|
||||
|
||||
09 Oct 2025, PHP 8.5.0RC2
|
||||
|
||||
|
||||
@@ -1257,6 +1257,10 @@ PHP_METHOD(SplHeap, __unserialize)
|
||||
Z_PARAM_ARRAY_HT(data)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (UNEXPECTED(spl_heap_consistency_validations(intern, true) != SUCCESS)) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (zend_hash_num_elements(data) != 2) {
|
||||
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name));
|
||||
RETURN_THROWS();
|
||||
@@ -1285,10 +1289,6 @@ PHP_METHOD(SplHeap, __unserialize)
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (EG(exception)) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (UNEXPECTED(spl_heap_consistency_validations(intern, false) != SUCCESS)) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
SplHeap should not accept unserialize data when it is corrupted or under modification
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class MyHeap extends SplMaxHeap {
|
||||
public function compare($a, $b): int {
|
||||
global $array;
|
||||
static $counter = 0;
|
||||
if ($counter++ === 0)
|
||||
$this->__unserialize($array);
|
||||
return $a < $b ? -1 : ($a == $b ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
$heap = new SplMaxHeap;
|
||||
$heap->insert(1);
|
||||
$array = $heap->__serialize();
|
||||
|
||||
$heap = new MyHeap;
|
||||
$heap->insert(0);
|
||||
try {
|
||||
$heap->insert(2);
|
||||
} catch (RuntimeException $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Heap cannot be changed when it is already being modified.
|
||||
Reference in New Issue
Block a user