[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 13/18] qapi: check invalid arguments on no-args comma
From: |
Markus Armbruster |
Subject: |
[Qemu-devel] [PULL 13/18] qapi: check invalid arguments on no-args commands |
Date: |
Mon, 19 Sep 2016 18:41:29 +0200 |
From: Marc-André Lureau <address@hidden>
The generated marshal functions do not visit arguments from commands
that take no arguments. Thus they fail to catch invalid
members. Visit the arguments, if provided, to throw an error in case of
invalid members.
Currently, qmp_check_client_args() checks for invalid arguments and
correctly catches this case. When switching to qmp_dispatch() we want to
keep that behaviour. The commands using 'O' may have arbitrary
arguments, and must have 'gen': false in the qapi schema to skip the
generated checks.
Old/new diff:
void qmp_marshal_stop(QDict *args, QObject **ret, Error **errp)
{
Error *err = NULL;
+ Visitor *v = NULL;
- (void)args;
+ if (args) {
+ v = qmp_input_visitor_new(QOBJECT(args), true);
+ visit_start_struct(v, NULL, NULL, 0, &err);
+ if (err) {
+ goto out;
+ }
+
+ if (!err) {
+ visit_check_struct(v, &err);
+ }
+ visit_end_struct(v, NULL);
+ if (err) {
+ goto out;
+ }
+ }
qmp_stop(&err);
+
+out:
error_propagate(errp, err);
+ visit_free(v);
+ if (args) {
+ v = qapi_dealloc_visitor_new();
+ visit_start_struct(v, NULL, NULL, 0, NULL);
+
+ visit_end_struct(v, NULL);
+ visit_free(v);
+ }
}
The new code closely resembles code for a command with arguments.
Differences:
- the visit of the argument and its cleanup struct don't visit any
members (because there are none).
- the visit of the argument struct and its cleanup are conditional.
Signed-off-by: Marc-André Lureau <address@hidden>
Message-Id: <address@hidden>
Reviewed-by: Markus Armbruster <address@hidden>
Signed-off-by: Markus Armbruster <address@hidden>
---
scripts/qapi-commands.py | 60 ++++++++++++++++++++++++++++++++++-------------
tests/test-qmp-commands.c | 15 ++++++++++++
2 files changed, 59 insertions(+), 16 deletions(-)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index eac64ce..2f603b0 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -95,6 +95,8 @@ def gen_marshal_decl(name):
def gen_marshal(name, arg_type, boxed, ret_type):
+ have_args = arg_type and not arg_type.is_empty()
+
ret = mcgen('''
%(proto)s
@@ -109,17 +111,31 @@ def gen_marshal(name, arg_type, boxed, ret_type):
''',
c_type=ret_type.c_type())
- if arg_type and not arg_type.is_empty():
+ if have_args:
+ visit_members = ('visit_type_%s_members(v, &arg, &err);'
+ % arg_type.c_name())
ret += mcgen('''
Visitor *v;
%(c_name)s arg = {0};
+''',
+ c_name=arg_type.c_name())
+ else:
+ visit_members = ''
+ ret += mcgen('''
+ Visitor *v = NULL;
+
+ if (args) {
+''')
+ push_indent()
+
+ ret += mcgen('''
v = qmp_input_visitor_new(QOBJECT(args), true);
visit_start_struct(v, NULL, NULL, 0, &err);
if (err) {
goto out;
}
- visit_type_%(c_name)s_members(v, &arg, &err);
+ %(visit_members)s
if (!err) {
visit_check_struct(v, &err);
}
@@ -128,35 +144,47 @@ def gen_marshal(name, arg_type, boxed, ret_type):
goto out;
}
''',
- c_name=arg_type.c_name())
+ visit_members=visit_members)
- else:
+ if not have_args:
+ pop_indent()
ret += mcgen('''
-
- (void)args;
+ }
''')
ret += gen_call(name, arg_type, boxed, ret_type)
- # 'goto out' produced above for arg_type, and by gen_call() for ret_type
- if (arg_type and not arg_type.is_empty()) or ret_type:
- ret += mcgen('''
+ ret += mcgen('''
out:
-''')
- ret += mcgen('''
error_propagate(errp, err);
-''')
- if arg_type and not arg_type.is_empty():
- ret += mcgen('''
visit_free(v);
+''')
+
+ if have_args:
+ visit_members = ('visit_type_%s_members(v, &arg, NULL);'
+ % arg_type.c_name())
+ else:
+ visit_members = ''
+ ret += mcgen('''
+ if (args) {
+''')
+ push_indent()
+
+ ret += mcgen('''
v = qapi_dealloc_visitor_new();
visit_start_struct(v, NULL, NULL, 0, NULL);
- visit_type_%(c_name)s_members(v, &arg, NULL);
+ %(visit_members)s
visit_end_struct(v, NULL);
visit_free(v);
''',
- c_name=arg_type.c_name())
+ visit_members=visit_members)
+
+ if not have_args:
+ pop_indent()
+ ret += mcgen('''
+ }
+''')
ret += mcgen('''
}
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 261fd9e..81cbe54 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -106,6 +106,7 @@ static void test_dispatch_cmd(void)
static void test_dispatch_cmd_failure(void)
{
QDict *req = qdict_new();
+ QDict *args = qdict_new();
QObject *resp;
qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
@@ -116,6 +117,20 @@ static void test_dispatch_cmd_failure(void)
qobject_decref(resp);
QDECREF(req);
+
+ /* check that with extra arguments it throws an error */
+ req = qdict_new();
+ qdict_put(args, "a", qint_from_int(66));
+ qdict_put(req, "arguments", args);
+
+ qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));
+
+ resp = qmp_dispatch(QOBJECT(req));
+ assert(resp != NULL);
+ assert(qdict_haskey(qobject_to_qdict(resp), "error"));
+
+ qobject_decref(resp);
+ QDECREF(req);
}
static QObject *test_qmp_dispatch(QDict *req)
--
2.5.5
- [Qemu-devel] [PULL 00/18] QAPI patches for 2016-09-19, Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 03/18] qapi-schema: add 'device_add', Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 05/18] monitor: register gen:false commands manually, Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 08/18] qapi: export the marshallers, Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 10/18] monitor: implement 'qmp_query_commands' without qmp_cmds, Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 13/18] qapi: check invalid arguments on no-args commands,
Markus Armbruster <=
- [Qemu-devel] [PULL 14/18] tests: add a test to check invalid args, Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 04/18] monitor: simplify invalid_qmp_mode(), Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 01/18] build-sys: define QEMU_VERSION_{MAJOR, MINOR, MICRO}, Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 06/18] qapi: Support unregistering QMP commands, Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 02/18] qapi-schema: use generated marshaller for 'qmp_capabilities', Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 17/18] qmp-commands.hx: fix some styling, Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 16/18] build-sys: remove qmp-commands-old.h, Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 12/18] qapi: remove the "middle" mode, Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 18/18] Replace qmp-commands.hx by docs/qmp-commands.txt, Markus Armbruster, 2016/09/19
- [Qemu-devel] [PULL 07/18] qmp: Hack to keep commands configuration-specific, Markus Armbruster, 2016/09/19