Jan. 25, 2023
6:28 p.m.
Jinoh Kang (@iamahuman) commented about dlls/windows.media.speech/recognizer.c:
> + {
> + IAudioClient_Start(impl->audio_client);
> + TRACE("session worker resumed.\n");
> + }
> + }
> + else if (status == 1) /* audio_buf_event signaled */
> + {
> + UINT32 frames_available = 0, tmp_buf_offset = 0;
> +
> + while (tmp_buf_offset < tmp_buf_size
> + && IAudioCaptureClient_GetBuffer(impl->capture_client, &audio_buf, &frames_available, &flags, NULL, NULL) == S_OK)
> + {
> + memcpy(tmp_buf + tmp_buf_offset, audio_buf, frames_available * impl->capture_wfx->nBlockAlign);
> + tmp_buf_offset += (frames_available * impl->capture_wfx->nBlockAlign);
> +
> + IAudioCaptureClient_ReleaseBuffer(impl->capture_client, frames_available);
1. Syntax: Redundant parentheses.
2. CSE: the common subexpression (`frames_available * impl->capture_wfx->nBlockAlign`) can be moved into its own variable.
3. Since we're fetching audio packets in a loop, there is no guarantee that the buffer won't overflow.
How about:
```suggestion:-1+0
SIZE_T packet_size = frames_available * impl->capture_wfx->nBlockAlign;
if (tmp_buf_offset + packet_size > tmp_buf_size)
{
/* Defer processing until the next iteration of the worker loop. */
IAudioCaptureClient_ReleaseBuffer(impl->capture_client, 0);
SetEvent(impl->audio_buf_event);
break;
}
memcpy(tmp_buf + tmp_buf_offset, audio_buf, packet_size);
tmp_buf_offset += packet_size;
IAudioCaptureClient_ReleaseBuffer(impl->capture_client, frames_available);
```
and double (or triple) `tmp_buf_size` before `malloc()`.
(The `SetEvent` can be replaced with a traker boolean flag that lets you bypass the wait entirely if you so prefer.)
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1948#note_21434