@@ -1010,29 +1010,39 @@ impl AudioCVT {
1010
1010
//! Certain conversions may cause buffer overflows. See AngryLawyer/rust-sdl2 issue #270.
1011
1011
unsafe {
1012
1012
if self . raw . needed != 0 {
1013
+ use std:: convert:: TryInto ;
1014
+ use std:: slice:: from_raw_parts_mut;
1015
+
1013
1016
let mut raw = self . raw ;
1014
1017
1015
- // calculate the size of the dst buffer
1016
- use std:: convert:: TryInto ;
1017
- raw. len = src. len ( ) . try_into ( ) . expect ( "Buffer length overflow" ) ;
1018
+ // Calculate the size of the buffer we're handing to SDL.
1019
+ // This is more a suggestion, and not really a guarantee...
1018
1020
let dst_size = self . capacity ( src. len ( ) ) ;
1019
- let needed = dst_size - src. len ( ) ;
1020
- src. reserve_exact ( needed) ;
1021
1021
1022
- // perform the conversion in place
1023
- raw. buf = src. as_mut_ptr ( ) ;
1022
+ // Bounce into SDL2 heap allocation as SDL_ConvertAudio may rewrite the pointer.
1023
+ raw. len = src. len ( ) . try_into ( ) . expect ( "Buffer length overflow" ) ;
1024
+ raw. buf = sys:: SDL_malloc ( dst_size as _ ) as * mut _ ;
1025
+ if raw. buf . is_null ( ) {
1026
+ panic ! ( "Failed SDL_malloc needed for SDL_ConvertAudio" ) ;
1027
+ }
1028
+ // raw.buf is dst_size long, but we want to copy into only the first src.len bytes.
1029
+ assert ! ( src. len( ) <= dst_size) ;
1030
+ from_raw_parts_mut ( raw. buf , src. len ( ) ) . copy_from_slice ( src. as_ref ( ) ) ;
1031
+
1024
1032
let ret = sys:: SDL_ConvertAudio ( & mut raw) ;
1025
1033
// There's no reason for SDL_ConvertAudio to fail.
1026
1034
// The only time it can fail is if buf is NULL, which it never is.
1027
1035
if ret != 0 {
1028
1036
panic ! ( "{}" , get_error( ) )
1029
1037
}
1030
1038
1031
- // return original buffer back to caller
1032
- debug_assert ! ( raw. len_cvt > 0 ) ;
1033
- debug_assert ! ( raw. len_cvt as usize <= src. capacity( ) ) ;
1039
+ // Bounce back into src, trying to re-use the same buffer.
1040
+ let outlen: usize = raw. len_cvt . try_into ( ) . expect ( "Buffer size rollover" ) ;
1041
+ debug_assert ! ( outlen <= dst_size) ;
1042
+ src. resize ( outlen, 0 ) ;
1043
+ src. copy_from_slice ( from_raw_parts_mut ( raw. buf , outlen) ) ;
1044
+ sys:: SDL_free ( raw. buf as * mut _ ) ;
1034
1045
1035
- src. set_len ( raw. len_cvt as usize ) ;
1036
1046
src
1037
1047
} else {
1038
1048
// The buffer remains unmodified
0 commit comments