File tree Expand file tree Collapse file tree 1 file changed +36
-2
lines changed Expand file tree Collapse file tree 1 file changed +36
-2
lines changed Original file line number Diff line number Diff line change @@ -780,9 +780,11 @@ impl StrV {
780
780
for item in other {
781
781
* self . ptr . as_ptr ( ) . add ( self . len ) = GString :: from ( item. as_ref ( ) ) . into_glib_ptr ( ) ;
782
782
self . len += 1 ;
783
- }
784
783
785
- * self . ptr . as_ptr ( ) . add ( self . len ) = ptr:: null_mut ( ) ;
784
+ // Add null terminator on every iteration because `as_ref`
785
+ // may panic
786
+ * self . ptr . as_ptr ( ) . add ( self . len ) = ptr:: null_mut ( ) ;
787
+ }
786
788
}
787
789
}
788
790
@@ -1813,4 +1815,36 @@ mod test {
1813
1815
// overflow
1814
1816
strv. extend_from_slice ( & [ ImplicitStr ; usize:: MAX - 3 ] ) ;
1815
1817
}
1818
+
1819
+ #[ test]
1820
+ fn test_extend_from_slice_panic_safe ( ) {
1821
+ struct MayPanic ( bool ) ;
1822
+
1823
+ impl AsRef < str > for MayPanic {
1824
+ fn as_ref ( & self ) -> & str {
1825
+ if self . 0 {
1826
+ panic ! ( "panicking as per request" ) ;
1827
+ } else {
1828
+ ""
1829
+ }
1830
+ }
1831
+ }
1832
+
1833
+ let mut strv = StrV :: from ( & [ crate :: gstr!( "" ) ; 3 ] [ ..] ) ;
1834
+ strv. clear ( ) ;
1835
+
1836
+ // Write one element and panic while getting the second element
1837
+ _ = std:: panic:: catch_unwind ( std:: panic:: AssertUnwindSafe ( || {
1838
+ strv. extend_from_slice ( & [ MayPanic ( false ) , MayPanic ( true ) ] ) ;
1839
+ } ) ) ;
1840
+
1841
+ // Check that it contains up to one element is null-terminated
1842
+ assert ! ( strv. len( ) <= 1 ) ;
1843
+ unsafe {
1844
+ for i in 0 ..strv. len ( ) {
1845
+ assert ! ( !( * strv. as_ptr( ) . add( i) ) . is_null( ) ) ;
1846
+ }
1847
+ assert ! ( ( * strv. as_ptr( ) . add( strv. len( ) ) ) . is_null( ) ) ;
1848
+ }
1849
+ }
1816
1850
}
You can’t perform that action at this time.
0 commit comments