aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGuido Günther <agx@sigxcpu.org>2018-11-08 11:09:10 +0100
committerGuido Günther <agx@sigxcpu.org>2018-11-08 11:34:46 +0100
commit1994bb27cff3468816ad919803e7576eae259b26 (patch)
treed4e0e8455a563ed034743e311cd292fc2bf3b467
parent370244733d44eaf509d242d30b5dddbb26f53fde (diff)
PatchSeries: Only pass patch description and header to git-mailinfo
There are patches around that use Content-Transfer-Encoding: base64 but the actual patch after '---' is unencoded ascii resulting in garbage after the patch description when imported into a patch queue. Since we're discarding the patch part of git-mailinfo anyway don't pass this on in the first place. Closes: #912426
-rw-r--r--gbp/patch_series.py35
-rw-r--r--tests/08_test_patch.py24
-rw-r--r--tests/08_test_patch_data/base64.patch25
3 files changed, 77 insertions, 7 deletions
diff --git a/gbp/patch_series.py b/gbp/patch_series.py
index c74a414a..ef373a83 100644
--- a/gbp/patch_series.py
+++ b/gbp/patch_series.py
@@ -19,9 +19,9 @@
import collections
import os
import re
-import subprocess
import tempfile
from gbp.errors import GbpError
+from gbp.git.repository import GitRepository
VALID_DEP3_ENDS = re.compile(r'(?:---|\*\*\*|Index:)[ \t][^ \t]|^diff -|^---')
@@ -68,17 +68,38 @@ class Patch(object):
using I{git mailinfo}
"""
self.info = {}
+ self.long_desc = ''
+
body = tempfile.NamedTemporaryFile(prefix='gbp_')
- pipe = subprocess.Popen("git mailinfo -k '%s' /dev/null 2>/dev/null < '%s'" %
- (body.name, self.path),
- shell=True,
- stdout=subprocess.PIPE).stdout
- for line in pipe:
- line = line.decode()
+
+ # No patch yet, file name information only
+ if not os.path.exists(self.path):
+ return
+ # The patch description might contain UTF-8 while the actual patch is ascii.
+ # To unconfuse git-mailinfo stop at the patch separator
+ toparse = []
+ for line in open(self.path, 'rb'):
+ if line == b'---\n':
+ break
+ toparse.append(line)
+
+ out, err, ret = GitRepository.git_inout(command='mailinfo',
+ args=['-k', body.name, '/dev/null'],
+ input=b''.join(toparse),
+ extra_env=None,
+ cwd=None,
+ capture_stderr=True)
+ if ret != 0:
+ raise GbpError("Failed to read patch header of '%s': %s" %
+ (self.path, err))
+
+ # Header
+ for line in out.decode().split('\n'):
if ':' in line:
rfc_header, value = line.split(" ", 1)
header = rfc_header[:-1].lower()
self.info[header] = value.strip()
+ # Body
try:
self.long_desc = "".join([l.decode("utf-8", "backslashreplace") for l in body])
except (IOError, UnicodeDecodeError) as msg:
diff --git a/tests/08_test_patch.py b/tests/08_test_patch.py
index c0f3e5ce..1567f018 100644
--- a/tests/08_test_patch.py
+++ b/tests/08_test_patch.py
@@ -102,3 +102,27 @@ usbip_common.c has the same problem.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
""",
p.long_desc)
+
+
+class TestBase64Patch(unittest.TestCase):
+ data_dir = os.path.splitext(__file__)[0] + '_data'
+
+ def test_parse(self):
+ """Get patch information from git mailimport with base64 body but plain text patch"""
+ patchfile = os.path.join(self.data_dir, "base64.patch")
+ self.assertTrue(os.path.exists(patchfile))
+ p = Dep3Patch(patchfile)
+ self.assertEqual("Sort files in archive (reproducible builds)", p.subject)
+ self.assertEqual("Nick Leverton", p.author)
+ self.assertEqual("nick@leverton.org", p.email)
+ self.assertEqual("""\
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: base64
+
+Sort files when using mergelib to create libnullmailer.a, to get
+reproducible build
+
+Author: Alexis Bienvenüe <pado@passoire.fr>
+""",
+ p.long_desc)
diff --git a/tests/08_test_patch_data/base64.patch b/tests/08_test_patch_data/base64.patch
new file mode 100644
index 00000000..c267be82
--- /dev/null
+++ b/tests/08_test_patch_data/base64.patch
@@ -0,0 +1,25 @@
+From: Nick Leverton <nick@leverton.org>
+Date: Tue, 11 Jul 2017 22:25:43 -0300
+Subject: Sort files in archive (reproducible builds)
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: base64
+
+U29ydCBmaWxlcyB3aGVuIHVzaW5nIG1lcmdlbGliIHRvIGNyZWF0ZSBsaWJudWxsbWFpbGVyLmEs
+IHRvIGdldApyZXByb2R1Y2libGUgYnVpbGQKCkF1dGhvcjogQWxleGlzIEJpZW52ZW7DvGUgPHBh
+ZG9AcGFzc29pcmUuZnI+Cg==
+---
+ lib/mergelib.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/mergelib.sh b/lib/mergelib.sh
+index f9b7a94..4e71079 100644
+--- a/lib/mergelib.sh
++++ b/lib/mergelib.sh
+@@ -12,5 +12,5 @@ for input in "$@"; do
+ "${AR:-ar}" x ../../"$input"
+ cd ..
+ done
+-"${AR:-ar}" rc ../"$archive" */*
++"${AR:-ar}" rc ../"$archive" `LC_ALL=C ls */*`
+ "${RANLIB:-ranlib}" ../"$archive"