Skip to content

Commit d276c49

Browse files
committed
fix: prevent overflow in buffer size calculations
1 parent 91c8ce8 commit d276c49

3 files changed

Lines changed: 12 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8484
- **AAudio**: Fix thread lock when a stream is dropped before it fully starts.
8585
- **AAudio**: Fix capture and playback timestamps falling back to time-zero on error.
8686
- **AAudio**: Fix capture and playback timestamp not accounting for audio pipeline buffer depth.
87-
- **AAudio**: Fix signed overflow in `buffer_capacity_in_frames` for large fixed buffer sizes.
87+
- **AAudio**: Fix overflow in `buffer_capacity_in_frames` for large fixed buffer sizes.
8888
- **ALSA**: Fix capture stream hanging or spinning on overruns.
8989
- **ALSA**: Fix non-monotonic `StreamInstant` during stream startup.
9090
- **ALSA**: Fix spurious timestamp errors during stream startup.
9191
- **ALSA**: Fix spurious timeout errors during polling.
9292
- **ALSA**: Fix rare panics when dropping the stream is interrupted.
9393
- **ALSA**: Fix timestamp overflows on 32-bit platforms.
94+
- **ALSA**: Fix overflow in `buffer_capacity_in_frames` for large fixed buffer sizes.
9495
- **ASIO**: Fix enumeration returning only the first device when using `collect()`.
9596
- **ASIO**: Fix device enumeration and stream creation failing when called from spawned threads.
9697
- **ASIO**: Fix buffer size not resizing when the driver reports `kAsioBufferSizeChange`.

src/host/alsa/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1459,7 +1459,7 @@ fn set_hw_params_from_format(
14591459
// buffer_size = 2x and period_size = x. This provides consistent low-latency
14601460
// behavior across different ALSA implementations and hardware.
14611461
if let BufferSize::Fixed(buffer_frames) = config.buffer_size {
1462-
hw_params.set_buffer_size_near((2 * buffer_frames) as alsa::pcm::Frames)?;
1462+
hw_params.set_buffer_size_near(2 * buffer_frames as alsa::pcm::Frames)?;
14631463
hw_params
14641464
.set_period_size_near(buffer_frames as alsa::pcm::Frames, alsa::ValueOr::Nearest)?;
14651465
}

src/host/pulseaudio/mod.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -501,14 +501,17 @@ fn make_playback_buffer_attr(
501501
match config.buffer_size {
502502
crate::BufferSize::Default => Default::default(),
503503
crate::BufferSize::Fixed(frame_count) => {
504-
let len = frame_count * config.channels as u32 * format.bytes_per_sample() as u32;
504+
let len =
505+
(frame_count as u64 * config.channels as u64 * format.bytes_per_sample() as u64)
506+
.min(u32::MAX as u64) as u32;
507+
let double_len = (len as u64 * 2).min(u32::MAX as u64) as u32;
505508
protocol::stream::BufferAttr {
506509
// Double-buffer: total buffer = 2 callback periods. With
507510
// adjust_latency this becomes the end-to-end latency target,
508511
// Minimum request = one callback period, ensuring the server
509512
// always asks for exactly frame_count frames per call.
510-
max_length: 2 * len,
511-
target_length: 2 * len,
513+
max_length: double_len,
514+
target_length: double_len,
512515
minimum_request_length: len,
513516
..Default::default()
514517
}
@@ -523,7 +526,9 @@ fn make_record_buffer_attr(
523526
match config.buffer_size {
524527
crate::BufferSize::Default => Default::default(),
525528
crate::BufferSize::Fixed(frame_count) => {
526-
let len = frame_count * config.channels as u32 * format.bytes_per_sample() as u32;
529+
let len =
530+
(frame_count as u64 * config.channels as u64 * format.bytes_per_sample() as u64)
531+
.min(u32::MAX as u64) as u32;
527532
protocol::stream::BufferAttr {
528533
// fragment_size controls the delivery chunk size for record
529534
// streams; target_length is playback-only and is ignored here.

0 commit comments

Comments
 (0)