Skip to content

Commit ed96321

Browse files
committed
fix aliasing issues in u128 formatting code
1 parent 3478d7c commit ed96321

File tree

2 files changed

+11
-5
lines changed

2 files changed

+11
-5
lines changed

library/core/src/fmt/num.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,6 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
595595
// 2^128 is about 3*10^38, so 39 gives an extra byte of space
596596
let mut buf = [MaybeUninit::<u8>::uninit(); 39];
597597
let mut curr = buf.len() as isize;
598-
let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
599598

600599
let (n, rem) = udiv_1e19(n);
601600
parse_u64_into(rem, &mut buf, &mut curr);
@@ -606,7 +605,11 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
606605
// SAFETY: Guaranteed that we wrote at most 19 bytes, and there must be space
607606
// remaining since it has length 39
608607
unsafe {
609-
ptr::write_bytes(buf_ptr.offset(target), b'0', (curr - target) as usize);
608+
ptr::write_bytes(
609+
MaybeUninit::slice_as_mut_ptr(&mut buf).offset(target),
610+
b'0',
611+
(curr - target) as usize,
612+
);
610613
}
611614
curr = target;
612615

@@ -615,6 +618,9 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
615618
// Should this following branch be annotated with unlikely?
616619
if n != 0 {
617620
let target = (buf.len() - 38) as isize;
621+
// The raw `buf_ptr` pointer is only valid until `buf` is used the next time,
622+
// buf `buf` is not used in this scope so we are good.
623+
let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
618624
// SAFETY: At this point we wrote at most 38 bytes, pad up to that point,
619625
// There can only be at most 1 digit remaining.
620626
unsafe {
@@ -629,7 +635,7 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
629635
// UTF-8 since `DEC_DIGITS_LUT` is
630636
let buf_slice = unsafe {
631637
str::from_utf8_unchecked(slice::from_raw_parts(
632-
buf_ptr.offset(curr),
638+
MaybeUninit::slice_as_mut_ptr(&mut buf).offset(curr),
633639
buf.len() - curr as usize,
634640
))
635641
};

library/core/src/mem/maybe_uninit.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -842,13 +842,13 @@ impl<T> MaybeUninit<T> {
842842
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
843843
#[inline(always)]
844844
pub fn slice_as_ptr(this: &[MaybeUninit<T>]) -> *const T {
845-
this as *const [MaybeUninit<T>] as *const T
845+
this.as_ptr() as *const T
846846
}
847847

848848
/// Gets a mutable pointer to the first element of the array.
849849
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
850850
#[inline(always)]
851851
pub fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
852-
this as *mut [MaybeUninit<T>] as *mut T
852+
this.as_mut_ptr() as *mut T
853853
}
854854
}

0 commit comments

Comments
 (0)