summaryrefslogtreecommitdiff
path: root/mesonbuild/mesonlib/universal.py
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2021-10-31 16:16:10 -0400
committerEli Schwartz <eschwartz93@gmail.com>2022-06-16 17:06:25 -0400
commit2e3ac3eec00f32dabcfc470cd4c1090303d08e58 (patch)
tree1c7c1b51798a99a5566c99233b5a6d2b713292c8 /mesonbuild/mesonlib/universal.py
parent7229443738482db2183d048cf8b8b8e6bd11fa6d (diff)
downloadmeson-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.py22
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