Skip to content

fix: prevent integer overflow in AudioSourceFactory frame count calculation#813

Open
jtjones1028 wants to merge 1 commit into
FluidInference:mainfrom
jtjones1028:fix/audio-source-factory-overflow
Open

fix: prevent integer overflow in AudioSourceFactory frame count calculation#813
jtjones1028 wants to merge 1 commit into
FluidInference:mainfrom
jtjones1028:fix/audio-source-factory-overflow

Conversation

@jtjones1028

Copy link
Copy Markdown

Summary

Fixes a crash when processing audio files where (audioFile.length - audioFile.framePosition) exceeds AVAudioFrameCount.max (UInt32.max = ~4.29 billion frames).

Problem

The bug caused a Swift runtime failure: "Not enough bits to represent the passed value" when casting Int64 to UInt32 without bounds checking in AudioSourceFactory.swift:138.

This occurred during initialization in macOS apps using FluidAudio for diarization, particularly when Speech API capability checks triggered audio processing with test/probe audio files.

Solution

Clamp the remaining frames to AVAudioFrameCount.max before casting:

// Before:
let remainingFrames = AVAudioFrameCount(audioFile.length - audioFile.framePosition)

// After:
let remainingFramesInt64 = audioFile.length - audioFile.framePosition
let remainingFrames = AVAudioFrameCount(min(remainingFramesInt64, Int64(AVAudioFrameCount.max)))

This prevents overflow while maintaining correct behavior for normal-sized audio files.

Testing

  • ✅ Builds successfully with swift build
  • ✅ Fixed crash in production macOS application during Speech API initialization
  • ✅ No impact on normal audio file processing

Backport Request

This fix should be backported to the 0.14.x maintenance branch as well, as it affects apps using FluidAudio 0.14.5-0.14.8.

…lation

Fixes a crash when processing audio files where (audioFile.length - audioFile.framePosition)
exceeds AVAudioFrameCount.max (UInt32.max = ~4.29 billion frames).

The bug caused a Swift runtime failure: "Not enough bits to represent the passed value"
when casting Int64 to UInt32 without bounds checking.

This occurred during initialization in apps using FluidAudio for diarization,
particularly when Speech API capability checks triggered audio processing.

Solution: Clamp the remaining frames to AVAudioFrameCount.max before casting,
preventing overflow while maintaining correct behavior for normal-sized audio files.
@Alex-Wengg

Copy link
Copy Markdown
Member

from claude

the only other signal; my review from the previous message stands as the only feedback so far:

  1. Incomplete clamp (main issue): min(remainingFramesInt64, Int64(AVAudioFrameCount.max)) still traps on a negative difference (framePosition > length, reachable with corrupt/VBR files). AVAudioFrameCount(clamping: ...) is the one-line fix covering both directions.
  2. Simpler structural fix: drop the length - framePosition computation entirely and always read inputCapacity — AVAudioFile.read returns frameLength == 0 at EOF, which the block already handles. This removes the trap surface and a latent silent-truncation issue.
  3. Same pattern unpatched at NemotronMultilingualTranscribe.swift:216, in the ≥20h-file path where positive overflow is actually plausible (CLI-only, so lower priority).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants