[AUv3] Render callback may resize buffers and does not enforce maximumFramesToRender
Summary
The AUv3 render callback may call scratchBuffer.setSize() while processing audio and does not appear to reject render requests larger than the allocated maximum frame count.
This violates real-time safety requirements and may cause reallocations, unpredictable latency, or buffer misuse on the audio thread.
Severity
P1 — Real-time safety and memory correctness
Affected area
modules/yup_audio_plugin_client/auv3/yup_audio_plugin_client_AUv3.mm
Current behaviour
Scratch-buffer sizing is performed from the render path rather than being fully determined during render-resource allocation.
The callback also does not appear to enforce:
frameCount <= maximumFramesToRender
Impact
- heap allocation on the real-time audio thread;
- audio dropouts or priority inversion;
- inconsistent performance on the first block;
- possible buffer overruns if preallocated structures are smaller than
frameCount;
- host-dependent failures when render quantum changes.
Steps to reproduce
- Build the plugin with allocation instrumentation.
- Load it in an AUv3 host.
- Start playback.
- Change the host buffer size or force the first render at the maximum quantum.
- Observe allocations from the render thread.
- Invoke the render block with a frame count larger than the configured maximum in a test harness.
Actual result
The render callback may resize storage, and oversized frame counts may not be rejected explicitly.
Expected result
All render storage must be allocated in allocateRenderResourcesAndReturnError().
The render callback must:
- perform no heap allocations;
- never resize containers;
- reject invalid frame counts;
- use only preallocated storage.
Suggested fix
During resource allocation:
const auto maxFrames = au.maximumFramesToRender;
scratchBuffer.setSize(totalChannels, static_cast<int>(maxFrames), false, true, false);
During rendering:
if (frameCount > allocatedMaximumFrames)
return kAudioUnitErr_TooManyFramesToProcess;
Preallocate all per-bus AudioBufferList storage at the same time.
Acceptance criteria
[AUv3] Render callback may resize buffers and does not enforce
maximumFramesToRenderSummary
The AUv3 render callback may call
scratchBuffer.setSize()while processing audio and does not appear to reject render requests larger than the allocated maximum frame count.This violates real-time safety requirements and may cause reallocations, unpredictable latency, or buffer misuse on the audio thread.
Severity
P1 — Real-time safety and memory correctness
Affected area
modules/yup_audio_plugin_client/auv3/yup_audio_plugin_client_AUv3.mmCurrent behaviour
Scratch-buffer sizing is performed from the render path rather than being fully determined during render-resource allocation.
The callback also does not appear to enforce:
Impact
frameCount;Steps to reproduce
Actual result
The render callback may resize storage, and oversized frame counts may not be rejected explicitly.
Expected result
All render storage must be allocated in
allocateRenderResourcesAndReturnError().The render callback must:
Suggested fix
During resource allocation:
During rendering:
Preallocate all per-bus
AudioBufferListstorage at the same time.Acceptance criteria
maximumFramesToRender.