Evian-Zhang opened a new issue, #10380:
URL: https://github.com/apache/arrow-rs/issues/10380

   ### Describe the bug
   
   Split from #10281 
   
   Sources are located here:
   
   
https://github.com/apache/arrow-rs/blob/d9919194eef5ecca7f3b42726359a820825b30e6/arrow-buffer/src/builder/boolean.rs#L330-L343
   
   
https://github.com/apache/arrow-rs/blob/d9919194eef5ecca7f3b42726359a820825b30e6/arrow-buffer/src/buffer/mutable.rs#L705-L838
   
   `BooleanBufferBuilder::extend_trusted_len` will call 
`MutableBuffer::extend_bool_trusted_len`. In this function, there will be 
firstly a `set_len` (line 746), and then invokes `iter.next` to fill those 
slots. If `I::next` panics, then there will be a typical exception safety 
violation. The SAFETY requirement of these two functions are "Callers must 
ensure that `iter` reports an exact size via `size_hint`." I think maybe this 
is a little bit inaccurate, although this can implicitly indicate that 
`I::next` must never panic. Maybe we should explicitly write this requirement 
in the SAFETY documentation?
   
   
   ### To Reproduce
   
   ```rust
   use arrow_buffer::builder::BooleanBufferBuilder;
   use std::panic::{AssertUnwindSafe, catch_unwind};
   
   struct PanicIter {
       remaining: usize,
       yielded: usize,
       panic_after: usize,
   }
   
   impl Iterator for PanicIter {
       type Item = bool;
   
       fn next(&mut self) -> Option<Self::Item> {
           if self.remaining == 0 {
               return None;
           }
           self.remaining -= 1;
           self.yielded += 1;
           if self.yielded > self.panic_after {
               panic!("Issue 3: panic during iter.next() after set_len already 
ran");
           }
           Some(true)
       }
   
       fn size_hint(&self) -> (usize, Option<usize>) {
           (self.remaining, Some(self.remaining))
       }
   }
   
   fn main() {
       let mut builder = BooleanBufferBuilder::new(0);
   
       // Iterator: reports 64 items, yields 8, then panics on the 9th
       let iter = PanicIter {
           remaining: 64,
           yielded: 0,
           panic_after: 8,
       };
   
       let result = catch_unwind(AssertUnwindSafe(|| unsafe {
           builder.extend_trusted_len(iter);
       }));
   
       println!(
           "builder.len() = {} (logical len — NOT updated by 
extend_trusted_len)",
           builder.len()
       );
       println!(
           "builder.as_slice().len() = {} (internal MutableBuffer len — WAS 
expanded by set_len)",
           builder.as_slice().len()
       );
   
       let slice = builder.as_slice();
   
       println!(
           "raw bytes: {:02x?}",
           &slice[..slice.len().min(16)]
       );
   }
   ```
   
   ### Expected behavior
   
   No soundness issue happens
   
   ### Additional context
   
   _No response_


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to