Skip to content

Commit

Permalink
parser: Handle binary git patches
Browse files Browse the repository at this point in the history
'git-format-patch' is able to generate binary patches. Fortunately,
these are quite easy to spot since they're explicitly labelled as such.
Add support for parsing these to the parser.

Signed-off-by: Stephen Finucane <stephen@that.guru>
Closes: #463
(cherry picked from commit 6ba50aa)
  • Loading branch information
stephenfin committed May 11, 2022
1 parent f4c0503 commit 78e257d
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 2 deletions.
18 changes: 16 additions & 2 deletions patchwork/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,7 @@ def parse_patch(content):
format, and splits it into the component comments and diff.
Args:
patch: The patch to be split
content: The mail to be split
Returns:
A tuple containing the diff and comment. Either one or both of
Expand All @@ -874,6 +874,7 @@ def parse_patch(content):
# 4: patch hunk header line (@@ line)
# 5: patch hunk content
# 6: patch meta header (rename from/rename to/new file/index)
# 7: binary patch hunk
#
# valid transitions:
# 0 -> 1 (diff, Index:)
Expand All @@ -882,10 +883,12 @@ def parse_patch(content):
# 2 -> 3 (+++)
# 3 -> 4 (@@ line)
# 4 -> 5 (patch content)
# 5 -> 1 (run out of lines from @@-specifed count)
# 5 -> 1 (ran out of lines from @@-specified count)
# 1 -> 6 (extended header lines)
# 6 -> 2 (---)
# 6 -> 7 (GIT binary patch)
# 6 -> 1 (other text)
# 7 -> 1 (diff)
#
# Suspected patch header is stored into buf, and appended to
# patchbuf if we find a following hunk. Otherwise, append to
Expand Down Expand Up @@ -980,9 +983,20 @@ def fn(x):
patchbuf += buf + line
buf = ''
state = 2
elif line.startswith('GIT binary patch'):
patchbuf += buf + line
buf = ''
state = 7
else:
buf += line
state = 1
elif state == 7:
if line.startswith('diff'):
buf += line
state = 0
else:
patchbuf += buf + line
buf = ''
else:
raise Exception("Unknown state %d! (line '%s')" % (state, line))

Expand Down
28 changes: 28 additions & 0 deletions patchwork/tests/mail/0025-git-add-binary-file.mbox
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
From 3029b9604cf2b2eaa5f38167f59246e2fa026eb5 Mon Sep 17 00:00:00 2001
From: Stephen Finucane <stephen@that.guru>
Date: Wed, 11 May 2022 10:59:59 +0100
Subject: [PATCH] Add a single pixel bitmap image
To: foo@example.com

Demonstrate how Git generates a patch for a binary file.

Signed-off-by: Stephen Finucane <stephen@that.guru>
---
pixel.bmp | Bin 0 -> 142 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 pixel.bmp

diff --git pixel.bmp pixel.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..9710347a13c4336e7dbaafa69af0e44a40c21172
GIT binary patch
literal 142
zcmZ?r?PGv|E+AC{#Eft(0hV9^lFE7z3>E+r{}~t{2+VVG4=P5;5yxUeQzj#`nE?RC
Ceh3`^

literal 0
HcmV?d00001

--
2.35.3

40 changes: 40 additions & 0 deletions patchwork/tests/mail/0026-git-add-mixed-binary-text-files.mbox
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
From 499d36d946a6f1f654eebad500742eb5c3057569 Mon Sep 17 00:00:00 2001
From: Stephen Finucane <stephen@that.guru>
Date: Wed, 11 May 2022 10:33:58 +0100
Subject: [PATCH] Add a single pixel bitmap image, minimal script
To: foo@example.com

Demonstrate how Git generates a patch for a binary file when mixed with
other file types.

Signed-off-by: Stephen Finucane <stephen@that.guru>
---
pixel.bmp | Bin 0 -> 142 bytes
quit.sh | 3 +++
2 files changed, 3 insertions(+)
create mode 100644 pixel.bmp
create mode 100644 quit.sh

diff --git pixel.bmp pixel.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..9710347a13c4336e7dbaafa69af0e44a40c21172
GIT binary patch
literal 142
zcmZ?r?PGv|E+AC{#Eft(0hV9^lFE7z3>E+r{}~t{2+VVG4=P5;5yxUeQzj#`nE?RC
Ceh3`^

literal 0
HcmV?d00001

diff --git quit.sh quit.sh
new file mode 100644
index 0000000..f5f929a
--- /dev/null
+++ quit.sh
@@ -0,0 +1,3 @@
+#/usr/bin/env bash
+echo "Wuh wuh"
+exit 1
--
2.35.3

24 changes: 24 additions & 0 deletions patchwork/tests/mail/0027-git-modify-binary-file.mbox
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
From 434fe33a7ed28cc8cd0b344e55f0be2c74f1a58c Mon Sep 17 00:00:00 2001
From: Stephen Finucane <stephen@that.guru>
Date: Wed, 11 May 2022 11:46:10 +0100
Subject: [PATCH] Make changes to an existing binary file
To: foo@example.com

Signed-off-by: Stephen Finucane <stephen@that.guru>
---
pixel.bmp | Bin 142 -> 0 bytes
1 file changed, 0 insertions(+), 0 deletions(-)

diff --git pixel.bmp pixel.bmp
index 9710347a13c4336e7dbaafa69af0e44a40c21172..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
GIT binary patch
literal 0
HcmV?d00001

literal 142
zcmZ?r?PGv|E+AC{#Eft(0hV9^lFE7z3>E+r{}~t{2+VVG4=P5;5yxUeQzj#`nE?RC
Ceh3`^

--
2.35.3

34 changes: 34 additions & 0 deletions patchwork/tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,40 @@ def test_git_pull_trailing_space(self):
'linux-davinci.git tags/davinci-for-v5.6/soc',
pull_url)

def test_git_add_binary_file(self):
diff, message = self._find_content('0025-git-add-binary-file.mbox')
self.assertTrue(diff is not None)
self.assertTrue(message is not None)
self.assertTrue(
diff.startswith('diff --git pixel.bmp pixel.bmp'), diff
)
self.assertIn('GIT binary patch\n', diff)
self.assertIn('literal 142\n', diff)
self.assertIn('literal 0\n', diff)

def test_git_add_mixed_binary_text_files(self):
diff, message = self._find_content(
'0026-git-add-mixed-binary-text-files.mbox'
)
self.assertTrue(diff is not None)
self.assertTrue(message is not None)
self.assertTrue(
diff.startswith('diff --git pixel.bmp pixel.bmp'), diff
)
self.assertIn('GIT binary patch\n', diff)
self.assertIn('diff --git quit.sh quit.sh\n', diff)

def test_git_modify_binary_file(self):
diff, message = self._find_content('0027-git-modify-binary-file.mbox')
self.assertTrue(diff is not None)
self.assertTrue(message is not None)
self.assertTrue(
diff.startswith('diff --git pixel.bmp pixel.bmp'), diff
)
self.assertIn('GIT binary patch\n', diff)
self.assertIn('literal 0\n', diff)
self.assertIn('literal 142\n', diff)

def test_git_rename(self):
diff, _ = self._find_content('0008-git-rename.mbox')
self.assertTrue(diff is not None)
Expand Down

0 comments on commit 78e257d

Please sign in to comment.