wasapi-rs icon indicating copy to clipboard operation
wasapi-rs copied to clipboard

Safe method is actually unsafe

Open millardjn opened this issue 1 year ago • 1 comments

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)
    }

millardjn avatar Apr 28 '24 09:04 millardjn

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

HEnquist avatar Apr 28 '24 18:04 HEnquist

This is solved in the just released v0.15

HEnquist avatar Jun 17 '24 21:06 HEnquist