[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 14/19] qapi: More rigorous checking for type safe
From: |
Eric Blake |
Subject: |
[Qemu-devel] [PATCH v4 14/19] qapi: More rigorous checking for type safety bypass |
Date: |
Fri, 19 Sep 2014 16:24:59 -0600 |
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.
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'"
@@ -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)
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)
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,
diff --git a/tests/qapi-schema/type-bypass-bad-gen.err
b/tests/qapi-schema/type-bypass-bad-gen.err
index e69de29..c408364 100644
--- a/tests/qapi-schema/type-bypass-bad-gen.err
+++ b/tests/qapi-schema/type-bypass-bad-gen.err
@@ -0,0 +1 @@
+tests/qapi-schema/type-bypass-bad-gen.json:2: 'gen' of command 'foo' should
only have value 'no'
diff --git a/tests/qapi-schema/type-bypass-bad-gen.exit
b/tests/qapi-schema/type-bypass-bad-gen.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/type-bypass-bad-gen.exit
+++ b/tests/qapi-schema/type-bypass-bad-gen.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/type-bypass-bad-gen.json
b/tests/qapi-schema/type-bypass-bad-gen.json
index 6894526..5514b80 100644
--- a/tests/qapi-schema/type-bypass-bad-gen.json
+++ b/tests/qapi-schema/type-bypass-bad-gen.json
@@ -1,2 +1,2 @@
-# FIXME: 'gen' should only appear with value 'no'
+# 'gen' should only appear with value 'no'
{ 'command': 'foo', 'gen': 'whatever' }
diff --git a/tests/qapi-schema/type-bypass-bad-gen.out
b/tests/qapi-schema/type-bypass-bad-gen.out
index e678f2c..e69de29 100644
--- a/tests/qapi-schema/type-bypass-bad-gen.out
+++ b/tests/qapi-schema/type-bypass-bad-gen.out
@@ -1,3 +0,0 @@
-[OrderedDict([('command', 'foo'), ('gen', 'whatever')])]
-[]
-[]
diff --git a/tests/qapi-schema/type-bypass-no-gen.err
b/tests/qapi-schema/type-bypass-no-gen.err
index e69de29..294ca2e 100644
--- a/tests/qapi-schema/type-bypass-no-gen.err
+++ b/tests/qapi-schema/type-bypass-no-gen.err
@@ -0,0 +1 @@
+tests/qapi-schema/type-bypass-no-gen.json:2: member 'arg' of 'data' for
command 'unsafe' uses '**' but did not request 'gen':'no'
diff --git a/tests/qapi-schema/type-bypass-no-gen.exit
b/tests/qapi-schema/type-bypass-no-gen.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/type-bypass-no-gen.exit
+++ b/tests/qapi-schema/type-bypass-no-gen.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/type-bypass-no-gen.json
b/tests/qapi-schema/type-bypass-no-gen.json
index 72c817f..49b5742 100644
--- a/tests/qapi-schema/type-bypass-no-gen.json
+++ b/tests/qapi-schema/type-bypass-no-gen.json
@@ -1,2 +1,2 @@
-# FIXME: type bypass should only work with 'gen':'no'
+# type bypass only works with 'gen':'no'
{ 'command': 'unsafe', 'data': { 'arg': '**' }, 'returns': '**' }
diff --git a/tests/qapi-schema/type-bypass-no-gen.out
b/tests/qapi-schema/type-bypass-no-gen.out
index 8b2a9ac..e69de29 100644
--- a/tests/qapi-schema/type-bypass-no-gen.out
+++ b/tests/qapi-schema/type-bypass-no-gen.out
@@ -1,3 +0,0 @@
-[OrderedDict([('command', 'unsafe'), ('data', OrderedDict([('arg', '**')])),
('returns', '**')])]
-[]
-[]
--
1.9.3
- Re: [Qemu-devel] [PATCH v4 12/19] qapi: Add some type check tests, (continued)
[Qemu-devel] [PATCH v4 19/19] qapi: Drop support for inline subtypes, Eric Blake, 2014/09/19
[Qemu-devel] [PATCH v4 06/19] qapi: Better error messages for bad enums, Eric Blake, 2014/09/19
[Qemu-devel] [PATCH v4 18/19] qapi: Drop inline subtype in query-pci, Eric Blake, 2014/09/19
[Qemu-devel] [PATCH v4 15/19] qapi: Merge UserDefTwo and UserDefNested in tests, Eric Blake, 2014/09/19
[Qemu-devel] [PATCH v4 14/19] qapi: More rigorous checking for type safety bypass,
Eric Blake <=
[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