diff options
author | Markus Armbruster <armbru@redhat.com> | 2023-03-16 08:13:19 +0100 |
---|---|---|
committer | Markus Armbruster <armbru@redhat.com> | 2023-04-24 15:21:39 +0200 |
commit | e2050ef633f77781e6b7b3aa04dd736e0ad825e1 (patch) | |
tree | 8867094aebe71b5d82da40c4c22cf2d2860ad60b /scripts/qapi | |
parent | 6f2ab6090de993988f7345e449852821ffc75f4e (diff) |
qapi: Fix to reject 'data': 'mumble' in struct
A struct's 'data' must be a JSON object defining the struct's members.
The QAPI code generator incorrectly accepts a JSON string instead, and
then crashes in QAPISchema._make_members() called from
._def_struct_type().
Fix to reject it: factor check_type_implicit() out of
check_type_name_or_implicit(), and switch check_struct() to use it
instead. Also add a test case.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20230316071325.492471-9-armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
[More detailed commit message]
Diffstat (limited to 'scripts/qapi')
-rw-r--r-- | scripts/qapi/expr.py | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py index 9bae500a7d..cae0a08359 100644 --- a/scripts/qapi/expr.py +++ b/scripts/qapi/expr.py @@ -354,14 +354,14 @@ def check_type_name_or_array(value: Optional[object], source) -def check_type_name_or_implicit(value: Optional[object], - info: QAPISourceInfo, source: str, - parent_name: Optional[str]) -> None: +def check_type_implicit(value: Optional[object], + info: QAPISourceInfo, source: str, + parent_name: Optional[str]) -> None: """ Normalize and validate an optional implicit struct type. - Accept ``None``, ``str``, or a ``dict`` defining an implicit - struct type. The latter is normalized in place. + Accept ``None`` or a ``dict`` defining an implicit struct type. + The latter is normalized in place. :param value: The value to check. :param info: QAPI schema source file information. @@ -377,9 +377,6 @@ def check_type_name_or_implicit(value: Optional[object], if value is None: return - if isinstance(value, str): - return - if not isinstance(value, dict): raise QAPISemError(info, "%s should be an object or type name" % source) @@ -401,6 +398,15 @@ def check_type_name_or_implicit(value: Optional[object], check_type_name_or_array(arg['type'], info, key_source) +def check_type_name_or_implicit(value: Optional[object], + info: QAPISourceInfo, source: str, + parent_name: Optional[str]) -> None: + if value is None or isinstance(value, str): + return + + check_type_implicit(value, info, source, parent_name) + + def check_features(features: Optional[object], info: QAPISourceInfo) -> None: """ @@ -486,7 +492,7 @@ def check_struct(expr: QAPIExpression) -> None: name = cast(str, expr['struct']) # Checked in check_exprs members = expr['data'] - check_type_name_or_implicit(members, expr.info, "'data'", name) + check_type_implicit(members, expr.info, "'data'", name) check_type_name(expr.get('base'), expr.info, "'base'") |