Repository navigation
Reset the audio converter before raising a codec error - #142
Open
romansorochak wants to merge 2 commits into
Open
romansorochak wants to merge 2 commits into
romansorochak wants to merge 2 commits into
Conversation
A failed AudioConverterFillComplexBuffer can leave the converter holding a span of its input, which points into memory AudioFileStream owns only for the duration of the packets callback. The stream keeps delivering data after .codecError, so the next fill consolidates that stale span with new input and reads freed memory (ACSpanningInputBuffer::consolidateInput -> memmove, SIGSEGV/SIGBUS). Call AudioConverterReset before each .codecError raise in AudioFileStreamProcessor, as processSeek() and createAudioConverter already do. In a harness that unmaps each chunk after AudioFileStreamParseBytes returns, MP3 input switching format mid-stream crashed on 10-11 of 40 seeds without the reset and on 0 of 40 with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit d5acc82)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A failed
AudioConverterFillComplexBufferinAudioFileStreamProcessor.propertyPacketsProcraises.codecErrorbut leaves the converter holding a span of its input. That span points into the packet dataAudioFileStreamowns only for the duration of the packets callback. The source keeps delivering data after the error, so on the next fill the converter consolidates the stale span with new input and reads freed memory:(or
MP3DecoderWrapper::Fill), which ends in SIGSEGV / SIGBUS.In our app (Radio Live, iOS) this is the second-largest playback crash family: 40 installs from 3.3.2 to 3.10.1, every one at the first
FillComplexBuffercall onsource.queue. In about 32 of the 40 the player was already in.errorjust before the crash.Fix
Call
AudioConverterResetbefore each of the three.codecErrorraises.processSeek()andcreateAudioConverteralready reset the converter the same way. The change is +16 / −3 inAudioFileStreamProcessor.swift.Evidence
I could not add a unit test. The defect is a use-after-free whose only observable effect is a crash on some inputs, and that crash takes the XCTest process down, so there is no seam to assert on. Instead I used a standalone harness that runs the library's exact parse → convert flow and unmaps each chunk after
AudioFileStreamParseBytesreturns. With MP3 input that switches format mid-stream, the converter returns'bada'(kAudioCodecBadDataError):swift test:Executed 59 tests, with 0 failures.Thanks again for merging #138 and #140.