[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v4 14/19] qapi: More rigorous checking for type
From: |
Markus Armbruster |
Subject: |
Re: [Qemu-devel] [PATCH v4 14/19] qapi: More rigorous checking for type safety bypass |
Date: |
Mon, 29 Sep 2014 10:38:39 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) |
Eric Blake <address@hidden> writes:
> Now that we have a way to validate every type, we can also be
> stricter about enforcing that callers that want to bypass
> type safety in generated code. Prior to this patch, it didn't
> matter what value was associated with the key 'gen', but it
> looked odd that 'gen':'yes' could result in bypassing the
> generated code. These changes also enforce the changes made
> earlier in the series for documentation and consolidation of
> using '**' as the wildcard type.
Perhaps it's worth mentioning that the schema has always used 'gen':
'no'.
That said, 'no' is silly. The natural JSON for a flag is false / true!
Since you're touching it anyway, consider making it an optional boolean
defaulting to false. Same for the other silly 'no': success-response.
> Signed-off-by: Eric Blake <address@hidden>
> ---
> scripts/qapi.py | 21 ++++++++++++++++-----
> tests/qapi-schema/type-bypass-bad-gen.err | 1 +
> tests/qapi-schema/type-bypass-bad-gen.exit | 2 +-
> tests/qapi-schema/type-bypass-bad-gen.json | 2 +-
> tests/qapi-schema/type-bypass-bad-gen.out | 3 ---
> tests/qapi-schema/type-bypass-no-gen.err | 1 +
> tests/qapi-schema/type-bypass-no-gen.exit | 2 +-
> tests/qapi-schema/type-bypass-no-gen.json | 2 +-
> tests/qapi-schema/type-bypass-no-gen.out | 3 ---
> 9 files changed, 22 insertions(+), 15 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 20c0ce9..15972c6 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -256,13 +256,13 @@ def discriminator_find_enum_define(expr):
> return find_enum(discriminator_type)
>
> def check_type(expr_info, source, data, allow_array = False,
> - allowed_names = [], allow_dict = True):
> + allowed_names = [], allow_dict = True, allow_star = False):
> global all_types
>
> if data is None:
> return
>
> - if data == '**':
> + if allow_star and data == '**':
> return
>
> # Check if array type for data is okay
> @@ -278,6 +278,10 @@ def check_type(expr_info, source, data, allow_array =
> False,
>
> # Check if type name for data is okay
> if isinstance(data, basestring):
> + if data == '**':
> + raise QAPIExprError(expr_info,
> + "%s uses '**' but did not request 'gen':'no'"
> + % source)
> if not data in all_types:
> raise QAPIExprError(expr_info,
> "%s references unknown type '%s'"
I'm blind: I can't see where this error gets suppressed when we have
'gen': 'no'.
> @@ -299,24 +303,27 @@ def check_type(expr_info, source, data, allow_array =
> False,
> check_type(expr_info, "member '%s' of %s" % (key, source), value,
> allow_array=True,
> allowed_names=['built-in', 'union', 'struct', 'enum'],
> - allow_dict=True)
> + allow_dict=True, allow_star=allow_star)
>
allow_star applies recursively. Correct, because...
> def check_command(expr, expr_info):
> global commands
> name = expr['command']
> + allow_star = expr.has_key('gen')
> +
> if name in commands:
> raise QAPIExprError(expr_info,
> "command '%s' is already defined" % name)
> commands.append(name)
> check_type(expr_info, "'data' for command '%s'" % name,
> expr.get('data'), allow_array=True,
> - allowed_names=['union', 'struct'])
> + allowed_names=['union', 'struct'], allow_star=allow_star)
> check_type(expr_info, "'base' for command '%s'" % name,
> expr.get('base'), allowed_names=['struct'],
> allow_dict=False)
> check_type(expr_info, "'returns' for command '%s'" % name,
> expr.get('returns'), allow_array=True,
> - allowed_names=['built-in', 'union', 'struct', 'enum'])
> + allowed_names=['built-in', 'union', 'struct', 'enum'],
> + allow_star=allow_star)
>
... it applies exactly to a command's 'data' and 'returns' when it has
'gen': 'no'. Good.
> def check_event(expr, expr_info):
> global events
> @@ -450,6 +457,10 @@ def check_keys(expr_elem, meta, required, optional=[]):
> raise QAPIExprError(info,
> "%s '%s' has unknown key '%s'"
> % (meta, name, key))
> + if (key == 'gen' or key == 'success-response') and value != 'no':
> + raise QAPIExprError(info,
> + "'%s' of %s '%s' should only have value 'no'"
> + % (key, meta, name))
> for key in required:
> if not expr.has_key(key):
> raise QAPIExprError(info,
[...]
[Qemu-devel] [PATCH v4 17/19] qapi: Drop inline subtype in query-version, Eric Blake, 2014/09/19
[Qemu-devel] [PATCH v4 01/19] qapi: Consistent whitespace in tests/Makefile, Eric Blake, 2014/09/19
[Qemu-devel] [PATCH v4 16/19] qapi: Drop tests for inline subtypes, Eric Blake, 2014/09/19
[Qemu-devel] [PATCH v4 02/19] qapi: Ignore files created during make check, Eric Blake, 2014/09/19
Re: [Qemu-devel] [PATCH v4 00/19] drop qapi nested structs, Eric Blake, 2014/09/26