]> git.ipfire.org Git - thirdparty/patchwork.git/commitdiff
parser: Handle binary git patches
authorStephen Finucane <stephen@that.guru>
Wed, 11 May 2022 09:30:45 +0000 (10:30 +0100)
committerStephen Finucane <stephen@that.guru>
Wed, 11 May 2022 11:22:25 +0000 (12:22 +0100)
'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 6ba50aadcea526a9b4e4742f0427479bb237da48)

patchwork/parser.py
patchwork/tests/mail/0025-git-add-binary-file.mbox [new file with mode: 0644]
patchwork/tests/mail/0026-git-add-mixed-binary-text-files.mbox [new file with mode: 0644]
patchwork/tests/mail/0027-git-modify-binary-file.mbox [new file with mode: 0644]
patchwork/tests/test_parser.py

index 554c0db915c4e295598ef4ccb177f90d18bf05f6..e8f8d8a4c1132dd0867c99b71f26dbb682d4295a 100644 (file)
@@ -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
@@ -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:)
@@ -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
@@ -980,9 +983,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 (file)
index 0000000..2fa9afa
--- /dev/null
@@ -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
+
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 (file)
index 0000000..9af2631
--- /dev/null
@@ -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
+
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 (file)
index 0000000..cd0f406
--- /dev/null
@@ -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
+
index 3db632514d5467862fb4a318b6857d426612859c..2bd7720aa7a3db8e31e2fcfe3fdb496f9a5bed5d 100644 (file)
@@ -691,6 +691,40 @@ class PatchParseTest(PatchTest):
             '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)