aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/interpreter/interpreter.py17
-rw-r--r--mesonbuild/interpreter/interpreterobjects.py5
-rw-r--r--mesonbuild/interpreter/primitives/string.py7
-rw-r--r--test cases/failing/123 subproject sandbox violation/meson.build9
-rw-r--r--test cases/failing/123 subproject sandbox violation/meson_options.txt2
-rw-r--r--test cases/failing/123 subproject sandbox violation/subprojects/subproj3/file.txt0
-rw-r--r--test cases/failing/123 subproject sandbox violation/subprojects/subproj3/meson.build3
-rw-r--r--test cases/failing/123 subproject sandbox violation/test.json5
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."
}
]
}