Safe method is actually unsafe
The following method from AudioCaptureClient is public "safe" method. However, if the user passes in an integer 'bytes_per_frame' that is incorrect/too-large the method will construct an incorrect length buffer slice and read past the end of the actual buffer.
I'd like for the bytes_per_frame value to be carried around in the AudioCaptureClient, though I am guessing if the AudioClient is re-initialized then it might become stale? Maybe borrowing could be used to prevent re-initialization while a AudioCaptureClient exists?
pub fn read_from_device_to_deque(
&self,
bytes_per_frame: usize,
data: &mut VecDeque<u8>,
) -> WasapiRes<BufferFlags> {
let mut buffer_ptr = ptr::null_mut();
let mut nbr_frames_returned = 0;
let mut flags = 0;
unsafe {
self.client.GetBuffer(
&mut buffer_ptr,
&mut nbr_frames_returned,
&mut flags,
None,
None,
)?
};
let bufferflags = BufferFlags::new(flags);
let len_in_bytes = nbr_frames_returned as usize * bytes_per_frame;
let bufferslice = unsafe { slice::from_raw_parts(buffer_ptr, len_in_bytes) };
for element in bufferslice.iter() {
data.push_back(*element);
}
unsafe { self.client.ReleaseBuffer(nbr_frames_returned).unwrap() };
trace!("read {} frames", nbr_frames_returned);
Ok(bufferflags)
}
Good catch! The bytes_per_frame get determined when initializing the AudioClient, so it could be stored then and later forwarded to the AudioCaptureClient. I think this should be safe. The only way to change it is by calling initialize again, but trying that should fail with a AUDCLNT_E_ALREADY_INITIALIZED error: https://learn.microsoft.com/en-us/windows/win32/api/audioclient/nf-audioclient-iaudioclient-initialize#return-value
This is solved in the just released v0.15