Skip to content

Commit f09ff7c

Browse files
committed
Fix ksort(..., SORT_REGULAR) behaviour on arrays with numeric and string 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.
1 parent 8aeae63 commit f09ff7c

File tree

1 file changed

+14
-34
lines changed

1 file changed

+14
-34
lines changed

ext/standard/array.c

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -166,40 +166,20 @@ static zend_never_inline ZEND_COLD int stable_sort_fallback(Bucket *a, Bucket *b
166166

167167
static zend_always_inline int php_array_key_compare_unstable_i(Bucket *f, Bucket *s) /* {{{ */
168168
{
169-
zend_uchar t;
170-
zend_long l1, l2;
171-
double d;
172-
173-
if (f->key == NULL) {
174-
if (s->key == NULL) {
175-
return (zend_long)f->h > (zend_long)s->h ? 1 : -1;
176-
} else {
177-
l1 = (zend_long)f->h;
178-
t = is_numeric_string(s->key->val, s->key->len, &l2, &d, 1);
179-
if (t == IS_LONG) {
180-
/* pass */
181-
} else if (t == IS_DOUBLE) {
182-
return ZEND_NORMALIZE_BOOL((double)l1 - d);
183-
} else {
184-
l2 = 0;
185-
}
186-
}
187-
} else {
188-
if (s->key) {
189-
return zendi_smart_strcmp(f->key, s->key);
190-
} else {
191-
l2 = (zend_long)s->h;
192-
t = is_numeric_string(f->key->val, f->key->len, &l1, &d, 1);
193-
if (t == IS_LONG) {
194-
/* pass */
195-
} else if (t == IS_DOUBLE) {
196-
return ZEND_NORMALIZE_BOOL(d - (double)l2);
197-
} else {
198-
l1 = 0;
199-
}
200-
}
201-
}
202-
return ZEND_NORMALIZE_BOOL(l1 - l2);
169+
zval first;
170+
zval second;
171+
172+
if (f->key) {
173+
ZVAL_STR(&first, f->key);
174+
} else {
175+
ZVAL_LONG(&first, f->h);
176+
}
177+
if (s->key) {
178+
ZVAL_STR(&second, s->key);
179+
} else {
180+
ZVAL_LONG(&second, s->h);
181+
}
182+
return zend_compare(&first, &second);
203183
}
204184
/* }}} */
205185

0 commit comments

Comments
 (0)