diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index f2dd2444e2392..ffd02e2f4f6e5 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -294,7 +294,11 @@ fn rc_inner_layout_for_value_layout(layout: Layout) -> Layout { // Previously, layout was calculated on the expression // `&*(ptr as *const RcInner)`, but this created a misaligned // reference (see #54908). - Layout::new::>().extend(layout).unwrap().0.pad_to_align() + Layout::new::>() + .extend(layout) + .unwrap_or_else(|_| panic!("capacity overflow")) + .0 + .pad_to_align() } /// A single-threaded reference-counting pointer. 'Rc' stands for 'Reference diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 9c6b43ba6c8ee..4f86d6c596050 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -406,7 +406,11 @@ fn arcinner_layout_for_value_layout(layout: Layout) -> Layout { // Previously, layout was calculated on the expression // `&*(ptr as *const ArcInner)`, but this created a misaligned // reference (see #54908). - Layout::new::>().extend(layout).unwrap().0.pad_to_align() + Layout::new::>() + .extend(layout) + .unwrap_or_else(|_| panic!("capacity overflow")) + .0 + .pad_to_align() } unsafe impl Send for ArcInner {} diff --git a/library/alloctests/tests/arc.rs b/library/alloctests/tests/arc.rs index 0a7f9e82a9c4b..3cec3c962ab06 100644 --- a/library/alloctests/tests/arc.rs +++ b/library/alloctests/tests/arc.rs @@ -390,3 +390,9 @@ fn issue_155746_make_mut_panic_safety() { assert_eq!(*arc, [[1]]); assert_eq!(Arc::strong_count(&arc), 1); // if this is 0, we have a UAF! } + +#[test] +#[should_panic = "capacity overflow"] +fn new_uninit_slice_capacity_overflow() { + let _ = Arc::<[u8]>::new_uninit_slice(isize::MAX as usize); +} diff --git a/library/alloctests/tests/rc.rs b/library/alloctests/tests/rc.rs index 698585e94f8a6..0009d6fbc7058 100644 --- a/library/alloctests/tests/rc.rs +++ b/library/alloctests/tests/rc.rs @@ -967,3 +967,11 @@ fn issue_158875_make_mut_dont_leak_allocator() { assert_eq!(Rc::strong_count(&alloc), 1); // if this is >1, we have a memory leak! } + +#[test] +#[should_panic = "capacity overflow"] +fn new_uninit_slice_capacity_overflow() { + // header + payload layout exceeds isize::MAX -> "capacity overflow", not + // an unwrapped LayoutError. Regression test for #136797. + let _ = Rc::<[u8]>::new_uninit_slice(isize::MAX as usize); +}