Skip to content

Commit

Permalink
Merge pull request Rust-SDL2#1098 from waych/fix_audio
Browse files Browse the repository at this point in the history
Bounce through SDL2 heap in AudioCVT::convert
  • Loading branch information
Cobrand authored Apr 22, 2021
2 parents 8bae639 + 8dcc0d8 commit 086ee3f
Showing 1 changed file with 21 additions and 11 deletions.
32 changes: 21 additions & 11 deletions src/sdl2/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1010,29 +1010,39 @@ impl AudioCVT {
//! Certain conversions may cause buffer overflows. See AngryLawyer/rust-sdl2 issue #270.
unsafe {
if self.raw.needed != 0 {
use std::convert::TryInto;
use std::slice::from_raw_parts_mut;

let mut raw = self.raw;

// calculate the size of the dst buffer
use std::convert::TryInto;
raw.len = src.len().try_into().expect("Buffer length overflow");
// Calculate the size of the buffer we're handing to SDL.
// This is more a suggestion, and not really a guarantee...
let dst_size = self.capacity(src.len());
let needed = dst_size - src.len();
src.reserve_exact(needed);

// perform the conversion in place
raw.buf = src.as_mut_ptr();
// Bounce into SDL2 heap allocation as SDL_ConvertAudio may rewrite the pointer.
raw.len = src.len().try_into().expect("Buffer length overflow");
raw.buf = sys::SDL_malloc(dst_size as _) as *mut _;
if raw.buf.is_null() {
panic!("Failed SDL_malloc needed for SDL_ConvertAudio");
}
// raw.buf is dst_size long, but we want to copy into only the first src.len bytes.
assert!(src.len() <= dst_size);
from_raw_parts_mut(raw.buf, src.len()).copy_from_slice(src.as_ref());

let ret = sys::SDL_ConvertAudio(&mut raw);
// There's no reason for SDL_ConvertAudio to fail.
// The only time it can fail is if buf is NULL, which it never is.
if ret != 0 {
panic!("{}", get_error())
}

// return original buffer back to caller
debug_assert!(raw.len_cvt > 0);
debug_assert!(raw.len_cvt as usize <= src.capacity());
// Bounce back into src, trying to re-use the same buffer.
let outlen: usize = raw.len_cvt.try_into().expect("Buffer size rollover");
debug_assert!(outlen <= dst_size);
src.resize(outlen, 0);
src.copy_from_slice(from_raw_parts_mut(raw.buf, outlen));
sys::SDL_free(raw.buf as *mut _);

src.set_len(raw.len_cvt as usize);
src
} else {
// The buffer remains unmodified
Expand Down

0 comments on commit 086ee3f

Please sign in to comment.