uttrflow / uttrflow/uttrflow-swift
WAVEncoder.header traps for a recording over 4 GiB, which the recording repair path can reach
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
## What happens
`WAVEncoder.header(frames:sampleRate:)` (`Sources/UttrflowAudio/WAVEncoder.swift:24-44`) writes `UInt32(36 + payloadSize)` and `UInt32(payloadSize)`. `UInt32(_:)` traps when the value does not fit, so any `frames` above about 2.1 billion (a payload over 4 GiB) crashes.
`RecordingWriter.repair` (`Sources/UttrflowAudio/RecordingWriter.swift:133-147`) builds this header from the size of whatever file is on disk, via `WAVEncoder.frames(inFileOf:)`. Under today's dictation limit of four minutes (`DictationLimit.default`) a recording is a few megabytes, so this cannot happen with a file the app wrote. It can happen with a file that is not what it seems, and repair runs on files found at launch.
## Why it matters
A crash at launch from a file in Application Support is the kind that repeats on every launch until someone deletes the file by hand.
## How to check
`WAVEncoder.header(frames: Int(UInt32.max), sampleRate: 16_000)` traps. (`header` is internal, reachable with `@testable import UttrflowAudio`.)
## Acceptance criteria
- `header` never traps: sizes that do not fit are clamped to `UInt32.max` (the usual convention for an over-long WAV), or `repair` refuses a file too large to describe and leaves it untouched. Say which in the pull request, with a one-line comment in the code.
- A test in `WAVEncoderTests.swift` calls `header` with a frame count just over the limit and checks the declared sizes.
- If you change `repair`, a test in `RecordingWriterTests.swift` covers it without creating a 4 GiB file (for example by moving the size decision into a small static function).
## Where to start
- `Sources/UttrflowAudio/WAVEncoder.swift:24-50`
- `Sources/UttrflowAudio/RecordingWriter.swift:133-147`
- Tests to extend: `Tests/UttrflowAudioTests/WAVEncoderTests.swift`, `Tests/UttrflowAudioTests/RecordingWriterTests.swift`.
- Before pushing, run `make verify` (export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer first). It is the same command CI runs, and it enforces the 95% coverage floor per module.
- Read [CONTRIBUTING.md](https://github.com/uttrflow/uttrflow-swift/blob/main/CONTRIBUTING.md) first, and say on this issue that you are taking it.
**Size:** S, about 2 hours.
Contributor guide
Research direction
Read CONTRIBUTING.md, then inspect Sources/UttrflowAudio/WAVEncoder.swift:24-50 and RecordingWriter.swift:133-147. Extend WAVEncoderTests.swift with an over-limit frame case, and add RecordingWriterTests.swift coverage if the repair path changes. Run make verify with the specified DEVELOPER_DIR; done means the header no longer traps and the declared-size behavior matches the chosen acceptance criterion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- audio-video-rtc, desktop
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100