File tree 2 files changed +26
-1
lines changed
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> {
1041
1041
let mut cur = ptr. add ( num_added) ;
1042
1042
if num_added >= lower_size_bound {
1043
1043
// 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.
1044
1051
self . reserve ( 1 ) ;
1052
+
1045
1053
let start = self . as_mut_ptr ( ) ;
1046
1054
ptr = start. add ( index) ;
1047
1055
cur = ptr. add ( num_added) ;
1048
1056
ptr:: copy ( cur, cur. add ( 1 ) , old_len - index) ;
1049
1057
1058
+ // Restore the guard.
1059
+ self . set_len ( 0 ) ;
1050
1060
guard. start = start;
1051
- guard. len += 1 ;
1061
+ guard. len = guard_len + 1 ;
1052
1062
guard. skip . end += 1 ;
1053
1063
}
1054
1064
ptr:: write ( cur, element) ;
Original file line number Diff line number Diff line change @@ -905,3 +905,18 @@ fn empty_macro() {
905
905
fn zero_size_items ( ) {
906
906
SmallVec :: < [ ( ) ; 0 ] > :: new ( ) . push ( ( ) ) ;
907
907
}
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