diff options
8 files changed, 38 insertions, 10 deletions
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 5bac8ba..bac5f48 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -670,6 +670,18 @@ class Interpreter(InterpreterBase, HoldableObject): d_module_versions = extract_as_list(kwargs, 'd_module_versions') d_import_dirs = self.extract_incdirs(kwargs, 'd_import_dirs') final_deps = [] + srcdir = Path(self.environment.source_dir) + # convert variables which refer to an -uninstalled.pc style datadir + for k, v in variables.items(): + try: + p = Path(v) + except ValueError: + continue + else: + if not self.is_subproject() and srcdir / self.subproject_dir in p.parents: + continue + if p.is_absolute() and p.is_dir() and srcdir / self.root_subdir in p.resolve().parents: + variables[k] = P_OBJ.DependencyVariableString(v) for d in deps: if not isinstance(d, (dependencies.Dependency, dependencies.ExternalLibrary, dependencies.InternalDependency)): raise InterpreterException('Dependencies must be external deps') @@ -2718,8 +2730,9 @@ external dependencies (including libraries) must go to "dependencies".''') @noKwargs def func_join_paths(self, node: mparser.BaseNode, args: T.Tuple[T.List[str]], kwargs: 'TYPE_kwargs') -> str: parts = args[0] + other = os.path.join('', *parts[1:]).replace('\\', '/') ret = os.path.join(*parts).replace('\\', '/') - if isinstance(parts[0], P_OBJ.DependencyVariableString): + if isinstance(parts[0], P_OBJ.DependencyVariableString) and '..' not in other: return P_OBJ.DependencyVariableString(ret) else: return ret @@ -2783,7 +2796,7 @@ Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey norm = Path(fname) # variables built from a dep.get_variable are allowed to refer to # subproject files, as long as they are scheduled to be installed. - if norm.is_absolute() and '..' not in norm.parts and validate_installable_file(norm): + if validate_installable_file(norm): return norm = Path(srcdir, subdir, fname).resolve() if os.path.isdir(norm): diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py index 4aa5548..39085e5 100644 --- a/mesonbuild/interpreter/interpreterobjects.py +++ b/mesonbuild/interpreter/interpreterobjects.py @@ -21,7 +21,6 @@ from ..interpreterbase import ( typed_pos_args, typed_kwargs, typed_operator, noArgsFlattening, noPosargs, noKwargs, unholder_return, flatten, resolve_second_level_holders, InterpreterException, InvalidArguments, InvalidCode) -from ..interpreter.primitives import DependencyVariableString from ..interpreter.type_checking import NoneType, ENV_SEPARATOR_KW from ..dependencies import Dependency, ExternalLibrary, InternalDependency from ..programs import ExternalProgram @@ -484,14 +483,14 @@ class DependencyHolder(ObjectHolder[Dependency]): default_varname = args[0] if default_varname is not None: FeatureNew('Positional argument to dependency.get_variable()', '0.58.0').use(self.subproject, self.current_node) - return DependencyVariableString(self.held_object.get_variable( + return self.held_object.get_variable( cmake=kwargs['cmake'] or default_varname, pkgconfig=kwargs['pkgconfig'] or default_varname, configtool=kwargs['configtool'] or default_varname, internal=kwargs['internal'] or default_varname, default_value=kwargs['default_value'], pkgconfig_define=kwargs['pkgconfig_define'], - )) + ) @FeatureNew('dependency.include_type', '0.52.0') @noPosargs diff --git a/mesonbuild/interpreter/primitives/string.py b/mesonbuild/interpreter/primitives/string.py index bf213ef..1fd6e92 100644 --- a/mesonbuild/interpreter/primitives/string.py +++ b/mesonbuild/interpreter/primitives/string.py @@ -189,5 +189,8 @@ class DependencyVariableString(str): pass class DependencyVariableStringHolder(StringHolder): - def op_div(self, other: str) -> DependencyVariableString: - return DependencyVariableString(super().op_div(other)) + def op_div(self, other: str) -> T.Union[str, DependencyVariableString]: + ret = super().op_div(other) + if '..' in other: + return ret + return DependencyVariableString(ret) diff --git a/test cases/failing/123 subproject sandbox violation/meson.build b/test cases/failing/123 subproject sandbox violation/meson.build index 0070eb6..d41994c 100644 --- a/test cases/failing/123 subproject sandbox violation/meson.build +++ b/test cases/failing/123 subproject sandbox violation/meson.build @@ -6,10 +6,19 @@ sub1_mustfail = sub1_d.get_variable('dir') / '..' / 'file.txt' sub2_d = subproject('subproj2').get_variable('d') sub2_mustfail = sub2_d.get_variable('dir') / 'file.txt' +main_d = declare_dependency( + variables: [ + 'dir=@0@'.format(meson.current_source_dir()), + ] +) +main_mustfail = main_d.get_variable('dir') / 'subprojects/subproj3/file.txt' + if get_option('failmode') == 'parent-dir' mustfail = sub1_mustfail elif get_option('failmode') == 'not-installed' mustfail = sub2_mustfail +elif get_option('failmode') == 'root-subdir' + mustfail = main_mustfail endif custom_target( diff --git a/test cases/failing/123 subproject sandbox violation/meson_options.txt b/test cases/failing/123 subproject sandbox violation/meson_options.txt index cee2bdc..e7b782d 100644 --- a/test cases/failing/123 subproject sandbox violation/meson_options.txt +++ b/test cases/failing/123 subproject sandbox violation/meson_options.txt @@ -1 +1 @@ -option('failmode', type: 'combo', choices: ['parent-dir', 'not-installed']) +option('failmode', type: 'combo', choices: ['parent-dir', 'not-installed', 'root-subdir']) diff --git a/test cases/failing/123 subproject sandbox violation/subprojects/subproj3/file.txt b/test cases/failing/123 subproject sandbox violation/subprojects/subproj3/file.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test cases/failing/123 subproject sandbox violation/subprojects/subproj3/file.txt diff --git a/test cases/failing/123 subproject sandbox violation/subprojects/subproj3/meson.build b/test cases/failing/123 subproject sandbox violation/subprojects/subproj3/meson.build new file mode 100644 index 0000000..c4fa64c --- /dev/null +++ b/test cases/failing/123 subproject sandbox violation/subprojects/subproj3/meson.build @@ -0,0 +1,3 @@ +project('subproj2') + +install_data('file.txt') diff --git a/test cases/failing/123 subproject sandbox violation/test.json b/test cases/failing/123 subproject sandbox violation/test.json index f314977..88ea620 100644 --- a/test cases/failing/123 subproject sandbox violation/test.json +++ b/test cases/failing/123 subproject sandbox violation/test.json @@ -3,13 +3,14 @@ "options": { "failmode": [ { "val": "not-installed" }, - { "val": "parent-dir" } + { "val": "parent-dir" }, + { "val": "root-subdir" } ] } }, "stdout": [ { - "line": "test cases/failing/123 subproject sandbox violation/meson.build:19:0: ERROR: Sandbox violation: Tried to grab file file.txt from a nested subproject." + "line": "test cases/failing/123 subproject sandbox violation/meson.build:24:0: ERROR: Sandbox violation: Tried to grab file file.txt from a nested subproject." } ] } |