From 9d387eb2130dc288b26f142c54a73f48a5ea2244 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 18 Mar 2026 12:21:56 +0400 Subject: [PATCH] fix: panic in linear myers algorithm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In `linearSpaceMyersRecWithIndices`, the suffix-scanning loop: ```go for suffix < n-prefix && a[aEnd-1-suffix] == b[bEnd-1-suffix] { ``` bounds the scan against n-prefix (a's remaining length after prefix) but not against m-prefix (b's remaining length). With the fuzzer's input a="\n\n\n\n\n\n\n\n\n0" → 10 lines, b="0" → 1 line: n=10, m=1, prefix=0 suffix=0: a[9]="0" == b[0]="0" → true, suffix becomes 1 suffix=1: tries b[1-1-1] = b[-1] → index out of range panic Signed-off-by: Andrey Smirnov --- diff/myers/myers.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/diff/myers/myers.go b/diff/myers/myers.go index d1cac70..ca13881 100644 --- a/diff/myers/myers.go +++ b/diff/myers/myers.go @@ -207,7 +207,7 @@ func linearSpaceMyersRecWithIndices(a, b []string, aStart, aEnd, bStart, bEnd, d // Check for common prefix/suffix to reduce problem size prefix := 0 - for prefix < n && a[aStart+prefix] == b[bStart+prefix] { + for prefix < n && prefix < m && a[aStart+prefix] == b[bStart+prefix] { prefix++ } @@ -217,7 +217,7 @@ func linearSpaceMyersRecWithIndices(a, b []string, aStart, aEnd, bStart, bEnd, d } suffix := 0 - for suffix < n-prefix && a[aEnd-1-suffix] == b[bEnd-1-suffix] { + for suffix < n-prefix && suffix < m-prefix && a[aEnd-1-suffix] == b[bEnd-1-suffix] { suffix++ } @@ -418,7 +418,15 @@ func findMiddleSnake(a, b []string, aStart, aEnd, bStart, bEnd int) snake { //re x = vf[idx] } + // Clamp to valid grid boundaries: x must be in [0, n], y = x-k must be in [0, m]. + // vf[k-1]+1 can exceed n when that diagonal already reached the end of a. + if x > n { + x = n + } y := x - k // Calculate y based on x and diagonal k + if y < 0 || y > m { + continue + } // Store the starting point of the potential snake for this (d, k) startX := x @@ -480,7 +488,15 @@ func findMiddleSnake(a, b []string, aStart, aEnd, bStart, bEnd int) snake { //re continue } + // Clamp to valid grid boundaries: x must be in [0, n], y = x-k must be in [0, m]. + // vr[k+1]-1 can go negative when that diagonal already reached the start. + if x < 0 { + x = 0 + } y := x - k + if y < 0 || y > m { + continue + } endX := x endY := y