aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorEli Schwartz <eschwartz93@gmail.com>2024-04-28 12:14:06 -0400
committerJussi Pakkanen <jpakkane@gmail.com>2024-04-28 22:51:08 +0300
commite5f32b74144b9f4a43304fa167899e202c5912b5 (patch)
treecd3991e1fa1e5daae50cbe7915b58b62dc7c172e /mesonbuild
parent4f3a3e2efeb415fe83f9e858b010a36baf72b455 (diff)
downloadmeson-e5f32b74144b9f4a43304fa167899e202c5912b5.zip
meson-e5f32b74144b9f4a43304fa167899e202c5912b5.tar.gz
meson-e5f32b74144b9f4a43304fa167899e202c5912b5.tar.bz2
catch build files that cannot be opened in utf8 mode and emit useful error
Previously, if a junked meson.build or native.ini was used we got a lengthy traceback ending in UnicodeDecodeError. Fixes: #13154 Fixes: #13156
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/ast/interpreter.py4
-rw-r--r--mesonbuild/coredata.py20
-rw-r--r--mesonbuild/interpreter/interpreter.py4
-rw-r--r--mesonbuild/interpreterbase/interpreterbase.py11
-rw-r--r--mesonbuild/optinterpreter.py6
5 files changed, 28 insertions, 17 deletions
diff --git a/mesonbuild/ast/interpreter.py b/mesonbuild/ast/interpreter.py
index 53ddc10..15d2793 100644
--- a/mesonbuild/ast/interpreter.py
+++ b/mesonbuild/ast/interpreter.py
@@ -189,9 +189,7 @@ class AstInterpreter(InterpreterBase):
if not os.path.isfile(absname):
sys.stderr.write(f'Unable to find build file {buildfilename} --> Skipping\n')
return
- with open(absname, encoding='utf-8') as f:
- code = f.read()
- assert isinstance(code, str)
+ code = self.read_buildfile(absname, buildfilename)
try:
codeblock = mparser.Parser(code, absname).parse()
except mesonlib.MesonException as me:
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 3cf873f..7213115 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -1102,14 +1102,18 @@ class MachineFileParser():
self.sections: T.Dict[str, T.Dict[str, T.Union[str, bool, int, T.List[str]]]] = {}
for fname in filenames:
- with open(fname, encoding='utf-8') as f:
- content = f.read()
- content = content.replace('@GLOBAL_SOURCE_ROOT@', sourcedir)
- content = content.replace('@DIRNAME@', os.path.dirname(fname))
- try:
- self.parser.read_string(content, fname)
- except configparser.Error as e:
- raise EnvironmentException(f'Malformed machine file: {e}')
+ try:
+ with open(fname, encoding='utf-8') as f:
+ content = f.read()
+ except UnicodeDecodeError as e:
+ raise EnvironmentException(f'Malformed machine file {fname!r} failed to parse as unicode: {e}')
+
+ content = content.replace('@GLOBAL_SOURCE_ROOT@', sourcedir)
+ content = content.replace('@DIRNAME@', os.path.dirname(fname))
+ try:
+ self.parser.read_string(content, fname)
+ except configparser.Error as e:
+ raise EnvironmentException(f'Malformed machine file: {e}')
# Parse [constants] first so they can be used in other sections
if self.parser.has_section('constants'):
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index de8f24d..f6b4cf4 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -2425,9 +2425,7 @@ class Interpreter(InterpreterBase, HoldableObject):
if not os.path.isfile(absname):
self.subdir = prev_subdir
raise InterpreterException(f"Nonexistent build file '{buildfilename!s}'")
- with open(absname, encoding='utf-8') as f:
- code = f.read()
- assert isinstance(code, str)
+ code = self.read_buildfile(absname, buildfilename)
try:
codeblock = mparser.Parser(code, absname).parse()
except mesonlib.MesonException as me:
diff --git a/mesonbuild/interpreterbase/interpreterbase.py b/mesonbuild/interpreterbase/interpreterbase.py
index ccc3349..525d5d6 100644
--- a/mesonbuild/interpreterbase/interpreterbase.py
+++ b/mesonbuild/interpreterbase/interpreterbase.py
@@ -93,12 +93,19 @@ class InterpreterBase:
# do nothing in an AST interpreter
return
+ def read_buildfile(self, fname: str, errname: str) -> str:
+ try:
+ with open(fname, encoding='utf-8') as f:
+ return f.read()
+ except UnicodeDecodeError as e:
+ node = mparser.BaseNode(1, 1, errname)
+ raise InvalidCode.from_node(f'Build file failed to parse as unicode: {e}', node=node)
+
def load_root_meson_file(self) -> None:
mesonfile = os.path.join(self.source_root, self.subdir, environment.build_filename)
if not os.path.isfile(mesonfile):
raise InvalidArguments(f'Missing Meson file in {mesonfile}')
- with open(mesonfile, encoding='utf-8') as mf:
- code = mf.read()
+ code = self.read_buildfile(mesonfile, mesonfile)
if code.isspace():
raise InvalidCode('Builder file is empty.')
assert isinstance(code, str)
diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py
index 980dadd..599da65 100644
--- a/mesonbuild/optinterpreter.py
+++ b/mesonbuild/optinterpreter.py
@@ -78,7 +78,11 @@ class OptionInterpreter:
def process(self, option_file: str) -> None:
try:
with open(option_file, encoding='utf-8') as f:
- ast = mparser.Parser(f.read(), option_file).parse()
+ code = f.read()
+ except UnicodeDecodeError as e:
+ raise mesonlib.MesonException(f'Malformed option file {option_file!r} failed to parse as unicode: {e}')
+ try:
+ ast = mparser.Parser(code, option_file).parse()
except mesonlib.MesonException as me:
me.file = option_file
raise me