From 18e2f8b2b3c7b3cb29e7d7ff037b175411f47f25 Mon Sep 17 00:00:00 2001 From: Vili Väinölä Date: Wed, 1 Jun 2022 18:31:33 +0300 Subject: Fix sandbox violation when using subproject as a symlink Fix "Tried to grab file outside current (sub)project" error when subproject exists within a source tree but it is used through a symlink. Using subprojects as symlinks is very useful feature when migrating an existing codebase to meson that all sources do not need to be immediately moved to subprojects folder. --- mesonbuild/interpreter/interpreter.py | 2 +- test cases/unit/106 subproject symlink/main.c | 6 ++++++ test cases/unit/106 subproject symlink/meson.build | 8 ++++++++ .../106 subproject symlink/symlinked_subproject/meson.build | 3 +++ .../unit/106 subproject symlink/symlinked_subproject/src.c | 4 ++++ unittests/allplatformstests.py | 13 +++++++++++++ 6 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 test cases/unit/106 subproject symlink/main.c create mode 100644 test cases/unit/106 subproject symlink/meson.build create mode 100644 test cases/unit/106 subproject symlink/symlinked_subproject/meson.build create mode 100644 test cases/unit/106 subproject symlink/symlinked_subproject/src.c diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 05614aaa3..6e25b9b22 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -2851,7 +2851,7 @@ Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey # subproject files, as long as they are scheduled to be installed. if validate_installable_file(norm): return - norm = Path(srcdir, subdir, fname).resolve() + norm = Path(os.path.abspath(Path(srcdir, subdir, fname))) if os.path.isdir(norm): inputtype = 'directory' else: diff --git a/test cases/unit/106 subproject symlink/main.c b/test cases/unit/106 subproject symlink/main.c new file mode 100644 index 000000000..62bd4b4b2 --- /dev/null +++ b/test cases/unit/106 subproject symlink/main.c @@ -0,0 +1,6 @@ +extern int foo(void); + +int main(void) +{ + return foo(); +} diff --git a/test cases/unit/106 subproject symlink/meson.build b/test cases/unit/106 subproject symlink/meson.build new file mode 100644 index 000000000..51c78c7ec --- /dev/null +++ b/test cases/unit/106 subproject symlink/meson.build @@ -0,0 +1,8 @@ +project('foo', 'c') + +symlinked_subproject = subproject('symlinked_subproject') + +executable('foo', + sources : 'main.c', + dependencies : symlinked_subproject.get_variable('dep') +) diff --git a/test cases/unit/106 subproject symlink/symlinked_subproject/meson.build b/test cases/unit/106 subproject symlink/symlinked_subproject/meson.build new file mode 100644 index 000000000..61440c7eb --- /dev/null +++ b/test cases/unit/106 subproject symlink/symlinked_subproject/meson.build @@ -0,0 +1,3 @@ +project('symlinked_subproject', 'c', version : '1.0.0') + +dep = declare_dependency(sources : 'src.c') diff --git a/test cases/unit/106 subproject symlink/symlinked_subproject/src.c b/test cases/unit/106 subproject symlink/symlinked_subproject/src.c new file mode 100644 index 000000000..97d7ad1d6 --- /dev/null +++ b/test cases/unit/106 subproject symlink/symlinked_subproject/src.c @@ -0,0 +1,4 @@ +int foo(void) +{ + return 0; +} diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index 42bc60e00..71e919e12 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -4263,3 +4263,16 @@ class AllPlatformTests(BasePlatformTests): if self.backend is Backend.ninja: self.assertIn('Generating file.txt with a custom command', out) self.assertIn('Generating subdir/file.txt with a custom command', out) + + def test_symlinked_subproject(self): + testdir = os.path.join(self.unit_test_dir, '106 subproject symlink') + subproject_dir = os.path.join(testdir, 'subprojects') + subproject = os.path.join(testdir, 'symlinked_subproject') + symlinked_subproject = os.path.join(testdir, 'subprojects', 'symlinked_subproject') + if not os.path.exists(subproject_dir): + os.mkdir(subproject_dir) + os.symlink(subproject, symlinked_subproject) + self.addCleanup(os.remove, symlinked_subproject) + + self.init(testdir) + self.build() -- cgit v1.2.3