diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index bfa380e7..9eaf4b19 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -473,6 +473,29 @@ def check_extlib_dir(apps): yield _("Unused extlib at %s") % os.path.join(dir_path, path) +def check_app_field_types(app): + """Check the fields have valid data types""" + + for field in app.keys(): + v = app.get(field) + t = metadata.fieldtype(field) + if v is None: + continue + elif field == 'builds': + if not isinstance(v, list): + yield(_("{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!") + .format(appid=app.id, field=field, + type='list', fieldtype=v.__class__.__name__)) + elif t == metadata.TYPE_LIST and not isinstance(v, list): + yield(_("{appid}: {field} must be a '{type}', but it is a '{fieldtype}!'") + .format(appid=app.id, field=field, + type='list', fieldtype=v.__class__.__name__)) + elif t == metadata.TYPE_STRING and not type(v) in (str, bool, dict): + yield(_("{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!") + .format(appid=app.id, field=field, + type='str', fieldtype=v.__class__.__name__)) + + def check_for_unsupported_metadata_files(basedir=""): """Checks whether any non-metadata files are in metadata/""" @@ -538,6 +561,7 @@ def main(): continue app_check_funcs = [ + check_app_field_types, check_regexes, check_update_check_data_url, check_vercode_operation, diff --git a/tests/lint.TestCase b/tests/lint.TestCase index 8255957c..2670c3dd 100755 --- a/tests/lint.TestCase +++ b/tests/lint.TestCase @@ -70,6 +70,59 @@ class LintTest(unittest.TestCase): logging.debug(warn) self.assertTrue(anywarns) + def test_check_app_field_types(self): + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.lint.config = config + + app = fdroidserver.metadata.App() + app.id = 'fake.app' + app.Name = 'Bad App' + app.Summary = 'We pwn you' + app.Description = 'These are some back' + + fields = { + 'AntiFeatures': { + 'good': [ + ['KnownVuln', ], + ['NonFreeNet', 'KnownVuln'], + ], + 'bad': [ + 'KnownVuln', + 'NonFreeNet,KnownVuln', + ], + }, + 'Categories': { + 'good': [ + ['Sports & Health', ], + ['Multimedia', 'Graphics'], + ], + 'bad': [ + 'Science & Education', + 'Multimedia,Graphics', + ], + }, + } + + for field, values in fields.items(): + + for bad in values['bad']: + anywarns = False + app[field] = bad + for warn in fdroidserver.lint.check_app_field_types(app): + anywarns = True + logging.debug(warn) + self.assertTrue(anywarns) + + for good in values['good']: + anywarns = False + app[field] = good + for warn in fdroidserver.lint.check_app_field_types(app): + anywarns = True + logging.debug(warn) + self.assertFalse(anywarns) + def test_check_vercode_operation(self): config = dict() fdroidserver.common.fill_config_defaults(config)