Skip to content
Merged
8 changes: 7 additions & 1 deletion src/uu/sort/src/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2655,7 +2655,13 @@ fn compare_by<'a>(
if global_settings.precomputed.fast_locale_collation {
let a_key = a_line_data.collation_key(a.index);
let b_key = b_line_data.collation_key(b.index);
let cmp = a_key.cmp(b_key);
let mut cmp = a_key.cmp(b_key);
// If collation keys are equal, fall back to lexicographic comparison
// This can be the case for inputs like `01` and `0_1`, which have equal keys
if cmp == Ordering::Equal {
// Reversing the order to match sort's sorting behaviour
cmp = b.line.cmp(a.line);
}
return if global_settings.reverse {
cmp.reverse()
} else {
Expand Down
21 changes: 21 additions & 0 deletions tests/by-util/test_sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2960,4 +2960,25 @@ e f 5436 down data path1 path2 path3 path4 path5\n";
.stdout_is(input);
}

#[test]
fn test_consistent_sorting_with_i18n_collate() {
// Regression test for issue #11980
// Lexicographic fallback sorting for equal sorting keys for 01 and 0_1
let expected_output = "0_1\n0_1\n01\n01\n02\n02\n";
new_ucmd!()
.env("LC_ALL", "en_US.UTF-8")
.arg("fix_i18n_collate_inconsistency_1.txt")
.arg("fix_i18n_collate_inconsistency_2.txt")
.succeeds()
.stdout_is(expected_output);

let expected_output = "01\n01\n02\n02\n0_1\n0_1\n";
new_ucmd!()
.env("LC_ALL", "C")
.arg("fix_i18n_collate_inconsistency_1.txt")
Comment thread
ksgk1 marked this conversation as resolved.
.arg("fix_i18n_collate_inconsistency_2.txt")
.succeeds()
.stdout_is(expected_output);
}

/* spell-checker: enable */
3 changes: 3 additions & 0 deletions tests/fixtures/sort/fix_i18n_collate_inconsistency_1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
01
0_1
02
3 changes: 3 additions & 0 deletions tests/fixtures/sort/fix_i18n_collate_inconsistency_2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0_1
01
02
Loading