diff --git a/diff/diff.go b/diff/diff.go index 75d9a484..5d03ba24 100644 --- a/diff/diff.go +++ b/diff/diff.go @@ -41,6 +41,11 @@ func checkDiffFile(parsedDiff *diff.FileDiff, workspace string) (filePath string // If file is being renamed we don't want to check it for flags. parsedFileA := strings.SplitN(parsedDiff.OrigName, "/", 2) parsedFileB := strings.SplitN(parsedDiff.NewName, "/", 2) + // Mode-only diffs (e.g. chmod changes) and some binary diffs emit no --- / +++ headers. + // go-diff returns empty OrigName/NewName for these entries; there is no content to scan. + if len(parsedFileA) < 2 || len(parsedFileB) < 2 { + return "", true + } fullPathToA := workspace + "/" + parsedFileA[1] fullPathToB := workspace + "/" + parsedFileB[1] info, err := os.Stat(fullPathToB) @@ -90,4 +95,4 @@ func ProcessDiffs(matcher lsearch.Matcher, contents []byte, builder *refs.Refere break } } -} +} \ No newline at end of file diff --git a/diff/diff_test.go b/diff/diff_test.go index 368b61d3..2606e21c 100644 --- a/diff/diff_test.go +++ b/diff/diff_test.go @@ -69,11 +69,12 @@ func newProcessFlagAccEnv() *testProcessor { func Test_checkDiffFile(t *testing.T) { cases := []struct { - name string - fileName string - origName string - newName string - skip bool + name string + fileName string + origName string + newName string + skip bool + expectedFilePath string // when non-empty, overrides "../testdata/" + fileName }{ { name: "basic", @@ -89,6 +90,16 @@ func Test_checkDiffFile(t *testing.T) { newName: "b/.testignore", skip: true, }, + { + // Mode-only diffs (e.g. chmod changes) produce no --- / +++ headers. + // go-diff returns empty OrigName and NewName for these entries, which + // caused a panic at diff.go:44 when SplitN("", "/", 2)[1] was accessed. + name: "skip mode-only diff with empty OrigName and NewName", + origName: "", + newName: "", + skip: true, + expectedFilePath: "", + }, } for _, tc := range cases { @@ -100,13 +111,16 @@ func Test_checkDiffFile(t *testing.T) { OrigStartLine: 0, StartPosition: 1, } - diff := diff.FileDiff{ + fileDiff := diff.FileDiff{ OrigName: tc.origName, NewName: tc.newName, Hunks: []*diff.Hunk{hunk}, } - filePath, ignore := checkDiffFile(&diff, "../testdata") - expectedFilePath := "../testdata/" + tc.fileName + filePath, ignore := checkDiffFile(&fileDiff, "../testdata") + expectedFilePath := tc.expectedFilePath + if expectedFilePath == "" && tc.fileName != "" { + expectedFilePath = "../testdata/" + tc.fileName + } assert.Equal(t, expectedFilePath, filePath) assert.Equal(t, tc.skip, ignore) }) @@ -248,4 +262,4 @@ func TestProcessDiffs_BuildReferences(t *testing.T) { assert.Equal(t, tc.expected, flagsRef) }) } -} +} \ No newline at end of file