From 02a1ab807191891e888c19b4b8b54de33dba081b Mon Sep 17 00:00:00 2001 From: Eugene Shamis Date: Fri, 1 Nov 2024 15:33:07 -0400 Subject: [PATCH 1/3] Replace checked slice indexing by unchecked to support panic-free code Fixes #126425 Replace the potentially panicking `[]` indexing with `get_unchecked()` to prevent linking with panic-related code. --- library/core/src/fmt/num.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index f1540803f97..aaf429bac8e 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -88,7 +88,9 @@ fn fmt_int(&self, mut x: T, f: &mut fmt::Formatter<'_>) -> fmt::R }; } } - let buf = &buf[curr..]; + // SAFETY: `curr` is initialized to `buf.len()` and is only decremented, + // so it is always in bounds. + let buf = unsafe { buf.get_unchecked(curr..) }; // SAFETY: The only chars in `buf` are created by `Self::digit` which are assumed to be // valid UTF-8 let buf = unsafe { From 37f48da802f2f76e210c82731fc7483d7ae96bfd Mon Sep 17 00:00:00 2001 From: Eugene Shamis Date: Mon, 4 Nov 2024 09:50:08 -0500 Subject: [PATCH 2/3] Updated SAFETY comment to address underflow --- library/core/src/fmt/num.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index aaf429bac8e..5a5c4d60074 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -88,8 +88,9 @@ fn fmt_int(&self, mut x: T, f: &mut fmt::Formatter<'_>) -> fmt::R }; } } - // SAFETY: `curr` is initialized to `buf.len()` and is only decremented, - // so it is always in bounds. + // SAFETY: `curr` is initialized to `buf.len()` and is only decremented, so it can't overflow. It is + // decremented exactly once for each digit. Since u128 is the widest fixed width integer format dupported, + // the maximum number of digits (bits) is 128 for base-2, so `curr` won't underflow as well. let buf = unsafe { buf.get_unchecked(curr..) }; // SAFETY: The only chars in `buf` are created by `Self::digit` which are assumed to be // valid UTF-8 From 65d8f1b8bfe79a3b88048ce24629456b007f8f4a Mon Sep 17 00:00:00 2001 From: Eugene Shamis Date: Mon, 4 Nov 2024 12:43:57 -0500 Subject: [PATCH 3/3] Fixed typo, rebased --- library/core/src/fmt/num.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index 5a5c4d60074..d43f25d9fd1 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -89,7 +89,7 @@ fn fmt_int(&self, mut x: T, f: &mut fmt::Formatter<'_>) -> fmt::R } } // SAFETY: `curr` is initialized to `buf.len()` and is only decremented, so it can't overflow. It is - // decremented exactly once for each digit. Since u128 is the widest fixed width integer format dupported, + // decremented exactly once for each digit. Since u128 is the widest fixed width integer format supported, // the maximum number of digits (bits) is 128 for base-2, so `curr` won't underflow as well. let buf = unsafe { buf.get_unchecked(curr..) }; // SAFETY: The only chars in `buf` are created by `Self::digit` which are assumed to be