Bugfix: sanitize_dir: use pathlib to handle case-insensitive filesystems (#6398)
This commit is contained in:
parent
1682058dec
commit
00f5dadd5b
|
@ -463,7 +463,7 @@ class CoreData:
|
|||
prefix = prefix[:-1]
|
||||
return prefix
|
||||
|
||||
def sanitize_dir_option_value(self, prefix, option, value):
|
||||
def sanitize_dir_option_value(self, prefix: str, option: str, value: Any) -> Any:
|
||||
'''
|
||||
If the option is an installation directory option and the value is an
|
||||
absolute path, check that it resides within prefix and return the value
|
||||
|
@ -471,22 +471,31 @@ class CoreData:
|
|||
|
||||
This way everyone can do f.ex, get_option('libdir') and be sure to get
|
||||
the library directory relative to prefix.
|
||||
|
||||
.as_posix() keeps the posix-like file seperators Meson uses.
|
||||
'''
|
||||
if option.endswith('dir') and os.path.isabs(value) and \
|
||||
try:
|
||||
value = PurePath(value)
|
||||
except TypeError:
|
||||
return value
|
||||
if option.endswith('dir') and value.is_absolute() and \
|
||||
option not in builtin_dir_noprefix_options:
|
||||
# Value must be a subdir of the prefix
|
||||
# commonpath will always return a path in the native format, so we
|
||||
# must use pathlib.PurePath to do the same conversion before
|
||||
# comparing.
|
||||
if os.path.commonpath([value, prefix]) != str(PurePath(prefix)):
|
||||
m = 'The value of the {!r} option is {!r} which must be a ' \
|
||||
'subdir of the prefix {!r}.\nNote that if you pass a ' \
|
||||
'relative path, it is assumed to be a subdir of prefix.'
|
||||
raise MesonException(m.format(option, value, prefix))
|
||||
# Convert path to be relative to prefix
|
||||
skip = len(prefix) + 1
|
||||
value = value[skip:]
|
||||
return value
|
||||
msg = ('The value of the {!r} option is {!r} which must be a '
|
||||
'subdir of the prefix {!r}.\nNote that if you pass a '
|
||||
'relative path, it is assumed to be a subdir of prefix.')
|
||||
# os.path.commonpath doesn't understand case-insensitive filesystems,
|
||||
# but PurePath().relative_to() does.
|
||||
try:
|
||||
value = value.relative_to(prefix)
|
||||
except ValueError:
|
||||
raise MesonException(msg.format(option, value, prefix))
|
||||
if '..' in str(value):
|
||||
raise MesonException(msg.format(option, value, prefix))
|
||||
return value.as_posix()
|
||||
|
||||
def init_builtins(self):
|
||||
# Create builtin options with default values
|
||||
|
|
|
@ -381,7 +381,7 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen
|
|||
setup_env = None
|
||||
# Configure in-process
|
||||
if pass_prefix_to_test(testdir):
|
||||
gen_args = ['--prefix', '/usr']
|
||||
gen_args = ['--prefix', 'x:/usr'] if mesonlib.is_windows() else ['--prefix', '/usr']
|
||||
else:
|
||||
gen_args = []
|
||||
if pass_libdir_to_test(testdir):
|
||||
|
@ -547,6 +547,10 @@ def skippable(suite, test):
|
|||
if not suite.endswith('frameworks'):
|
||||
return True
|
||||
|
||||
# this test assumptions aren't valid for Windows paths
|
||||
if test.endswith('38 libdir must be inside prefix'):
|
||||
return True
|
||||
|
||||
# gtk-doc test may be skipped, pending upstream fixes for spaces in
|
||||
# filenames landing in the distro used for CI
|
||||
if test.endswith('10 gtk-doc'):
|
||||
|
|
|
@ -1783,7 +1783,8 @@ class AllPlatformTests(BasePlatformTests):
|
|||
https://github.com/mesonbuild/meson/issues/1345
|
||||
'''
|
||||
testdir = os.path.join(self.common_test_dir, '90 default options')
|
||||
prefix = '/someabs'
|
||||
# on Windows, /someabs is *not* an absolute path
|
||||
prefix = 'x:/someabs' if is_windows() else '/someabs'
|
||||
libdir = 'libdir'
|
||||
extra_args = ['--prefix=' + prefix,
|
||||
# This can just be a relative path, but we want to test
|
||||
|
@ -1804,16 +1805,25 @@ class AllPlatformTests(BasePlatformTests):
|
|||
'''
|
||||
testdir = os.path.join(self.common_test_dir, '1 trivial')
|
||||
# libdir being inside prefix is ok
|
||||
args = ['--prefix', '/opt', '--libdir', '/opt/lib32']
|
||||
if is_windows():
|
||||
args = ['--prefix', 'x:/opt', '--libdir', 'x:/opt/lib32']
|
||||
else:
|
||||
args = ['--prefix', '/opt', '--libdir', '/opt/lib32']
|
||||
self.init(testdir, extra_args=args)
|
||||
self.wipe()
|
||||
# libdir not being inside prefix is not ok
|
||||
args = ['--prefix', '/usr', '--libdir', '/opt/lib32']
|
||||
if is_windows():
|
||||
args = ['--prefix', 'x:/usr', '--libdir', 'x:/opt/lib32']
|
||||
else:
|
||||
args = ['--prefix', '/usr', '--libdir', '/opt/lib32']
|
||||
self.assertRaises(subprocess.CalledProcessError, self.init, testdir, extra_args=args)
|
||||
self.wipe()
|
||||
# libdir must be inside prefix even when set via mesonconf
|
||||
self.init(testdir)
|
||||
self.assertRaises(subprocess.CalledProcessError, self.setconf, '-Dlibdir=/opt', False)
|
||||
if is_windows():
|
||||
self.assertRaises(subprocess.CalledProcessError, self.setconf, '-Dlibdir=x:/opt', False)
|
||||
else:
|
||||
self.assertRaises(subprocess.CalledProcessError, self.setconf, '-Dlibdir=/opt', False)
|
||||
|
||||
def test_prefix_dependent_defaults(self):
|
||||
'''
|
||||
|
@ -7310,14 +7320,11 @@ def main():
|
|||
import pytest # noqa: F401
|
||||
# Need pytest-xdist for `-n` arg
|
||||
import xdist # noqa: F401
|
||||
if sys.version_info.major <= 3 and sys.version_info.minor <= 5:
|
||||
raise ImportError('pytest with python <= 3.5 is causing issues on the CI')
|
||||
pytest_args = ['-n', 'auto', './run_unittests.py']
|
||||
pytest_args += convert_args(sys.argv[1:])
|
||||
return subprocess.run(python_command + ['-m', 'pytest'] + pytest_args).returncode
|
||||
except ImportError:
|
||||
print('pytest-xdist not found, using unittest instead')
|
||||
pass
|
||||
# All attempts at locating pytest failed, fall back to plain unittest.
|
||||
cases = ['InternalTests', 'DataTests', 'AllPlatformTests', 'FailureTests',
|
||||
'PythonTests', 'NativeFileTests', 'RewriterTests', 'CrossFileTests',
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# normally run only from run_tests.py or run_project_tests.py
|
||||
# else do like
|
||||
# meson build '-Dtestoption=A string with spaces' -Dother_one=true -Dcombo_opt=one -Dprefix=/usr -Dlibdir=lib -Dbackend=ninja -Dwerror=True
|
||||
project('options', 'c')
|
||||
|
||||
assert(get_option('testoption') == 'A string with spaces', 'Incorrect value for testoption option.')
|
||||
|
|
|
@ -1,2 +1,6 @@
|
|||
project('libdir prefix', 'c',
|
||||
default_options : ['libdir=/opt/lib'])
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
error('MESON_SKIP_TEST: this test does not work on Windows since /foo is not absolute')
|
||||
endif
|
Loading…
Reference in New Issue