diff --git a/fdroidserver/common.py b/fdroidserver/common.py index b2d1ae85..a0940154 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -399,6 +399,11 @@ def read_config(opts=None): config = yaml.safe_load(fp) if not config: config = {} + if not isinstance(config, dict): + msg = _('{path} is not "key: value" dict, but a {datatype}!') + raise TypeError( + msg.format(path=config_file, datatype=type(config).__name__) + ) elif os.path.exists(old_config_file): logging.warning(_("""{oldfile} is deprecated, use {newfile}""") .format(oldfile=old_config_file, newfile=config_file)) @@ -528,6 +533,9 @@ def load_localized_config(name, repodir): locale = DEFAULT_LOCALE with open(f, encoding="utf-8") as fp: elem = yaml.safe_load(fp) + if not isinstance(elem, dict): + msg = _('{path} is not "key: value" dict, but a {datatype}!') + raise TypeError(msg.format(path=f, datatype=type(elem).__name__)) for afname, field_dict in elem.items(): if afname not in ret: ret[afname] = dict() diff --git a/tests/common.TestCase b/tests/common.TestCase index 66c5f184..d98ed24b 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -1919,6 +1919,18 @@ class CommonTest(unittest.TestCase): config = fdroidserver.common.read_config(fdroidserver.common.options) self.assertEqual(os.getenv('SECRET', 'fail'), config.get('keypass')) + def test_with_config_yml_is_dict(self): + os.chdir(self.tmpdir) + Path('config.yml').write_text('apksigner = /placeholder/path') + with self.assertRaises(TypeError): + fdroidserver.common.read_config(fdroidserver.common.options) + + def test_with_config_yml_is_not_mixed_type(self): + os.chdir(self.tmpdir) + Path('config.yml').write_text('k: v\napksigner = /placeholder/path') + with self.assertRaises(yaml.scanner.ScannerError): + fdroidserver.common.read_config(fdroidserver.common.options) + def test_with_config_py(self): """Make sure it is still possible to use config.py alone.""" os.chdir(self.tmpdir) @@ -2716,6 +2728,27 @@ class CommonTest(unittest.TestCase): ) self.assertEqual(['en-US'], list(categories['GuardianProject']['name'].keys())) + def test_load_localized_config_0_file(self): + os.chdir(self.testdir) + os.mkdir('config') + Path('config/categories.yml').write_text('') + with self.assertRaises(TypeError): + fdroidserver.common.load_localized_config(CATEGORIES_CONFIG_NAME, 'repo') + + def test_load_localized_config_string(self): + os.chdir(self.testdir) + os.mkdir('config') + Path('config/categories.yml').write_text('this is a string') + with self.assertRaises(TypeError): + fdroidserver.common.load_localized_config(CATEGORIES_CONFIG_NAME, 'repo') + + def test_load_localized_config_list(self): + os.chdir(self.testdir) + os.mkdir('config') + Path('config/categories.yml').write_text('- System') + with self.assertRaises(TypeError): + fdroidserver.common.load_localized_config(CATEGORIES_CONFIG_NAME, 'repo') + if __name__ == "__main__": os.chdir(os.path.dirname(__file__))