From: Stephen Finucane Date: Wed, 11 May 2022 09:30:45 +0000 (+0100) Subject: parser: Handle binary git patches X-Git-Tag: v3.1.0~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6ba50aadcea526a9b4e4742f0427479bb237da48;p=thirdparty%2Fpatchwork.git parser: Handle binary git patches '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 Closes: #463 --- diff --git a/patchwork/parser.py b/patchwork/parser.py index 537f8bc0..562c1c7c 100644 --- a/patchwork/parser.py +++ b/patchwork/parser.py @@ -873,7 +873,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 @@ -895,6 +895,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:) @@ -903,10 +904,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 @@ -1001,9 +1004,20 @@ def parse_patch(content): 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)) diff --git a/patchwork/tests/mail/0025-git-add-binary-file.mbox b/patchwork/tests/mail/0025-git-add-binary-file.mbox new file mode 100644 index 00000000..2fa9afa7 --- /dev/null +++ b/patchwork/tests/mail/0025-git-add-binary-file.mbox @@ -0,0 +1,28 @@ +From 3029b9604cf2b2eaa5f38167f59246e2fa026eb5 Mon Sep 17 00:00:00 2001 +From: Stephen Finucane +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 +--- + 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 + diff --git a/patchwork/tests/mail/0026-git-add-mixed-binary-text-files.mbox b/patchwork/tests/mail/0026-git-add-mixed-binary-text-files.mbox new file mode 100644 index 00000000..9af26316 --- /dev/null +++ b/patchwork/tests/mail/0026-git-add-mixed-binary-text-files.mbox @@ -0,0 +1,40 @@ +From 499d36d946a6f1f654eebad500742eb5c3057569 Mon Sep 17 00:00:00 2001 +From: Stephen Finucane +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 +--- + 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 + diff --git a/patchwork/tests/mail/0027-git-modify-binary-file.mbox b/patchwork/tests/mail/0027-git-modify-binary-file.mbox new file mode 100644 index 00000000..cd0f4067 --- /dev/null +++ b/patchwork/tests/mail/0027-git-modify-binary-file.mbox @@ -0,0 +1,24 @@ +From 434fe33a7ed28cc8cd0b344e55f0be2c74f1a58c Mon Sep 17 00:00:00 2001 +From: Stephen Finucane +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 +--- + 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 + diff --git a/patchwork/tests/test_parser.py b/patchwork/tests/test_parser.py index ec368108..108d8b9b 100644 --- a/patchwork/tests/test_parser.py +++ b/patchwork/tests/test_parser.py @@ -730,6 +730,40 @@ class PatchParseTest(PatchTest): 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)