mirror of
https://github.com/storytold/soundcraft.git
synced 2026-10-24 10:36:46 -06:00
Fix integer overflow in TempoMap::bar_beat_at_tick for i64::MIN
Found while testing crates/time/src/tempo.rs:271 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
7b339fe921
commit
4ef6458e4e
@@ -268,9 +268,12 @@ impl TempoMap {
|
||||
let first = self.meter_at_tick(0);
|
||||
if tick < 0 {
|
||||
let tpb = first.ticks_per_bar();
|
||||
let bars_back = (-tick + tpb - 1) / tpb;
|
||||
let bar_tick = -bars_back * tpb;
|
||||
let within = tick - bar_tick;
|
||||
let abs = tick.unsigned_abs();
|
||||
let tpb_u = tpb.unsigned_abs();
|
||||
let bars_back_u = abs / tpb_u + u64::from(!abs.is_multiple_of(tpb_u));
|
||||
let bars_back = i64::try_from(bars_back_u).unwrap_or(i64::MAX);
|
||||
// Offset of `tick` inside its bar, without negating `i64::MIN`.
|
||||
let within = ((tpb_u - abs % tpb_u) % tpb_u) as i64;
|
||||
let beat_t = first.ticks_per_beat();
|
||||
return BarBeat { bar: 1 - bars_back, beat: within / beat_t + 1, tick: within % beat_t };
|
||||
}
|
||||
@@ -341,6 +344,15 @@ mod tests {
|
||||
assert_eq!(m.bar_start_tick(0), -TICKS_PER_QUARTER * 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bar_beat_at_min_tick_does_not_overflow() {
|
||||
let m = TempoMap::default();
|
||||
let bb = m.bar_beat_at_tick(i64::MIN);
|
||||
assert!(bb.bar < 1);
|
||||
assert!(bb.beat >= 1 && bb.tick >= 0);
|
||||
assert_eq!(m.bar_beat_at_tick(-1).bar, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tempo_change_is_integrated() {
|
||||
let mut m = TempoMap::default();
|
||||
|
||||
Reference in New Issue
Block a user