[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v7 27/39] qapi: More rigorous checking for type safe
From: |
Eric Blake |
Subject: |
[Qemu-devel] [PATCH v7 27/39] qapi: More rigorous checking for type safety bypass |
Date: |
Wed, 29 Apr 2015 07:06:42 -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, as well as 'gen':false as the
canonical spelling for requesting type bypass.
Note that 'gen':false is a one-way switch away from the default;
we do not support 'gen':true (similar for 'success-response').
In practice, this doesn't matter.
Signed-off-by: Eric Blake <address@hidden>
Reviewed-by: Markus Armbruster <address@hidden>
---
v7: fix typo in commit message
---
scripts/qapi.py | 22 +++++++++++++++++-----
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, 23 insertions(+), 15 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 2b52932..47b9d9f 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -324,14 +324,15 @@ def check_name(expr_info, source, name, allow_optional =
False,
"%s uses invalid name '%s'" % (source, name))
def check_type(expr_info, source, value, allow_array = False,
- allow_dict = False, allow_optional = False, allow_metas = []):
+ allow_dict = False, allow_optional = False,
+ allow_star = False, allow_metas = []):
global all_names
orig_value = value
if value is None:
return
- if value == '**':
+ if allow_star and value == '**':
return
# Check if array type for value is okay
@@ -348,6 +349,10 @@ def check_type(expr_info, source, value, allow_array =
False,
# Check if type name for value is okay
if isinstance(value, str):
+ if value == '**':
+ raise QAPIExprError(expr_info,
+ "%s uses '**' but did not request 'gen':false"
+ % source)
if not value in all_names:
raise QAPIExprError(expr_info,
"%s uses unknown type '%s'"
@@ -371,19 +376,22 @@ def check_type(expr_info, source, value, allow_array =
False,
check_type(expr_info, "Member '%s' of %s" % (key, source), arg,
allow_array=True, allow_dict=True, allow_optional=True,
allow_metas=['built-in', 'union', 'alternate', 'struct',
- 'enum'])
+ 'enum'], allow_star=allow_star)
def check_command(expr, expr_info):
name = expr['command']
+ allow_star = expr.has_key('gen')
+
check_type(expr_info, "'data' for command '%s'" % name,
expr.get('data'), allow_dict=True, allow_optional=True,
- allow_metas=['union', 'struct'])
+ allow_metas=['union', 'struct'], allow_star=allow_star)
returns_meta = ['union', 'struct']
if name in returns_whitelist:
returns_meta += ['built-in', 'alternate', 'enum']
check_type(expr_info, "'returns' for command '%s'" % name,
expr.get('returns'), allow_array=True, allow_dict=True,
- allow_optional=True, allow_metas=returns_meta)
+ allow_optional=True, allow_metas=returns_meta,
+ allow_star=allow_star)
def check_event(expr, expr_info):
global events
@@ -579,6 +587,10 @@ def check_keys(expr_elem, meta, required, optional=[]):
raise QAPIExprError(info,
"Unknown key '%s' in %s '%s'"
% (key, meta, name))
+ if (key == 'gen' or key == 'success-response') and value != False:
+ raise QAPIExprError(info,
+ "'%s' of %s '%s' should only use false value"
+ % (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..a83c3c6 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 use false value
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 bb70bee..e8dec34 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 false
+# 'gen' should only appear with value false
{ '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..20cef0a 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':false
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 af87c19..4feae37 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':false
+# type bypass only works with 'gen':false
{ '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', '**')])]
-[]
-[]
--
2.1.0
- [Qemu-devel] [PATCH v7 00/39] drop qapi nested structs, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 03/39] qapi: Simplify builtin type handling, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 06/39] qapi: Add some enum tests, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 10/39] qapi: Forbid base without discriminator in unions, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 12/39] qapi: Prepare for catching more semantic parse errors, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 02/39] qapi: Document type-safety considerations, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 15/39] qapi: Document new 'alternate' meta-type, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 22/39] qapi: Unify type bypass and add tests, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 27/39] qapi: More rigorous checking for type safety bypass,
Eric Blake <=
- [Qemu-devel] [PATCH v7 26/39] qapi: Whitelist commands that don't return dictionary, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 14/39] qapi: Rename anonymous union type in test, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 19/39] qapi: Add tests of redefined expressions, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 11/39] qapi: Tighten checking of unions, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 29/39] qapi: Document 'struct' metatype, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 21/39] qapi: Allow true, false and null in schema json, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 16/39] qapi: Use 'alternate' to replace anonymous union, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 18/39] qapi: Better error messages for bad expressions, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 13/39] qapi: Segregate anonymous unions into alternates in generator, Eric Blake, 2015/04/29
- [Qemu-devel] [PATCH v7 17/39] qapi: Add some expr tests, Eric Blake, 2015/04/29