aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/interpreterbase
diff options
context:
space:
mode:
authorCharles Brunet <charles.brunet@optelgroup.com>2023-02-25 12:13:30 -0500
committerEli Schwartz <eschwartz93@gmail.com>2023-02-27 13:40:16 -0500
commit5dbe49aa3362aefa8a8bc1153272fa14d4f7669b (patch)
tree2bbc574db3c7b225d930817729fb9f1248bae0b4 /mesonbuild/interpreterbase
parent4a357ba6b22ea90365954378569bea7c1d0271a8 (diff)
downloadmeson-5dbe49aa3362aefa8a8bc1153272fa14d4f7669b.zip
meson-5dbe49aa3362aefa8a8bc1153272fa14d4f7669b.tar.gz
meson-5dbe49aa3362aefa8a8bc1153272fa14d4f7669b.tar.bz2
prevent unhandled exception for operations on None
For instance, when writing `-subdir('a')` or `not subdir('a')`. Fixes #11225.
Diffstat (limited to 'mesonbuild/interpreterbase')
-rw-r--r--mesonbuild/interpreterbase/interpreterbase.py56
1 files changed, 47 insertions, 9 deletions
diff --git a/mesonbuild/interpreterbase/interpreterbase.py b/mesonbuild/interpreterbase/interpreterbase.py
index f72ddc1..da64f68 100644
--- a/mesonbuild/interpreterbase/interpreterbase.py
+++ b/mesonbuild/interpreterbase/interpreterbase.py
@@ -31,12 +31,13 @@ from .baseobjects import (
)
from .exceptions import (
+ BreakRequest,
+ ContinueRequest,
InterpreterException,
- InvalidCode,
InvalidArguments,
+ InvalidCode,
+ MesonException,
SubdirDoneRequest,
- ContinueRequest,
- BreakRequest
)
from .decorators import FeatureNew
@@ -71,6 +72,13 @@ if T.TYPE_CHECKING:
T.Callable[[mparser.BaseNode, T.List[TYPE_var], T.Dict[str, TYPE_var]], TYPE_var]
]
+
+class InvalidCodeOnVoid(InvalidCode):
+
+ def __init__(self, op_type: str) -> None:
+ super().__init__(f'Cannot perform {op_type!r} operation on void statement.')
+
+
class InterpreterBase:
def __init__(self, source_root: str, subdir: str, subproject: 'SubProject'):
self.source_root = source_root
@@ -238,7 +246,10 @@ class InterpreterBase:
def resolve_key(key: mparser.BaseNode) -> str:
if not isinstance(key, mparser.StringNode):
FeatureNew.single_use('Dictionary entry using non literal key', '0.53.0', self.subproject)
- str_key = _unholder(self.evaluate_statement(key))
+ key_holder = self.evaluate_statement(key)
+ if key_holder is None:
+ raise InvalidArguments('Key cannot be void.')
+ str_key = _unholder(key_holder)
if not isinstance(str_key, str):
raise InvalidArguments('Key must be a string')
return str_key
@@ -248,6 +259,8 @@ class InterpreterBase:
def evaluate_notstatement(self, cur: mparser.NotNode) -> InterpreterObject:
v = self.evaluate_statement(cur.value)
+ if v is None:
+ raise InvalidCodeOnVoid('not')
if isinstance(v, Disabler):
return v
return self._holderify(v.operator_call(MesonOperator.NOT, None))
@@ -259,10 +272,12 @@ class InterpreterBase:
# statement evaluation.
self.tmp_meson_version = None
result = self.evaluate_statement(i.condition)
+ if result is None:
+ raise InvalidCodeOnVoid('if')
if isinstance(result, Disabler):
return result
if not isinstance(result, InterpreterObject):
- raise mesonlib.MesonBugException(f'Argument to not ({result}) is not an InterpreterObject but {type(result).__name__}.')
+ raise mesonlib.MesonBugException(f'Argument to if ({result}) is not an InterpreterObject but {type(result).__name__}.')
res = result.operator_call(MesonOperator.BOOL, None)
if not isinstance(res, bool):
raise InvalidCode(f'If clause {result!r} does not evaluate to true or false.')
@@ -281,9 +296,13 @@ class InterpreterBase:
def evaluate_comparison(self, node: mparser.ComparisonNode) -> InterpreterObject:
val1 = self.evaluate_statement(node.left)
+ if val1 is None:
+ raise MesonException('Cannot compare a void statement on the left-hand side')
if isinstance(val1, Disabler):
return val1
val2 = self.evaluate_statement(node.right)
+ if val2 is None:
+ raise MesonException('Cannot compare a void statement on the right-hand side')
if isinstance(val2, Disabler):
return val2
@@ -308,30 +327,40 @@ class InterpreterBase:
def evaluate_andstatement(self, cur: mparser.AndNode) -> InterpreterObject:
l = self.evaluate_statement(cur.left)
+ if l is None:
+ raise MesonException('Cannot compare a void statement on the left-hand side')
if isinstance(l, Disabler):
return l
l_bool = l.operator_call(MesonOperator.BOOL, None)
if not l_bool:
return self._holderify(l_bool)
r = self.evaluate_statement(cur.right)
+ if r is None:
+ raise MesonException('Cannot compare a void statement on the right-hand side')
if isinstance(r, Disabler):
return r
return self._holderify(r.operator_call(MesonOperator.BOOL, None))
def evaluate_orstatement(self, cur: mparser.OrNode) -> InterpreterObject:
l = self.evaluate_statement(cur.left)
+ if l is None:
+ raise MesonException('Cannot compare a void statement on the left-hand side')
if isinstance(l, Disabler):
return l
l_bool = l.operator_call(MesonOperator.BOOL, None)
if l_bool:
return self._holderify(l_bool)
r = self.evaluate_statement(cur.right)
+ if r is None:
+ raise MesonException('Cannot compare a void statement on the right-hand side')
if isinstance(r, Disabler):
return r
return self._holderify(r.operator_call(MesonOperator.BOOL, None))
def evaluate_uminusstatement(self, cur: mparser.UMinusNode) -> InterpreterObject:
v = self.evaluate_statement(cur.value)
+ if v is None:
+ raise InvalidCodeOnVoid('unary minus')
if isinstance(v, Disabler):
return v
v.current_node = cur
@@ -344,6 +373,8 @@ class InterpreterBase:
r = self.evaluate_statement(cur.right)
if isinstance(r, Disabler):
return r
+ if l is None or r is None:
+ raise InvalidCodeOnVoid(cur.operation)
mapping: T.Dict[str, MesonOperator] = {
'add': MesonOperator.PLUS,
@@ -359,6 +390,8 @@ class InterpreterBase:
def evaluate_ternary(self, node: mparser.TernaryNode) -> T.Optional[InterpreterObject]:
assert isinstance(node, mparser.TernaryNode)
result = self.evaluate_statement(node.condition)
+ if result is None:
+ raise MesonException('Cannot use a void statement as condition for ternary operator.')
if isinstance(result, Disabler):
return result
result.current_node = node
@@ -424,6 +457,8 @@ class InterpreterBase:
assert isinstance(node, mparser.PlusAssignmentNode)
varname = node.var_name
addition = self.evaluate_statement(node.value)
+ if addition is None:
+ raise InvalidCodeOnVoid('plus assign')
# Remember that all variables are immutable. We must always create a
# full new variable and then assign it.
@@ -435,12 +470,15 @@ class InterpreterBase:
def evaluate_indexing(self, node: mparser.IndexNode) -> InterpreterObject:
assert isinstance(node, mparser.IndexNode)
iobject = self.evaluate_statement(node.iobject)
+ if iobject is None:
+ raise InterpreterException('Tried to evaluate indexing on void.')
if isinstance(iobject, Disabler):
return iobject
- index = _unholder(self.evaluate_statement(node.index))
+ index_holder = self.evaluate_statement(node.index)
+ if index_holder is None:
+ raise InvalidArguments('Cannot use void statement as index.')
+ index = _unholder(index_holder)
- if iobject is None:
- raise InterpreterException('Tried to evaluate indexing on None')
iobject.current_node = node
return self._holderify(iobject.operator_call(MesonOperator.INDEX, index))
@@ -578,7 +616,7 @@ class InterpreterBase:
def set_variable(self, varname: str, variable: T.Union[TYPE_var, InterpreterObject], *, holderify: bool = False) -> None:
if variable is None:
- raise InvalidCode('Can not assign None to variable.')
+ raise InvalidCode('Can not assign void to variable.')
if holderify:
variable = self._holderify(variable)
else: