diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 63479af1..84f19ed5 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -720,8 +720,10 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext f"{app.id}:{build.versionName}", p.output) # Make sure it's not debuggable... - if common.is_apk_and_debuggable(src): - raise BuildException("APK is debuggable") + if common.is_debuggable_or_testOnly(src): + raise BuildException( + "%s: debuggable or testOnly set in AndroidManifest.xml" % src + ) # By way of a sanity check, make sure the version and version # code in our new APK match what we expect... diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 87010370..66dd106e 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2677,10 +2677,13 @@ def ensure_final_value(packageName, arsc, value): return '' -def is_apk_and_debuggable(apkfile): - """Return True if the given file is an APK and is debuggable. +def is_debuggable_or_testOnly(apkfile): + """Return True if the given file is an APK and is debuggable or testOnly. - Parse only from the APK. + These two settings should never be enabled in release builds. This + parses + from the APK and nothing else to run fast, since it is run on + every APK as part of update. Parameters ---------- @@ -2699,7 +2702,7 @@ def is_apk_and_debuggable(apkfile): if _type == START_TAG and axml.getName() == 'application': for i in range(0, axml.getAttributeCount()): name = axml.getAttributeName(i) - if name == 'debuggable': + if name in ('debuggable', 'testOnly'): _type = axml.getAttributeValueType(i) _data = axml.getAttributeValueData(i) value = format_value(_type, _data, lambda _: axml.getAttributeValue(i)) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 26e248d5..eaf1bb8b 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -1616,8 +1616,10 @@ def process_apk(apkcache, apkfilename, repodir, knownapks, use_date_from_apk=Fal return True, None, False # Check for debuggable apks... - if common.is_apk_and_debuggable(apkfile): - logging.warning('{0} is set to android:debuggable="true"'.format(apkfile)) + if common.is_debuggable_or_testOnly(apkfile): + logging.warning( + "%s: debuggable or testOnly set in AndroidManifest.xml" % apkfile + ) if options.rename_apks: n = apk['packageName'] + '_' + str(apk['versionCode']) + '.apk' diff --git a/tests/build.TestCase b/tests/build.TestCase index cce6a424..6a4ddb02 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -221,7 +221,7 @@ class BuildTest(unittest.TestCase): @mock.patch('fdroidserver.common.get_apk_id') @mock.patch('fdroidserver.build.FDroidPopen') - @mock.patch('fdroidserver.common.is_apk_and_debuggable', lambda f: False) + @mock.patch('fdroidserver.common.is_debuggable_or_testOnly', lambda f: False) @mock.patch('fdroidserver.common.get_native_code', lambda f: 'x86') def test_build_local_maven(self, fake_FDroidPopen, fake_get_apk_id): """Test build_local() with a maven project""" @@ -342,7 +342,8 @@ class BuildTest(unittest.TestCase): 'fdroidserver.common.sha256sum', return_value='ad7ce5467e18d40050dc51b8e7affc3e635c85bd8c59be62de32352328ed467e', ) as _ignored, mock.patch( - 'fdroidserver.common.is_apk_and_debuggable', return_value=False + 'fdroidserver.common.is_debuggable_or_testOnly', + return_value=False, ) as _ignored, mock.patch( 'fdroidserver.build.FDroidPopen', FakeProcess ) as _ignored, mock.patch( @@ -394,7 +395,7 @@ class BuildTest(unittest.TestCase): @mock.patch('sdkmanager.build_package_list', lambda use_net: None) @mock.patch('fdroidserver.build.FDroidPopen', FakeProcess) @mock.patch('fdroidserver.common.get_native_code', lambda _ignored: 'x86') - @mock.patch('fdroidserver.common.is_apk_and_debuggable', lambda _ignored: False) + @mock.patch('fdroidserver.common.is_debuggable_or_testOnly', lambda _ignored: False) @mock.patch( 'fdroidserver.common.sha256sum', lambda f: 'ad7ce5467e18d40050dc51b8e7affc3e635c85bd8c59be62de32352328ed467e', @@ -531,7 +532,8 @@ class BuildTest(unittest.TestCase): return_value=(app.id, build.versionCode, build.versionName), ): with mock.patch( - 'fdroidserver.common.is_apk_and_debuggable', return_value=False + 'fdroidserver.common.is_debuggable_or_testOnly', + return_value=False, ): fdroidserver.build.build_local( app, diff --git a/tests/common.TestCase b/tests/common.TestCase index a92dc92a..543e8eb6 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -185,7 +185,7 @@ class CommonTest(unittest.TestCase): fdroidserver.common._add_java_paths_to_config(pathlist, config) self.assertEqual(config['java_paths']['8'], choice[1:]) - def test_is_apk_and_debuggable(self): + def test_is_debuggable_or_testOnly(self): config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config @@ -197,7 +197,7 @@ class CommonTest(unittest.TestCase): testfiles.append(os.path.join(self.basedir, 'urzip-badcert.apk')) for apkfile in testfiles: self.assertTrue( - fdroidserver.common.is_apk_and_debuggable(apkfile), + fdroidserver.common.is_debuggable_or_testOnly(apkfile), "debuggable APK state was not properly parsed!", ) @@ -208,7 +208,7 @@ class CommonTest(unittest.TestCase): testfiles.append(os.path.join(self.basedir, 'v2.only.sig_2.apk')) for apkfile in testfiles: self.assertFalse( - fdroidserver.common.is_apk_and_debuggable(apkfile), + fdroidserver.common.is_debuggable_or_testOnly(apkfile), "debuggable APK state was not properly parsed!", ) diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index aba95323..83ce75b7 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -276,7 +276,8 @@ class ScannerTest(unittest.TestCase): return_value=(app.id, build.versionCode, build.versionName), ): with mock.patch( - 'fdroidserver.common.is_apk_and_debuggable', return_value=False + 'fdroidserver.common.is_debuggable_or_testOnly', + return_value=False, ): fdroidserver.build.build_local( app,