nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: bluekeyes/go-gitdiff
Pull request #28 (2021-09-09 18:22:05)

Fix out-of-bounds panic parsing timestamps
Found by go-fuzz.


Patch:
diff --git a/gitdiff/file_header.go b/gitdiff/file_header.go
index e3185bd..58904b4 100644
--- a/gitdiff/file_header.go
+++ b/gitdiff/file_header.go
@@ -527,7 +527,7 @@ func hasEpochTimestamp(s string) bool {
 
 	// a valid timestamp can have optional ':' in zone specifier
 	// remove that if it exists so we have a single format
-	if ts[len(ts)-3] == ':' {
+	if len(ts) >= 3 && ts[len(ts)-3] == ':' {
 		ts = ts[:len(ts)-3] + ts[len(ts)-2:]
 	}
 


Test patch:
diff --git a/gitdiff/file_header_test.go b/gitdiff/file_header_test.go
index 99cfed3..102795c 100644
--- a/gitdiff/file_header_test.go
+++ b/gitdiff/file_header_test.go
@@ -724,6 +724,14 @@ func TestHasEpochTimestamp(t *testing.T) {
 			Input:  "+++ file.txt\t2019-03-21 12:34:56.789 -0700\n",
 			Output: false,
 		},
+		"notTimestamp": {
+			Input:  "+++ file.txt\trandom text\n",
+			Output: false,
+		},
+		"notTimestampShort": {
+			Input:  "+++ file.txt\t0\n",
+			Output: false,
+		},
 	}
 
 	for name, test := range tests {
Repository: bluekeyes/go-gitdiff
Pull request #55 (2025-01-08 03:22:33)

Parse binary headers with file paths
Some patches may include one or more file paths as part of the binary header when there is no binary data. Git accounts for this by only checking the prefix and suffix of the line, but I missed that logic when implementing this originally.

Alternate to #54.


Patch:
diff --git a/gitdiff/binary.go b/gitdiff/binary.go
index c65a9a6..282e323 100644
--- a/gitdiff/binary.go
+++ b/gitdiff/binary.go
@@ -50,11 +50,11 @@ func (p *parser) ParseBinaryFragments(f *File) (n int, err error) {
 }
 
 func (p *parser) ParseBinaryMarker() (isBinary bool, hasData bool, err error) {
-	switch p.Line(0) {
-	case "GIT binary patch\n":
+	line := p.Line(0)
+	switch {
+	case line == "GIT binary patch\n":
 		hasData = true
-	case "Binary files differ\n":
-	case "Files differ\n":
+	case isBinaryNoDataMarker(line):
 	default:
 		return false, false, nil
 	}
@@ -65,6 +65,13 @@ func (p *parser) ParseBinaryMarker() (isBinary bool, hasData bool, err error) {
 	return true, hasData, nil
 }
 
+func isBinaryNoDataMarker(line string) bool {
+	if strings.HasSuffix(line, " differ\n") {
+		return strings.HasPrefix(line, "Binary files ") || strings.HasPrefix(line, "Files ")
+	}
+	return false
+}
+
 func (p *parser) ParseBinaryFragmentHeader() (*BinaryFragment, error) {
 	parts := strings.SplitN(strings.TrimSuffix(p.Line(0), "\n"), " ", 2)
 	if len(parts) < 2 {


Test patch:
diff --git a/gitdiff/binary_test.go b/gitdiff/binary_test.go
index a31a0e0..64db243 100644
--- a/gitdiff/binary_test.go
+++ b/gitdiff/binary_test.go
@@ -25,6 +25,16 @@ func TestParseBinaryMarker(t *testing.T) {
 			IsBinary: true,
 			HasData:  false,
 		},
+		"binaryFileNoPatchPaths": {
+			Input:    "Binary files a/foo.bin and b/foo.bin differ\n",
+			IsBinary: true,
+			HasData:  false,
+		},
+		"fileNoPatch": {
+			Input:    "Files differ\n",
+			IsBinary: true,
+			HasData:  false,
+		},
 		"textFile": {
 			Input:    "@@ -10,14 +22,31 @@\n",
 			IsBinary: false,
Repository: bluekeyes/go-gitdiff
Pull request #56 (2025-01-08 03:33:43)

Fix binary headers in formatted patches
Include file names in the header (now that we can actually parse them) and fix a bad find-and-replace that changed "differ" to "fmer". Add a new test to verify that binary files without data format correctly.


Patch:
diff --git a/gitdiff/format.go b/gitdiff/format.go
index 5653f6f..d97aba9 100644
--- a/gitdiff/format.go
+++ b/gitdiff/format.go
@@ -169,7 +169,11 @@ func (fm *formatter) FormatFile(f *File) {
 
 	if f.IsBinary {
 		if f.BinaryFragment == nil {
-			fm.WriteString("Binary files fmer\n")
+			fm.WriteString("Binary files ")
+			fm.WriteQuotedName("a/" + aName)
+			fm.WriteString(" and ")
+			fm.WriteQuotedName("b/" + bName)
+			fm.WriteString(" differ\n")
 		} else {
 			fm.WriteString("GIT binary patch\n")
 			fm.FormatBinaryFragment(f.BinaryFragment)


Test patch:
diff --git a/gitdiff/format_roundtrip_test.go b/gitdiff/format_roundtrip_test.go
index 58cff97..a230e91 100644
--- a/gitdiff/format_roundtrip_test.go
+++ b/gitdiff/format_roundtrip_test.go
@@ -31,6 +31,7 @@ func TestFormatRoundtrip(t *testing.T) {
 		// data is slightly different when re-encoded by Go.
 		{File: "binary_modify.patch", SkipTextCompare: true},
 		{File: "binary_new.patch", SkipTextCompare: true},
+		{File: "binary_modify_nodata.patch"},
 	}
 
 	for _, patch := range patches {
diff --git a/gitdiff/testdata/string/binary_modify_nodata.patch b/gitdiff/testdata/string/binary_modify_nodata.patch
new file mode 100644
index 0000000..833a534
--- /dev/null
+++ b/gitdiff/testdata/string/binary_modify_nodata.patch
@@ -0,0 +1,3 @@
+diff --git a/file.bin b/file.bin
+index a7f4d5d..bdc9a70 100644
+Binary files a/file.bin and b/file.bin differ