Skip to content

Commit 2bb7c10

Browse files
authored
Fix stability of compare_strings_ascii (#823)
Closes #822
1 parent e5f0c45 commit 2bb7c10

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

crates/edit/src/icu.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -813,13 +813,15 @@ fn compare_strings_ascii(a: &[u8], b: &[u8]) -> Ordering {
813813
// case-insensitive equal, because then we use that as a fallback.
814814
while let Some((&a, &b)) = iter.next() {
815815
if a != b {
816-
let mut order = a.cmp(&b);
817816
let la = a.to_ascii_lowercase();
818817
let lb = b.to_ascii_lowercase();
818+
let mut order = la.cmp(&lb);
819+
820+
if order == Ordering::Equal {
821+
// High weight: Find the first character which differs case-insensitively.
822+
// Otherwise, it falls back to (or rather: defaults to) a case-sensitive comparison.
823+
order = a.cmp(&b);
819824

820-
if la == lb {
821-
// High weight: Find the first character which
822-
// differs case-insensitively.
823825
for (a, b) in iter {
824826
let la = a.to_ascii_lowercase();
825827
let lb = b.to_ascii_lowercase();
@@ -1378,6 +1380,9 @@ mod tests {
13781380
assert_eq!(compare_strings_ascii(b"abcd", b"abc"), Ordering::Greater);
13791381
// Same chars, different cases - 1st char wins
13801382
assert_eq!(compare_strings_ascii(b"AbC", b"aBc"), Ordering::Less);
1383+
// Different chars, different cases
1384+
assert_eq!(compare_strings_ascii(b"a", b"B"), Ordering::Less);
1385+
assert_eq!(compare_strings_ascii(b"B", b"a"), Ordering::Greater);
13811386
// Different chars, different cases - 2nd char wins, because it differs
13821387
assert_eq!(compare_strings_ascii(b"hallo", b"Hello"), Ordering::Less);
13831388
assert_eq!(compare_strings_ascii(b"Hello", b"hallo"), Ordering::Greater);

0 commit comments

Comments
 (0)