uttrflow / uttrflow/uttrflow-swift

WAVEncoder.header traps for a recording over 4 GiB, which the recording repair path can reach

Open Beginner friendly
#501 0 comments 0 reactions 0 assignees View on GitHub
area:dictation bug good first issue P2
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.