File tree Expand file tree Collapse file tree 2 files changed +26
-1
lines changed Expand file tree Collapse file tree 2 files changed +26
-1
lines changed Original file line number Diff line number Diff line change @@ -1041,14 +1041,24 @@ impl<A: Array> SmallVec<A> {
10411041 let mut cur = ptr. add ( num_added) ;
10421042 if num_added >= lower_size_bound {
10431043 // Iterator provided more elements than the hint. Move trailing items again.
1044+
1045+ // `reserve` needs `len` to be accurate.
1046+ self . set_len ( old_len + num_added) ;
1047+ let guard_len = guard. len ;
1048+ guard. len = 0 ; // in case `reserve` panics, don't double-free in guard.drop().
1049+
1050+ // Grow the vector by 1.
10441051 self . reserve ( 1 ) ;
1052+
10451053 let start = self . as_mut_ptr ( ) ;
10461054 ptr = start. add ( index) ;
10471055 cur = ptr. add ( num_added) ;
10481056 ptr:: copy ( cur, cur. add ( 1 ) , old_len - index) ;
10491057
1058+ // Restore the guard.
1059+ self . set_len ( 0 ) ;
10501060 guard. start = start;
1051- guard. len += 1 ;
1061+ guard. len = guard_len + 1 ;
10521062 guard. skip . end += 1 ;
10531063 }
10541064 ptr:: write ( cur, element) ;
Original file line number Diff line number Diff line change @@ -905,3 +905,18 @@ fn empty_macro() {
905905fn zero_size_items ( ) {
906906 SmallVec :: < [ ( ) ; 0 ] > :: new ( ) . push ( ( ) ) ;
907907}
908+
909+ #[ test]
910+ fn test_insert_many_overflow ( ) {
911+ let mut v: SmallVec < [ u8 ; 0 ] > = SmallVec :: new ( ) ;
912+
913+ // Spill on heap
914+ v. push ( 123 ) ;
915+
916+ // Prepare an iterator with small lower bound
917+ let iter = ( 0u8 ..=255 ) . filter ( |n| n % 2 == 0 ) ;
918+ assert_eq ! ( iter. size_hint( ) . 0 , 0 ) ;
919+
920+ // Triggering the bug
921+ v. insert_many ( 0 , iter) ;
922+ }
You can’t perform that action at this time.
0 commit comments