diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 3c7d7dc0..f4da28a4 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2629,29 +2629,12 @@ def get_file_extension(filename): return os.path.splitext(filename)[1].lower()[1:] -def use_androguard(): - """Report if androguard is available, and config its debug logging.""" - try: - import androguard - if use_androguard.show_path: - logging.debug(_('Using androguard from "{path}"').format(path=androguard.__file__)) - use_androguard.show_path = False - if options and options.verbose: - logging.getLogger("androguard.axml").setLevel(logging.INFO) - logging.getLogger("androguard.core.api_specific_resources").setLevel(logging.ERROR) - return True - except ImportError: - return False - - -use_androguard.show_path = True # type: ignore - - def get_androguard_APK(apkfile): try: + # these were moved in androguard 4.0 + from androguard.core.apk import APK + except ImportError: from androguard.core.bytecodes.apk import APK - except ImportError as exc: - raise FDroidException("androguard library is not installed") from exc return APK(apkfile) @@ -2693,7 +2676,11 @@ def is_debuggable_or_testOnly(apkfile): """ if get_file_extension(apkfile) != 'apk': return False - from androguard.core.bytecodes.axml import AXMLParser, format_value, START_TAG + try: + # these were moved in androguard 4.0 + from androguard.core.axml import AXMLParser, format_value, START_TAG + except ImportError: + from androguard.core.bytecodes.axml import AXMLParser, format_value, START_TAG with ZipFile(apkfile) as apk: with apk.open('AndroidManifest.xml') as manifest: axml = AXMLParser(manifest.read()) @@ -2753,12 +2740,19 @@ def get_apk_id_androguard(apkfile): versionName is set to a Android String Resource (e.g. an integer hex value that starts with @). + This function is part of androguard as get_apkid(), so this + vendored and modified to return versionCode as an integer. + """ if not os.path.exists(apkfile): raise FDroidException(_("Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'") .format(apkfilename=apkfile)) - from androguard.core.bytecodes.axml import AXMLParser, format_value, START_TAG, END_TAG, TEXT, END_DOCUMENT + try: + # these were moved in androguard 4.0 + from androguard.core.axml import AXMLParser, format_value, START_TAG, END_TAG, TEXT, END_DOCUMENT + except ImportError: + from androguard.core.bytecodes.axml import AXMLParser, format_value, START_TAG, END_TAG, TEXT, END_DOCUMENT appid = None versionCode = None @@ -3159,7 +3153,7 @@ def get_first_signer_certificate(apkpath): elif len(cert_files) == 1: cert_encoded = get_certificate(apk.read(cert_files[0])) - if not cert_encoded and use_androguard(): + if not cert_encoded: apkobject = get_androguard_APK(apkpath) certs = apkobject.get_certificates_der_v2() if len(certs) > 0: diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 23e3d604..be3824bd 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -1722,8 +1722,7 @@ def _sanitize_sdk_version(value): def scan_apk_androguard(apk, apkfile): try: - from androguard.core.bytecodes.apk import APK - apkobject = APK(apkfile) + apkobject = common.get_androguard_APK(apkfile) if apkobject.is_valid_APK(): arsc = apkobject.get_android_resources() else: @@ -2581,7 +2580,6 @@ def main(): config = common.read_config(options) common.setup_status_output(start_timestamp) - common.use_androguard() if not (('jarsigner' in config or 'apksigner' in config) and 'keytool' in config): raise FDroidException(_('Java JDK not found! Install in standard location or set java_paths!')) diff --git a/setup.py b/setup.py index 49548f78..94e43e98 100755 --- a/setup.py +++ b/setup.py @@ -92,7 +92,7 @@ setup( ], install_requires=[ 'appdirs', - 'androguard >= 3.1.0, != 3.3.0, != 3.3.1, != 3.3.2, <4', + 'androguard >= 3.3.3', 'clint', 'defusedxml', 'GitPython', diff --git a/tests/run-tests b/tests/run-tests index ca9aa951..31cb4939 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -8,7 +8,9 @@ echo_header() { get_fdroid_apk_filename() { if [ -z $aapt ]; then - python3 -c "from androguard.core.bytecodes.apk import APK; a=APK('$1'); print(a.package+'_'+a.get_androidversion_code()+'.apk')" + appid=$(androguard apkid "$1" | sed -En 's/ +"([a-z][^"]+)",$/\1/ip') + versionCode=$(androguard apkid "$1" | sed -En 's/ +"([0-9]+)",$/\1/p') + echo "${appid}_${versionCode}.apk" else $aapt dump badging "$1" | sed -n "s,^package: name='\(.*\)' versionCode='\([0-9][0-9]*\)' .*,\1_\2.apk,p" fi diff --git a/tests/update.TestCase b/tests/update.TestCase index 2ab19a3a..232537ca 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -5,6 +5,7 @@ import copy import git import glob +import hashlib import inspect import json import logging @@ -20,11 +21,18 @@ import unittest import yaml import zipfile import textwrap +from binascii import hexlify from datetime import datetime from pathlib import Path from testcommon import TmpCwd, mkdtemp from unittest import mock +try: + # these were moved in androguard 4.0 + from androguard.core.apk import APK +except ImportError: + from androguard.core.bytecodes.apk import APK + try: from yaml import CSafeLoader as SafeLoader except ImportError: @@ -581,13 +589,6 @@ class UpdateTest(unittest.TestCase): self.assertEqual(good_fingerprint, sig, 'python sig was: ' + str(sig)) # check that v1 and v2 have the same certificate - try: - import hashlib - from binascii import hexlify - from androguard.core.bytecodes.apk import APK - except ImportError: - print('WARNING: skipping rest of test since androguard is missing!') - return apkobject = APK(apkpath) cert_encoded = apkobject.get_certificates_der_v2()[0] self.assertEqual(good_fingerprint, sig,