mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Fix GH-9296: ksort
behaves incorrectly on arrays with mixed keys
The comparator function used at ksort in SORT_REGULAR mode need to be consistent with basic comparison rules. These rules were changed in PHP-8.0 for numeric strings, but comparator used at ksort kept the old behaviour. It leads to inconsistent situations, when after ksort the first key is GREATER than some of the next ones by according to the basic comparison operators. Closes GH-9293.
This commit is contained in:
parent
962d8bd0b6
commit
cd1aed8edd
8 changed files with 55 additions and 51 deletions
|
@ -166,40 +166,25 @@ static zend_never_inline ZEND_COLD int stable_sort_fallback(Bucket *a, Bucket *b
|
|||
|
||||
static zend_always_inline int php_array_key_compare_unstable_i(Bucket *f, Bucket *s) /* {{{ */
|
||||
{
|
||||
zend_uchar t;
|
||||
zend_long l1, l2;
|
||||
double d;
|
||||
zval first;
|
||||
zval second;
|
||||
|
||||
if (f->key == NULL) {
|
||||
if (s->key == NULL) {
|
||||
return (zend_long)f->h > (zend_long)s->h ? 1 : -1;
|
||||
} else {
|
||||
l1 = (zend_long)f->h;
|
||||
t = is_numeric_string(s->key->val, s->key->len, &l2, &d, 1);
|
||||
if (t == IS_LONG) {
|
||||
/* pass */
|
||||
} else if (t == IS_DOUBLE) {
|
||||
return ZEND_NORMALIZE_BOOL((double)l1 - d);
|
||||
} else {
|
||||
l2 = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (s->key) {
|
||||
return zendi_smart_strcmp(f->key, s->key);
|
||||
} else {
|
||||
l2 = (zend_long)s->h;
|
||||
t = is_numeric_string(f->key->val, f->key->len, &l1, &d, 1);
|
||||
if (t == IS_LONG) {
|
||||
/* pass */
|
||||
} else if (t == IS_DOUBLE) {
|
||||
return ZEND_NORMALIZE_BOOL(d - (double)l2);
|
||||
} else {
|
||||
l1 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ZEND_NORMALIZE_BOOL(l1 - l2);
|
||||
if (f->key == NULL && s->key == NULL) {
|
||||
return (zend_long)f->h > (zend_long)s->h ? 1 : -1;
|
||||
} else if (f->key && s->key) {
|
||||
return zendi_smart_strcmp(f->key, s->key);
|
||||
}
|
||||
if (f->key) {
|
||||
ZVAL_STR(&first, f->key);
|
||||
} else {
|
||||
ZVAL_LONG(&first, f->h);
|
||||
}
|
||||
if (s->key) {
|
||||
ZVAL_STR(&second, s->key);
|
||||
} else {
|
||||
ZVAL_LONG(&second, s->h);
|
||||
}
|
||||
return zend_compare(&first, &second);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue