Skip to content

Commit 086ee3f

Browse files
authored
Merge pull request Rust-SDL2#1098 from waych/fix_audio
Bounce through SDL2 heap in AudioCVT::convert
2 parents 8bae639 + 8dcc0d8 commit 086ee3f

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

src/sdl2/audio.rs

+21-11
Original file line numberDiff line numberDiff line change
@@ -1010,29 +1010,39 @@ impl AudioCVT {
10101010
//! Certain conversions may cause buffer overflows. See AngryLawyer/rust-sdl2 issue #270.
10111011
unsafe {
10121012
if self.raw.needed != 0 {
1013+
use std::convert::TryInto;
1014+
use std::slice::from_raw_parts_mut;
1015+
10131016
let mut raw = self.raw;
10141017

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...
10181020
let dst_size = self.capacity(src.len());
1019-
let needed = dst_size - src.len();
1020-
src.reserve_exact(needed);
10211021

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+
10241032
let ret = sys::SDL_ConvertAudio(&mut raw);
10251033
// There's no reason for SDL_ConvertAudio to fail.
10261034
// The only time it can fail is if buf is NULL, which it never is.
10271035
if ret != 0 {
10281036
panic!("{}", get_error())
10291037
}
10301038

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 _);
10341045

1035-
src.set_len(raw.len_cvt as usize);
10361046
src
10371047
} else {
10381048
// The buffer remains unmodified

0 commit comments

Comments
 (0)