diff options
| author | Xavier Claessens <xavier.claessens@collabora.com> | 2021-10-31 16:16:10 -0400 |
|---|---|---|
| committer | Eli Schwartz <eschwartz93@gmail.com> | 2022-06-16 17:06:25 -0400 |
| commit | 2e3ac3eec00f32dabcfc470cd4c1090303d08e58 (patch) | |
| tree | 1c7c1b51798a99a5566c99233b5a6d2b713292c8 /mesonbuild/mesonlib/universal.py | |
| parent | 7229443738482db2183d048cf8b8b8e6bd11fa6d (diff) | |
| download | meson-2e3ac3eec00f32dabcfc470cd4c1090303d08e58.tar.gz | |
minstall: Add more safety checks when unpickling installdata
When need to catch exceptions just like we do in coredata.load() to
print proper error message instead of backtrace when user mix meson
versions.
This happens frequently when user has a newer version of meson installed
in their HOME and then "sudo meson install" uses the system version of
meson.
Diffstat (limited to 'mesonbuild/mesonlib/universal.py')
| -rw-r--r-- | mesonbuild/mesonlib/universal.py | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/mesonbuild/mesonlib/universal.py b/mesonbuild/mesonlib/universal.py index d708671c8..71f206af6 100644 --- a/mesonbuild/mesonlib/universal.py +++ b/mesonbuild/mesonlib/universal.py @@ -31,6 +31,7 @@ import typing as T import uuid import textwrap import copy +import pickle from mesonbuild import mlog @@ -123,6 +124,7 @@ __all__ = [ 'listify', 'partition', 'path_is_in_root', + 'pickle_load', 'Popen_safe', 'quiet_git', 'quote_arg', @@ -2232,3 +2234,23 @@ class OptionKey: def is_base(self) -> bool: """Convenience method to check if this is a base option.""" return self.type is OptionType.BASE + +def pickle_load(filename: str, object_name: str, object_type: T.Type) -> T.Any: + load_fail_msg = f'{object_name} file {filename!r} is corrupted. Try with a fresh build tree.' + try: + with open(filename, 'rb') as f: + obj = pickle.load(f) + except (pickle.UnpicklingError, EOFError): + raise MesonException(load_fail_msg) + except (TypeError, ModuleNotFoundError, AttributeError): + raise MesonException( + f"{object_name} file {filename!r} references functions or classes that don't " + "exist. This probably means that it was generated with an old " + "version of meson.") + if not isinstance(obj, object_type): + raise MesonException(load_fail_msg) + from ..coredata import version as coredata_version + from ..coredata import major_versions_differ, MesonVersionMismatchException + if major_versions_differ(obj.version, coredata_version): + raise MesonVersionMismatchException(obj.version, coredata_version) + return obj |
