diff --git a/fdroidserver/common.py b/fdroidserver/common.py index ca02219f..75eac97c 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -55,6 +55,8 @@ from .asynchronousfilereader import AsynchronousFileReader # A signature block file with a .DSA, .RSA, or .EC extension CERT_PATH_REGEX = re.compile(r'^META-INF/.*\.(DSA|EC|RSA)$') +APK_NAME_REGEX = re.compile(r'^([a-zA-Z][\w.]*)_(-?[0-9]+)_?([0-9a-f]{7})?\.apk') +STANDARD_FILE_NAME_REGEX = re.compile(r'^(\w[\w.]*)_(-?[0-9]+)\.\w+') XMLElementTree.register_namespace('android', 'http://schemas.android.com/apk/res/android') diff --git a/fdroidserver/update.py b/fdroidserver/update.py index caea795b..c36fd86e 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -853,14 +853,10 @@ def scan_repo_files(apkcache, repodir, knownapks, use_date_from_file=False): # the static ID is the SHA256 unless it is set in the metadata repo_file['packageName'] = shasum - n = name_utf8.rsplit('_', maxsplit=1) - if len(n) == 2: - packageName = n[0] - versionCode = n[1].split('.')[0] - if re.match('^-?[0-9]+$', versionCode) \ - and common.is_valid_package_name(n[0]): - repo_file['packageName'] = packageName - repo_file['versionCode'] = int(versionCode) + m = common.STANDARD_FILE_NAME_REGEX.match(name_utf8) + if m: + repo_file['packageName'] = m.group(1) + repo_file['versionCode'] = int(m.group(2)) srcfilename = name + b'_src.tar.gz' if os.path.exists(os.path.join(repodir, srcfilename)): repo_file['srcname'] = srcfilename.decode('utf-8') diff --git a/tests/common.TestCase b/tests/common.TestCase index 74364098..f0dcacce 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -281,6 +281,70 @@ class CommonTest(unittest.TestCase): key = "val" """)) + def test_apk_name_regex(self): + good = [ + 'urzipπÇÇπÇÇ现代汉语通用字българскиعربي1234ö_-123456.apk', + 'urzipπÇÇπÇÇ现代汉语通用字българскиعربي1234ö_123456_abcdef0.apk', + 'urzip_-123456.apk', + 'a0_0.apk', + 'Z0_0.apk', + 'a0_0_abcdef0.apk', + 'a_a_a_a_0_abcdef0.apk', + 'a_____0.apk', + 'a_____123456_abcdef0.apk', + 'org.fdroid.fdroid_123456.apk', + # valid, but "_99999" is part of packageName rather than versionCode + 'org.fdroid.fdroid_99999_123456.apk', + # should be valid, but I can't figure out the regex since \w includes digits + # 'πÇÇπÇÇ现代汉语通用字българскиعربي1234ö_0_123bafd.apk', + ] + for name in good: + m = fdroidserver.common.APK_NAME_REGEX.match(name) + self.assertIsNotNone(m) + self.assertIn(m.group(2), ('-123456', '0', '123456')) + self.assertIn(m.group(3), ('abcdef0', None)) + + bad = [ + 'urzipπÇÇπÇÇ现代汉语通用字българскиعربي1234ö_123456_abcdefg.apk', + 'urzip-_-198274.apk', + 'urzip-_0_123bafd.apk', + 'no spaces allowed_123.apk', + '0_0.apk', + '0_0_abcdef0.apk', + ] + for name in bad: + self.assertIsNone(fdroidserver.common.APK_NAME_REGEX.match(name)) + + def test_standard_file_name_regex(self): + good = [ + 'urzipπÇÇπÇÇ现代汉语通用字българскиعربي1234ö_-123456.mp3', + 'urzipπÇÇπÇÇ现代汉语通用字българскиعربي1234ö_123456.mov', + 'Document_-123456.pdf', + 'WTF_0.MOV', + 'Z0_0.ebk', + 'a_a_a_a_0.txt', + 'org.fdroid.fdroid.privileged.ota_123456.zip', + 'πÇÇπÇÇ现代汉语通用字българскиعربي1234ö_0.jpeg', + 'a_____0.PNG', + # valid, but "_99999" is part of packageName rather than versionCode + 'a_____99999_123456.zip', + 'org.fdroid.fdroid_99999_123456.zip', + ] + for name in good: + m = fdroidserver.common.STANDARD_FILE_NAME_REGEX.match(name) + self.assertIsNotNone(m) + self.assertIn(m.group(2), ('-123456', '0', '123456')) + + bad = [ + 'urzipπÇÇπÇÇ现代汉语通用字българскиعربي1234ö_abcdefg.JPEG', + 'urzip-_-198274.zip', + 'urzip-_123bafd.pdf', + 'no spaces allowed_123.foobar', + 'a_____0.', + ] + for name in bad: + self.assertIsNone(fdroidserver.common.STANDARD_FILE_NAME_REGEX.match(name)) + if __name__ == "__main__": parser = optparse.OptionParser() diff --git a/tests/stats/known_apks.txt b/tests/stats/known_apks.txt index ec777242..329213b7 100644 --- a/tests/stats/known_apks.txt +++ b/tests/stats/known_apks.txt @@ -1,4 +1,4 @@ -fake.ota.update_1234.zip 897a92a4ccff4f415f6ba275b2af16d4ecaee60a983b215bddcb9f8964e7a24c 2016-03-10 +fake.ota.update_1234.zip fake.ota.update 2016-03-10 obb.main.oldversion_1444412523.apk obb.main.oldversion 2013-12-31 obb.main.twoversions_1101613.apk obb.main.twoversions 2015-10-12 obb.main.twoversions_1101615.apk obb.main.twoversions 2016-01-01