mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix GH-21454: Missing write lock validation in SplHeap
Closes GH-21448.
This commit is contained in:
4
NEWS
4
NEWS
@@ -33,6 +33,10 @@ PHP NEWS
|
||||
. Fixed Set-Cookie parsing bug wrong offset while scanning attributes.
|
||||
(David Carlier)
|
||||
|
||||
- SPL:
|
||||
. Fixed bug GH-21454 (missing write lock validation in SplHeap).
|
||||
(ndossche)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug GH-20906 (Assertion failure when messing up output buffers).
|
||||
(ndossche)
|
||||
|
||||
@@ -961,7 +961,7 @@ static void spl_heap_it_move_forward(zend_object_iterator *iter) /* {{{ */
|
||||
{
|
||||
spl_heap_object *object = Z_SPLHEAP_P(&iter->data);
|
||||
|
||||
if (UNEXPECTED(spl_heap_consistency_validations(object, false) != SUCCESS)) {
|
||||
if (UNEXPECTED(spl_heap_consistency_validations(object, true) != SUCCESS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -992,6 +992,10 @@ PHP_METHOD(SplHeap, next)
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (UNEXPECTED(spl_heap_consistency_validations(intern, true) != SUCCESS)) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
spl_ptr_heap_delete_top(intern->heap, NULL, ZEND_THIS);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
34
ext/spl/tests/heap_next_write_lock.phpt
Normal file
34
ext/spl/tests/heap_next_write_lock.phpt
Normal file
@@ -0,0 +1,34 @@
|
||||
--TEST--
|
||||
SplHeap::next() write lock
|
||||
--CREDITS--
|
||||
cnitlrt
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class EvilPQ extends SplPriorityQueue {
|
||||
private bool $did = false;
|
||||
|
||||
public function compare(mixed $p1, mixed $p2): int {
|
||||
if (!$this->did) {
|
||||
$this->did = true;
|
||||
// Re-entrant write during internal heap insertion comparison.
|
||||
if (!$this->isEmpty()) {
|
||||
$this->next(); // no write-lock validation
|
||||
}
|
||||
}
|
||||
return parent::compare($p1, $p2);
|
||||
}
|
||||
}
|
||||
|
||||
$q = new EvilPQ();
|
||||
try {
|
||||
for ($i = 0; $i < 200; $i++) {
|
||||
$q->insert("d$i", 100 - $i);
|
||||
}
|
||||
} catch (RuntimeException $e) {
|
||||
echo $e::class, ": ", $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
RuntimeException: Heap cannot be changed when it is already being modified.
|
||||
Reference in New Issue
Block a user