From 84dfd6b06af1799d776a72af13d5c32642bda84e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 17 Jul 2018 12:32:18 +0200 Subject: [PATCH] update: more reliable handling of XMLNS with androguard Sometimes androguard returns the XMLNS as entirely empty, which would make it an invalid APK since normally the 'android' name is mapped to the 'http://schemas.amazon.com/apk/res/android' value. Occasionally, a different key is used. closes fdroid/fdroidserver#515 --- fdroidserver/update.py | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 6d1ddcfa..bf848061 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -1231,7 +1231,19 @@ def scan_apk_androguard(apk, apkfile): raise BuildException(_("Invalid APK")) apk['packageName'] = apkobject.get_package() - vcstr = apkobject.get_androidversion_code() + + xml = apkobject.get_android_manifest_xml() + androidmanifest_xml = apkobject.xml['AndroidManifest.xml'] + if len(xml.nsmap) > 0: + # one of them surely will be the Android one, or its corrupt + xmlns = '{http://schemas.android.com/apk/res/android}' + else: + # strange but sometimes the namespace is blank. This seems to + # only happen with the Bromite/Chromium APKs + xmlns = '{}' + + vcstr = androidmanifest_xml.get(xmlns + 'versionCode') + if vcstr.startswith('0x'): apk['versionCode'] = int(vcstr, 16) else: @@ -1239,7 +1251,7 @@ def scan_apk_androguard(apk, apkfile): apk['name'] = apkobject.get_app_name() apk['versionName'] = common.ensure_final_value(apk['packageName'], arsc, - apkobject.get_androidversion_name()) + androidmanifest_xml.get(xmlns + 'versionName')) minSdkVersion = _sanitize_sdk_version(apkobject.get_min_sdk_version()) if minSdkVersion is not None: @@ -1270,14 +1282,9 @@ def scan_apk_androguard(apk, apkfile): apk['nativecode'] = [] apk['nativecode'].extend(sorted(list(arch))) - xml = apkobject.get_android_manifest_xml() - xmlns = xml.nsmap.get('android') - if not xmlns: - xmlns = 'http://schemas.android.com/apk/res/android' - for item in xml.findall('uses-permission'): - name = str(item.attrib['{' + xmlns + '}name']) - maxSdkVersion = item.attrib.get('{' + xmlns + '}maxSdkVersion') + name = str(item.attrib[xmlns + 'name']) + maxSdkVersion = item.attrib.get(xmlns + 'maxSdkVersion') maxSdkVersion = int(maxSdkVersion) if maxSdkVersion else None permission = UsesPermission( name, @@ -1292,8 +1299,8 @@ def scan_apk_androguard(apk, apkfile): apk['uses-permission'].append(permission) for item in xml.findall('uses-permission-sdk-23'): - name = str(item.attrib['{' + xmlns + '}name']) - maxSdkVersion = item.attrib.get('{' + xmlns + '}maxSdkVersion') + name = str(item.attrib[xmlns + 'name']) + maxSdkVersion = item.attrib.get(xmlns + 'maxSdkVersion') maxSdkVersion = int(maxSdkVersion) if maxSdkVersion else None permission_sdk_23 = UsesPermissionSdk23( name, @@ -1302,7 +1309,7 @@ def scan_apk_androguard(apk, apkfile): apk['uses-permission-sdk-23'].append(permission_sdk_23) for item in xml.findall('uses-feature'): - key = '{' + xmlns + '}name' + key = xmlns + 'name' if key not in item.attrib: continue feature = str(item.attrib[key]) @@ -1310,7 +1317,7 @@ def scan_apk_androguard(apk, apkfile): and feature != "android.hardware.screen.landscape": if feature.startswith("android.feature."): feature = feature[16:] - required = item.attrib.get('{' + xmlns + '}required') + required = item.attrib.get(xmlns + 'required') if required is None or required == 'true': apk['features'].append(feature)