From 33628958d52c678b02fb44f7a83c1802f4772ee1 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Mon, 27 Apr 2026 21:02:19 +0200 Subject: [PATCH] Fix stability of compare_strings_ascii --- crates/edit/src/icu.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/crates/edit/src/icu.rs b/crates/edit/src/icu.rs index 3b070e5b859..4ad19923c98 100644 --- a/crates/edit/src/icu.rs +++ b/crates/edit/src/icu.rs @@ -813,13 +813,15 @@ fn compare_strings_ascii(a: &[u8], b: &[u8]) -> Ordering { // case-insensitive equal, because then we use that as a fallback. while let Some((&a, &b)) = iter.next() { if a != b { - let mut order = a.cmp(&b); let la = a.to_ascii_lowercase(); let lb = b.to_ascii_lowercase(); + let mut order = la.cmp(&lb); + + if order == Ordering::Equal { + // High weight: Find the first character which differs case-insensitively. + // Otherwise, it falls back to (or rather: defaults to) a case-sensitive comparison. + order = a.cmp(&b); - if la == lb { - // High weight: Find the first character which - // differs case-insensitively. for (a, b) in iter { let la = a.to_ascii_lowercase(); let lb = b.to_ascii_lowercase(); @@ -1378,6 +1380,9 @@ mod tests { assert_eq!(compare_strings_ascii(b"abcd", b"abc"), Ordering::Greater); // Same chars, different cases - 1st char wins assert_eq!(compare_strings_ascii(b"AbC", b"aBc"), Ordering::Less); + // Different chars, different cases + assert_eq!(compare_strings_ascii(b"a", b"B"), Ordering::Less); + assert_eq!(compare_strings_ascii(b"B", b"a"), Ordering::Greater); // Different chars, different cases - 2nd char wins, because it differs assert_eq!(compare_strings_ascii(b"hallo", b"Hello"), Ordering::Less); assert_eq!(compare_strings_ascii(b"Hello", b"hallo"), Ordering::Greater);