From a924304d27b162747df49899bf301bd0e4120f2c Mon Sep 17 00:00:00 2001 From: Jeffrey Vo Date: Fri, 30 Jan 2026 01:39:39 +0900 Subject: [PATCH] Mark `BufferBuilder::new_from_buffer` as unsafe (#9292) # Which issue does this PR close? - Closes #9287 # Rationale for this change As identified by the issue, it is possible to use safe APIs to produce an unaligned buffer in `BufferBuilder`. # What changes are included in this PR? Mark `BufferBuilder::new_from_buffer` as unsafe since there are alignment invariants that must be upheld to use it correctly. Also fix some docstrings. # Are these changes tested? Marking API unsafe only. # Are there any user-facing changes? Yes. --- arrow-buffer/src/builder/mod.rs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/arrow-buffer/src/builder/mod.rs b/arrow-buffer/src/builder/mod.rs index abe510bdabc6..e0e41e2576f2 100644 --- a/arrow-buffer/src/builder/mod.rs +++ b/arrow-buffer/src/builder/mod.rs @@ -70,7 +70,6 @@ impl BufferBuilder { /// /// ``` /// # use arrow_buffer::builder::BufferBuilder; - /// /// let mut builder = BufferBuilder::::new(10); /// /// assert!(builder.capacity() >= 10); @@ -87,7 +86,11 @@ impl BufferBuilder { } /// Creates a new builder from a [`MutableBuffer`] - pub fn new_from_buffer(buffer: MutableBuffer) -> Self { + /// + /// # Safety + /// + /// - `buffer` bytes must be aligned to type `T` + pub unsafe fn new_from_buffer(buffer: MutableBuffer) -> Self { let buffer_len = buffer.len(); Self { buffer, @@ -102,7 +105,6 @@ impl BufferBuilder { /// /// ``` /// # use arrow_buffer::builder::BufferBuilder; - /// /// let mut builder = BufferBuilder::::new(10); /// builder.append(42); /// @@ -118,7 +120,6 @@ impl BufferBuilder { /// /// ``` /// # use arrow_buffer::builder::BufferBuilder; - /// /// let mut builder = BufferBuilder::::new(10); /// builder.append(42); /// @@ -149,7 +150,6 @@ impl BufferBuilder { /// /// ``` /// # use arrow_buffer::builder::BufferBuilder; - /// /// let mut builder = BufferBuilder::::new(10); /// builder.advance(2); /// @@ -167,7 +167,6 @@ impl BufferBuilder { /// /// ``` /// # use arrow_buffer::builder::BufferBuilder; - /// /// let mut builder = BufferBuilder::::new(10); /// builder.reserve(10); /// @@ -185,7 +184,6 @@ impl BufferBuilder { /// /// ``` /// # use arrow_buffer::builder::BufferBuilder; - /// /// let mut builder = BufferBuilder::::new(10); /// builder.append(42); /// @@ -205,7 +203,6 @@ impl BufferBuilder { /// /// ``` /// # use arrow_buffer::builder::BufferBuilder; - /// /// let mut builder = BufferBuilder::::new(10); /// builder.append_n(10, 42); /// @@ -223,12 +220,12 @@ impl BufferBuilder { /// /// ``` /// # use arrow_buffer::builder::BufferBuilder; - /// /// let mut builder = BufferBuilder::::new(10); /// builder.append_n_zeroed(3); /// /// assert_eq!(builder.len(), 3); /// assert_eq!(builder.as_slice(), &[0, 0, 0]) + /// ``` #[inline] pub fn append_n_zeroed(&mut self, n: usize) { self.buffer.extend_zeros(n * std::mem::size_of::()); @@ -241,7 +238,6 @@ impl BufferBuilder { /// /// ``` /// # use arrow_buffer::builder::BufferBuilder; - /// /// let mut builder = BufferBuilder::::new(10); /// builder.append_slice(&[42, 44, 46]); /// @@ -257,7 +253,6 @@ impl BufferBuilder { /// /// ``` /// # use arrow_buffer::builder::BufferBuilder; - /// /// let mut builder = BufferBuilder::::new(10); /// builder.append(1.3); /// builder.append_n(2, 2.3); @@ -280,7 +275,6 @@ impl BufferBuilder { /// /// ``` /// # use arrow_buffer::builder::BufferBuilder; - /// /// let mut builder = BufferBuilder::::new(10); /// /// builder.append_slice(&[1., 2., 3.4]); @@ -307,7 +301,6 @@ impl BufferBuilder { /// /// ``` /// # use arrow_buffer::builder::BufferBuilder; - /// /// let mut builder = BufferBuilder::::new(10); /// /// builder.append_slice(&[42, 44, 46]); @@ -377,7 +370,10 @@ impl Extend for BufferBuilder { impl From> for BufferBuilder { fn from(value: Vec) -> Self { - Self::new_from_buffer(MutableBuffer::from(value)) + let buffer = MutableBuffer::from(value); + // SAFETY + // - buffer is aligned to T + unsafe { Self::new_from_buffer(buffer) } } }