From 17bd72f0e2e89a2c6aa03de29fc2583a7ec07943 Mon Sep 17 00:00:00 2001 From: Billy Keyes Date: Wed, 3 Sep 2025 17:26:05 -0700 Subject: [PATCH] Report short sources as conflicts during apply (#63) Previously, this returned an io.ErrUnexpectedEOF. This is not wrong, in that we did unexpectedly hit the end of the input file, but it is vague and implies a possible library bug rather than a problem with the patch or the input. This condition is really a conflict, as the changes described by the patch are not compatible with the state of the input. --- gitdiff/apply_test.go | 4 ++-- gitdiff/apply_text.go | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/gitdiff/apply_test.go b/gitdiff/apply_test.go index f19153b..05915ba 100644 --- a/gitdiff/apply_test.go +++ b/gitdiff/apply_test.go @@ -31,14 +31,14 @@ func TestApplyTextFragment(t *testing.T) { Src: "text_fragment_error.src", Patch: "text_fragment_error_short_src_before.patch", }, - Err: io.ErrUnexpectedEOF, + Err: &Conflict{}, }, "errorShortSrc": { Files: applyFiles{ Src: "text_fragment_error.src", Patch: "text_fragment_error_short_src.patch", }, - Err: io.ErrUnexpectedEOF, + Err: &Conflict{}, }, "errorContextConflict": { Files: applyFiles{ diff --git a/gitdiff/apply_text.go b/gitdiff/apply_text.go index 43af83a..8d0accb 100644 --- a/gitdiff/apply_text.go +++ b/gitdiff/apply_text.go @@ -1,6 +1,7 @@ package gitdiff import ( + "errors" "io" ) @@ -85,6 +86,11 @@ func (a *TextApplier) ApplyFragment(f *TextFragment) error { preimage := make([][]byte, fragEnd-start) n, err := a.lineSrc.ReadLinesAt(preimage, start) if err != nil { + // an EOF indicates that source file is shorter than the patch expects, + // which should be reported as a conflict rather than a generic error + if errors.Is(err, io.EOF) { + err = &Conflict{"src has fewer lines than required by fragment"} + } return applyError(err, lineNum(start+int64(n))) }