Fix #20262: SORT_REGULAR transitivity violation with mixed numeric/non-numeric strings #20305
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
array_unique()withSORT_REGULARwas missing duplicates, andsort()was incorrectly ordering equal values due to a transitivity violation in string comparison.When comparing numeric strings (like
'5','10') with non-numeric strings (like'3A'), the comparison function fell back to lexicographic comparison, which violated transitivity:'5' < '10'(numeric: 5 < 10)'10' < '3A'(lexicographic: '1' < '3')'5' > '3A'(lexicographic: '5' > '3') Violates transitivityThis caused equal values to not be grouped together in sorted arrays.
Solution
Fixed
php_array_data_compare_unstable_i()inext/standard/array.cto consistently order non-numeric strings before numeric strings when one is numeric and one is not, ensuring transitivity for all SORT_REGULAR operations.Important: This fix does not change the behavior of comparison operators like
<=>, maintaining backward compatibility. The fix only affects sorting and array operations with SORT_REGULAR, similar to how enum comparison is handled specially for sorting. This fix also does not correct the underlying issue as it affects object and nested arrays.Test Updates Required
The following tests need their expected output updated to reflect the new transitive sort order:
ext/standard/tests/array/sort/array_multisort_basic1.phptext/standard/tests/array/sort/array_multisort_variation5.phptext/standard/tests/array/sort/array_multisort_variation6.phptTests marked as "(OK to fail as result is unpredictable)" (arsort_variation11, asort_variation11, sort_variation11, rsort_variation11) should maybe still be updated for consistency.