mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix GH-20043: array_unique assertion failure with RC1 array causing an exception on sort
The reason this happens is because the array_unique operation happens in-place because the input array is RC1. At one point during comparison an exception is thrown which will capture the arguments in the backtrace, which will increment the refcount of the RC1 array to 2. Then a modification happens after the throw on the RC2 array causing the assertion failure. We shouldn't try continue work after an exception happened during the sort. Closes GH-20059.
This commit is contained in:
2
NEWS
2
NEWS
@@ -54,6 +54,8 @@ PHP NEWS
|
||||
. Fixed bug GH-19701 (Serialize/deserialize loses some data). (nielsdos)
|
||||
. Fixed bug GH-19801 (leaks in var_dump() and debug_zval_dump()).
|
||||
(alexandre-daubois)
|
||||
. Fixed bug GH-20043 (array_unique assertion failure with RC1 array
|
||||
causing an exception on sort). (nielsdos)
|
||||
|
||||
- Streams:
|
||||
. Fixed bug GH-19248 (Use strerror_r instead of strerror in main).
|
||||
|
||||
@@ -4900,6 +4900,11 @@ PHP_FUNCTION(array_unique)
|
||||
ZVAL_UNDEF(&arTmp[i].b.val);
|
||||
zend_sort((void *) arTmp, i, sizeof(struct bucketindex),
|
||||
(compare_func_t) cmp, (swap_func_t) array_bucketindex_swap);
|
||||
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* go through the sorted array and delete duplicates from the copy */
|
||||
lastkept = arTmp;
|
||||
for (cmpdata = arTmp + 1; Z_TYPE(cmpdata->b.val) != IS_UNDEF; cmpdata++) {
|
||||
@@ -4919,6 +4924,8 @@ PHP_FUNCTION(array_unique)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
pefree(arTmp, GC_FLAGS(Z_ARRVAL_P(array)) & IS_ARRAY_PERSISTENT);
|
||||
|
||||
if (in_place) {
|
||||
|
||||
12
ext/standard/tests/array/gh20043.phpt
Normal file
12
ext/standard/tests/array/gh20043.phpt
Normal file
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
GH-20043 (array_unique assertion failure with RC1 array causing an exception on sort)
|
||||
--FILE--
|
||||
<?php
|
||||
try {
|
||||
array_unique([new stdClass, new stdClass], SORT_STRING | SORT_FLAG_CASE);
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
Object of class stdClass could not be converted to string
|
||||
Reference in New Issue
Block a user