diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index c6370870c..838ad2fde 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -37,6 +37,7 @@ from ..interpreterbase import FeatureNew, FeatureDeprecated, FeatureBroken, Feat from ..interpreterbase import ObjectHolder, ContextManagerObject from ..interpreterbase import stringifyUserArguments from ..modules import ExtensionModule, ModuleObject, MutableModuleObject, NewExtensionModule, NotFoundExtensionModule +from ..optinterpreter import optname_regex from . import interpreterobjects as OBJ from . import compiler as compilerOBJ @@ -1090,6 +1091,10 @@ class Interpreter(InterpreterBase, HoldableObject): raise InterpreterException('Having a colon in option name is forbidden, ' 'projects are not allowed to directly access ' 'options of other subprojects.') + + if optname_regex.search(optname.split('.', maxsplit=1)[-1]) is not None: + raise InterpreterException(f'Invalid option name {optname!r}') + opt = self.get_option_internal(optname) if isinstance(opt, coredata.UserFeatureOption): opt.name = optname diff --git a/test cases/common/40 options/meson.build b/test cases/common/40 options/meson.build index a10ff28f0..de4a7d50d 100644 --- a/test cases/common/40 options/meson.build +++ b/test cases/common/40 options/meson.build @@ -46,3 +46,11 @@ assert(get_option('wrap_mode') == 'default', 'Wrap mode option is broken.') assert(get_option('boolean_string') == false) assert(get_option('boolean_string2') == true) assert(get_option('integer_string') == 42) + +testcase expect_error('Invalid option name \'..invalid\'') + get_option('..invalid') +endtestcase + +testcase expect_error('Invalid option name \'this.is.also.invalid\'') + get_option('this.is.also.invalid') +endtestcase