From 4e5df4b3b7e0db0c4ed174f8b2de53b9004a1c45 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Wed, 14 Feb 2024 00:09:07 -0500 Subject: fix crash in generator.process() with an invalid preserve_path_from This code cleverly tried to use a fancy new pathlib.Path method to get the os.path.commonpath of two paths and check whether one is inside the other. It failed pretty badly, because of a hidden secret of pathlib: it is designed to throw random exceptions at all times (except when building os.PathLike interfaces) instead of performing useful work. Return to `os.path`. In particular, before this change, we wanted to check if files are NOT in a subpath of `preserve_path_from`, and raise a meson "ERROR: xxx" in such a case. However, the code to check for it would raise a python ValueError if that was the case, so we never got to the properly formatted error. --- mesonbuild/build.py | 7 +++++-- test cases/common/168 preserve gendir/meson.build | 5 +++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 066e6aa85..7aea22927 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1800,8 +1800,11 @@ class Generator(HoldableObject): @staticmethod def is_parent_path(parent: str, trial: str) -> bool: - relpath = pathlib.PurePath(trial).relative_to(parent) - return relpath.parts[0] != '..' # For subdirs we can only go "down". + try: + common = os.path.commonpath((parent, trial)) + except ValueError: # Windows on different drives + return False + return pathlib.PurePath(common) == pathlib.PurePath(parent) def process_files(self, files: T.Iterable[T.Union[str, File, 'CustomTarget', 'CustomTargetIndex', 'GeneratedList']], state: T.Union['Interpreter', 'ModuleState'], diff --git a/test cases/common/168 preserve gendir/meson.build b/test cases/common/168 preserve gendir/meson.build index ce219f0d8..d543b6019 100644 --- a/test cases/common/168 preserve gendir/meson.build +++ b/test cases/common/168 preserve gendir/meson.build @@ -9,5 +9,10 @@ gen = generator(gprog, \ generated = gen.process('base.inp', 'com/mesonbuild/subbie.inp', preserve_path_from : meson.current_source_dir()) +testcase expect_error('generator.process: When using preserve_path_from, all input files must be in a subdirectory of the given dir.') + generated = gen.process('base.inp', 'com/mesonbuild/subbie.inp', + preserve_path_from : meson.current_source_dir() / 'com') +endtestcase + e = executable('testprog', 'testprog.c', generated) test('testprog', e) -- cgit v1.2.3