From c6037f3f7dad1cf8814d23be771698d2c182e6d8 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Sat, 17 Oct 2026 11:04:09 +0200 Subject: [PATCH] Saturate note tick addition in event.extract_chords Found while testing crates/engine/src/cmd/event_more.rs:579-580 (extract_chords) Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/engine/src/cmd/event_more.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/crates/engine/src/cmd/event_more.rs b/crates/engine/src/cmd/event_more.rs index c0780a55..b2da63d4 100644 --- a/crates/engine/src/cmd/event_more.rs +++ b/crates/engine/src/cmd/event_more.rs @@ -576,8 +576,8 @@ fn extract_chords(e: &mut Engine, p: &Value) -> Result { let base = s.tempo.samples_to_ticks(c.start, s.sample_rate); let end = s.tempo.samples_to_ticks(c.end(), s.sample_rate); for n in &sequence.notes { - let a = base + n.start; - let b = (base + n.end()).min(end); + let a = base.saturating_add(n.start); + let b = base.saturating_add(n.end()).min(end); if b > a { notes.push((a, b, n.pitch)); } @@ -943,6 +943,17 @@ mod tests { assert!(r["bpm"].as_f64().is_some()); } + #[test] + fn extract_chords_survives_huge_note_start() { + let (mut e, t) = midi_engine(); + let r = e.execute("midi.new_clip", &json!({"track": t.0, "start": 48_000, "end": 96_000})).unwrap(); + let clip = r["clip"].as_u64().unwrap(); + e.execute("midi.note_add", &json!({"clip": clip, "pitch": 60, "start_ticks": i64::MAX, "length_ticks": 480})).unwrap(); + e.execute("edit.select", &json!({"tracks": [t.0], "start": 0, "end": 96_000})).unwrap(); + let r = e.execute("event.extract_chords", &json!({})); + assert!(r.is_ok(), "{r:?}"); + } + #[test] fn move_song_start_moves_tick_material() { let (mut e, t) = midi_engine();