fix(bls): sort numeric version segments newer than letters

When only one version had a digit at the current position, both sides
were parsed as numbers and the letter side read as 0. "0" then compared
equal to "a" and the result depended on what followed. Per the
specification, the side with digits is newer.
This commit is contained in:
alex authored and Alex Zenla committed 2026-09-26 18:58:54 -07:00
1 parent 9d6d88c5e0
commit 29e405f11f
1 file changed
+15 -2
+15 -2
View File
@@ -294,9 +294,14 @@ pub fn compare_versions(a: &str, b: &str) -> Ordering {
handle_single_char!(ca, cb, a_chars, b_chars, '.'); handle_single_char!(ca, cb, a_chars, b_chars, '.');
// Handle digits with numerical comparison. // Handle digits with numerical comparison.
// We key off of the A character being a digit intentionally as we presume // If only one string has digits at this position, that string is newer.
// this indicates it will be the same at this position.
if ca.is_ascii_digit() || cb.is_ascii_digit() { if ca.is_ascii_digit() || cb.is_ascii_digit() {
if !ca.is_ascii_digit() {
return Ordering::Less;
}
if !cb.is_ascii_digit() {
return Ordering::Greater;
}
let result = compare_numeric(&mut a_chars, &mut b_chars); let result = compare_numeric(&mut a_chars, &mut b_chars);
if result != Ordering::Equal { if result != Ordering::Equal {
return result; return result;
@@ -719,6 +724,14 @@ efi /EFI/fedora/shimx64.efi
assert_eq!(compare_versions("", "1"), Ordering::Less); assert_eq!(compare_versions("", "1"), Ordering::Less);
} }
#[test]
fn digits_are_newer_than_letters() {
assert_eq!(compare_versions("0", "a"), Ordering::Greater);
assert_eq!(compare_versions("a", "0"), Ordering::Less);
assert_eq!(compare_versions("1.0", "1.a"), Ordering::Greater);
assert_eq!(compare_versions("1.a", "1.0"), Ordering::Less);
}
#[test] #[test]
fn optional_both_none_equal() { fn optional_both_none_equal() {
assert_eq!(compare_versions_optional(None, None), Ordering::Equal); assert_eq!(compare_versions_optional(None, None), Ordering::Equal);