From e588316411e8c9d6290dfddd74a4eaa7d0eb7a25 Mon Sep 17 00:00:00 2001 From: Konstantin Ryabitsev Date: Mon, 20 Apr 2020 12:46:35 -0400 Subject: Support file delete patches and binary patches Git's file delete patches don't contain hunks, so we weren't properly processing them for attestation (and for b4 am). While fixing that, I also added attestation support for binary patches. Reported-by: Geert Uytterhoeven Signed-off-by: Konstantin Ryabitsev --- b4/__init__.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/b4/__init__.py b/b4/__init__.py index 2d2e730..c20258b 100644 --- a/b4/__init__.py +++ b/b4/__init__.py @@ -549,7 +549,7 @@ class LoreMessage: self.date = email.utils.parsedate_to_datetime(str(self.msg['Date'])) - diffre = re.compile(r'^(---.*\n\+\+\+|GIT binary patch)', re.M | re.I) + diffre = re.compile(r'^(---.*\n\+\+\+|GIT binary patch|diff --git \w/\S+ \w/\S+)', re.M | re.I) diffstatre = re.compile(r'^\s*\d+ file.*\d+ (insertion|deletion)', re.M | re.I) # walk until we find the first text/plain part @@ -707,7 +707,6 @@ class LoreMessage: # # This subroutine removes anything at the beginning of diff data, like # diffstat or any other auxiliary data, and anything trailing at the end - # XXX: This currently doesn't work for git binary patches # diff = diff.replace('\r', '') @@ -718,8 +717,31 @@ class LoreMessage: # Used for counting where we are in the patch pp = mm = 0 + inside_binary_chunk = False for line in diff.split('\n'): if not len(line): + if inside_binary_chunk: + inside_binary_chunk = False + # add all buflines to difflines + phasher.update(('\n'.join(buflines) + '\n\n').encode('utf-8')) + buflines = list() + continue + buflines.append(line) + continue + elif inside_binary_chunk: + buflines.append(line) + continue + # If line starts with 'index ' and previous line starts with 'deleted ', then + # it's a file delete and therefore doesn't have a regular hunk. + if line.find('index ') == 0 and len(buflines) > 1 and buflines[-1].find('deleted ') == 0: + # add this and 2 preceding lines to difflines and reset buflines + buflines.append(line) + phasher.update(('\n'.join(buflines[-3:]) + '\n').encode('utf-8')) + buflines = list() + continue + if line.find('delta ') == 0 or line.find('literal ') == 0: + # we are inside a binary patch + inside_binary_chunk = True buflines.append(line) continue hunk_match = HUNK_RE.match(line) -- cgit v1.2.3