chiark / gitweb /
compare apk with Binaries from metadata right after building
authorMichael Pöhn <michael.poehn@fsfe.org>
Tue, 4 Apr 2017 16:58:16 +0000 (18:58 +0200)
committerMichael Pöhn <michael.poehn@fsfe.org>
Sat, 22 Apr 2017 08:48:50 +0000 (10:48 +0200)
fdroidserver/build.py
fdroidserver/common.py

index c63df9d14a07711dcd23be46109fde1d85dfa9ca..e41b5d6ae071b2250f1397f4e07520d61416f367 100644 (file)
@@ -28,6 +28,7 @@ import traceback
 import time
 import json
 import requests
+import tempfile
 from configparser import ConfigParser
 from argparse import ArgumentParser
 import logging
@@ -1218,8 +1219,42 @@ def main():
                         except requests.exceptions.HTTPError as e:
                             raise FDroidException('downloading Binaries from %s failed' % url) from e
 
+                        # Now we check weather the build can be verified to
+                        # match the supplied binary or not. Should the
+                        # comparison fail, we mark this build as a failure
+                        # and remove everything from the unsigend folder.
+                        with tempfile.TemporaryDirectory() as tmpdir:
+                            unsigned_apk = \
+                                '{0}_{1}.apk'.format(appid,
+                                                     build.versionCode)
+                            unsigned_apk = os.path.join(output_dir,
+                                                        unsigned_apk)
+                            compare_result = \
+                                common.compare_apks(of, unsigned_apk,
+                                                    tmpdir, log_dir,
+                                                    skip_manual_diff=True)
+                            if compare_result:
+                                compare_result = compare_result.split('\n')
+                                line_count = len(compare_result)
+                                compare_result = compare_result[:299]
+                                if line_count > len(compare_result):
+                                    line_difference = \
+                                        line_count - len(compare_result)
+                                    compare_result.append('%d more lines ...' %
+                                                          line_difference)
+                                compare_result = '\n'.join(compare_result)
+                                raise FDroidException('compared built binary '
+                                                      'to supplied reference '
+                                                      'binary but failed',
+                                                      compare_result)
+                            else:
+                                logging.info('compared built binary to '
+                                             'supplied reference binary '
+                                             'successfully')
+
                     build_succeeded.append(app)
                     wikilog = "Build succeeded"
+
             except VCSException as vcse:
                 reason = str(vcse).split('\n', 1)[0] if options.verbose else str(vcse)
                 logging.error("VCS error while building app %s: %s" % (
index 8ced40c97a72cd6d7c9cbcbab452908480b52374..181c1fd9da4c54c3a13b56d9c9f8592df2c95173 100644 (file)
@@ -2049,7 +2049,7 @@ def verify_apk_signature(apk, jar=False):
 apk_badchars = re.compile('''[/ :;'"]''')
 
 
-def compare_apks(apk1, apk2, tmp_dir, log_dir=None):
+def compare_apks(apk1, apk2, tmp_dir, log_dir=None, skip_manual_diff=False):
     """Compare two apks
 
     Returns None if the apk content is the same (apart from the signing key),
@@ -2101,9 +2101,10 @@ def compare_apks(apk1, apk2, tmp_dir, log_dir=None):
     p = FDroidPopen(['diff', '-r', apk1dir, apk2dir], output=False)
     lines = p.output.splitlines()
     if len(lines) != 1 or 'META-INF' not in lines[0]:
-        meld = find_command('meld')
-        if meld is not None:
-            p = FDroidPopen(['meld', apk1dir, apk2dir], output=False)
+        if not skip_manual_diff:
+            meld = find_command('meld')
+            if meld is not None:
+                p = FDroidPopen(['meld', apk1dir, apk2dir], output=False)
         return("Unexpected diff output - " + p.output)
 
     # since everything verifies, delete the comparison to keep cruft down