File tree Expand file tree Collapse file tree 7 files changed +72
-0
lines changed Expand file tree Collapse file tree 7 files changed +72
-0
lines changed Original file line number Diff line number Diff line change @@ -533,6 +533,25 @@ impl OsString {
533533 unsafe { Box :: from_raw ( rw) }
534534 }
535535
536+ /// Consumes and leaks the `OsString`, returning a mutable reference to the contents,
537+ /// `&'a mut OsStr`.
538+ ///
539+ /// The caller has free choice over the returned lifetime, including 'static.
540+ /// Indeed, this function is ideally used for data that lives for the remainder of
541+ /// the program’s life, as dropping the returned reference will cause a memory leak.
542+ ///
543+ /// It does not reallocate or shrink the `OsString`, so the leaked allocation may include
544+ /// unused capacity that is not part of the returned slice. If you want to discard excess
545+ /// capacity, call [`into_boxed_os_str`], and then [`Box::leak`] instead.
546+ /// However, keep in mind that trimming the capacity may result in a reallocation and copy.
547+ ///
548+ /// [`into_boxed_os_str`]: Self::into_boxed_os_str
549+ #[ unstable( feature = "os_string_pathbuf_leak" , issue = "125965" ) ]
550+ #[ inline]
551+ pub fn leak < ' a > ( self ) -> & ' a mut OsStr {
552+ OsStr :: from_inner_mut ( self . inner . leak ( ) )
553+ }
554+
536555 /// Part of a hack to make PathBuf::push/pop more efficient.
537556 #[ inline]
538557 pub ( crate ) fn as_mut_vec_for_path_buf ( & mut self ) -> & mut Vec < u8 > {
Original file line number Diff line number Diff line change @@ -23,6 +23,15 @@ fn test_os_string_clear() {
2323 assert_eq ! ( 0 , os_string. inner. as_inner( ) . len( ) ) ;
2424}
2525
26+ #[ test]
27+ fn test_os_string_leak ( ) {
28+ let os_string = OsString :: from ( "have a cake" ) ;
29+ let ( len, cap) = ( os_string. len ( ) , os_string. capacity ( ) ) ;
30+ let leaked = os_string. leak ( ) ;
31+ assert_eq ! ( leaked. as_encoded_bytes( ) , b"have a cake" ) ;
32+ unsafe { drop ( String :: from_raw_parts ( leaked as * mut OsStr as _ , len, cap) ) }
33+ }
34+
2635#[ test]
2736fn test_os_string_capacity ( ) {
2837 let os_string = OsString :: with_capacity ( 0 ) ;
Original file line number Diff line number Diff line change @@ -1226,6 +1226,25 @@ impl PathBuf {
12261226 self
12271227 }
12281228
1229+ /// Consumes and leaks the `PathBuf`, returning a mutable reference to the contents,
1230+ /// `&'a mut Path`.
1231+ ///
1232+ /// The caller has free choice over the returned lifetime, including 'static.
1233+ /// Indeed, this function is ideally used for data that lives for the remainder of
1234+ /// the program’s life, as dropping the returned reference will cause a memory leak.
1235+ ///
1236+ /// It does not reallocate or shrink the `PathBuf`, so the leaked allocation may include
1237+ /// unused capacity that is not part of the returned slice. If you want to discard excess
1238+ /// capacity, call [`into_boxed_path`], and then [`Box::leak`] instead.
1239+ /// However, keep in mind that trimming the capacity may result in a reallocation and copy.
1240+ ///
1241+ /// [`into_boxed_path`]: Self::into_boxed_path
1242+ #[ unstable( feature = "os_string_pathbuf_leak" , issue = "125965" ) ]
1243+ #[ inline]
1244+ pub fn leak < ' a > ( self ) -> & ' a mut Path {
1245+ Path :: from_inner_mut ( self . inner . leak ( ) )
1246+ }
1247+
12291248 /// Extends `self` with `path`.
12301249 ///
12311250 /// If `path` is absolute, it replaces the current path.
Original file line number Diff line number Diff line change @@ -126,6 +126,16 @@ fn into() {
126126 assert_eq ! ( static_cow_path, owned_cow_path) ;
127127}
128128
129+ #[ test]
130+ fn test_pathbuf_leak ( ) {
131+ let string = "/have/a/cake" . to_owned ( ) ;
132+ let ( len, cap) = ( string. len ( ) , string. capacity ( ) ) ;
133+ let buf = PathBuf :: from ( string) ;
134+ let leaked = buf. leak ( ) ;
135+ assert_eq ! ( leaked. as_os_str( ) . as_encoded_bytes( ) , b"/have/a/cake" ) ;
136+ unsafe { drop ( String :: from_raw_parts ( leaked. as_mut_os_str ( ) as * mut OsStr as _ , len, cap) ) }
137+ }
138+
129139#[ test]
130140#[ cfg( unix) ]
131141pub fn test_decompositions_unix ( ) {
Original file line number Diff line number Diff line change @@ -176,6 +176,11 @@ impl Buf {
176176 self . inner . extend_from_slice ( & s. inner )
177177 }
178178
179+ #[ inline]
180+ pub fn leak < ' a > ( self ) -> & ' a mut Slice {
181+ unsafe { mem:: transmute ( self . inner . leak ( ) ) }
182+ }
183+
179184 #[ inline]
180185 pub fn into_box ( self ) -> Box < Slice > {
181186 unsafe { mem:: transmute ( self . inner . into_boxed_slice ( ) ) }
Original file line number Diff line number Diff line change @@ -138,6 +138,11 @@ impl Buf {
138138 self . inner . shrink_to ( min_capacity)
139139 }
140140
141+ #[ inline]
142+ pub fn leak < ' a > ( self ) -> & ' a mut Slice {
143+ unsafe { mem:: transmute ( self . inner . leak ( ) ) }
144+ }
145+
141146 #[ inline]
142147 pub fn into_box ( self ) -> Box < Slice > {
143148 unsafe { mem:: transmute ( self . inner . into_box ( ) ) }
Original file line number Diff line number Diff line change @@ -325,6 +325,11 @@ impl Wtf8Buf {
325325 self . bytes . shrink_to ( min_capacity)
326326 }
327327
328+ #[ inline]
329+ pub fn leak < ' a > ( self ) -> & ' a mut Wtf8 {
330+ unsafe { Wtf8 :: from_mut_bytes_unchecked ( self . bytes . leak ( ) ) }
331+ }
332+
328333 /// Returns the number of bytes that this string buffer can hold without reallocating.
329334 #[ inline]
330335 pub fn capacity ( & self ) -> usize {
You can’t perform that action at this time.
0 commit comments