From e882c8b23fbb43f78256c895f103101265f0f4c8 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Mon, 15 Mar 2021 11:53:34 +0200 Subject: Warn when grabbing internals of subprojects with include_directories. --- mesonbuild/interpreter.py | 30 ++++++++++++++++++++-- .../common/240 includedir violation/meson.build | 7 +++++ .../subprojects/sub/include/placeholder.h | 3 +++ .../subprojects/sub/meson.build | 3 +++ .../common/240 includedir violation/test.json | 7 +++++ 5 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 test cases/common/240 includedir violation/meson.build create mode 100644 test cases/common/240 includedir violation/subprojects/sub/include/placeholder.h create mode 100644 test cases/common/240 includedir violation/subprojects/sub/meson.build create mode 100644 test cases/common/240 includedir violation/test.json diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index e563f36..5b8f361 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -4577,6 +4577,28 @@ different subdirectory. absdir_build = os.path.join(absbase_build, a) if not os.path.isdir(absdir_src) and not os.path.isdir(absdir_build): raise InvalidArguments('Include dir %s does not exist.' % a) + else: + try: + self.validate_within_subproject(a, '') + except InterpreterException: + mlog.warning('include_directories sandbox violation!') + print(f'''The project is trying to access the directory {a} which belongs to a different +subproject. This is a problem as it hardcodes the relative paths of these two projeccts. +This makes it impossible to compile the project in any other directory layout and also +makes it impossible for the subproject to change its own directory layout. + +Instead of poking directly at the internals the subproject should be executed and +it should set a variable that the caller can then use. Something like: + +# In subproject +my_inc = include_directories('include') + +# In parent project +dep_sp = subproject('sub') +dep_inc = dep_sp.get_variable('my_inc') + +This warning will become a hard error in a future Meson release. +''') i = IncludeDirsHolder(build.IncludeDirs(self.subdir, incdir_strings, is_system)) return i @@ -4774,6 +4796,10 @@ Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey def validate_within_subproject(self, subdir, fname): srcdir = Path(self.environment.source_dir) norm = Path(srcdir, subdir, fname).resolve() + if os.path.isdir(norm): + inputtype = 'directory' + else: + inputtype = 'file' if srcdir not in norm.parents: # Grabbing files outside the source tree is ok. # This is for vendor stuff like: @@ -4782,9 +4808,9 @@ Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey return project_root = Path(srcdir, self.root_subdir) if project_root not in norm.parents: - raise InterpreterException(f'Sandbox violation: Tried to grab file {norm.name} outside current (sub)project.') + raise InterpreterException(f'Sandbox violation: Tried to grab {inputtype} {norm.name} outside current (sub)project.') if project_root / self.subproject_dir in norm.parents: - raise InterpreterException(f'Sandbox violation: Tried to grab file {norm.name} from a nested subproject.') + raise InterpreterException(f'Sandbox violation: Tried to grab {inputtype} {norm.name} from a nested subproject.') def source_strings_to_files(self, sources: T.List[str]) -> T.List[mesonlib.File]: mesonlib.check_direntry_issues(sources) diff --git a/test cases/common/240 includedir violation/meson.build b/test cases/common/240 includedir violation/meson.build new file mode 100644 index 0000000..a82069e --- /dev/null +++ b/test cases/common/240 includedir violation/meson.build @@ -0,0 +1,7 @@ +project('foo', 'c') + +# This is here rather than in failing because this needs a +# transition period to avoid breaking existing projects. +# Once this becomes an error, move this under failing tests. + +inc = include_directories('subprojects/sub/include') diff --git a/test cases/common/240 includedir violation/subprojects/sub/include/placeholder.h b/test cases/common/240 includedir violation/subprojects/sub/include/placeholder.h new file mode 100644 index 0000000..196f917 --- /dev/null +++ b/test cases/common/240 includedir violation/subprojects/sub/include/placeholder.h @@ -0,0 +1,3 @@ +#pragma once + +// Git can not handle empty directories, so there must be something here. diff --git a/test cases/common/240 includedir violation/subprojects/sub/meson.build b/test cases/common/240 includedir violation/subprojects/sub/meson.build new file mode 100644 index 0000000..7211018 --- /dev/null +++ b/test cases/common/240 includedir violation/subprojects/sub/meson.build @@ -0,0 +1,3 @@ +project('subproj', 'c') + +# This is never actually executed, just here for completeness. diff --git a/test cases/common/240 includedir violation/test.json b/test cases/common/240 includedir violation/test.json new file mode 100644 index 0000000..d6e56a3 --- /dev/null +++ b/test cases/common/240 includedir violation/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "WARNING: include_directories sandbox violation!" + } + ] +} -- cgit v1.1