From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39936) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1acLya-0008U7-CU for qemu-devel@nongnu.org; Sat, 05 Mar 2016 18:51:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1acLyZ-0005qG-EY for qemu-devel@nongnu.org; Sat, 05 Mar 2016 18:51:12 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38380) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1acLyZ-0005pw-AN for qemu-devel@nongnu.org; Sat, 05 Mar 2016 18:51:11 -0500 From: Eric Blake Date: Sat, 5 Mar 2016 16:50:57 -0700 Message-Id: <1457221861-18067-15-git-send-email-eblake@redhat.com> In-Reply-To: <1457221861-18067-1-git-send-email-eblake@redhat.com> References: <1457221861-18067-1-git-send-email-eblake@redhat.com> Subject: [Qemu-devel] [PATCH v13 14/18] qapi-commands: Wrap argument visit in visit_start_struct List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: armbru@redhat.com, Michael Roth The qmp-input visitor was playing rather fast and loose: when visiting a QDict, you could grab members of the root dictionary without first pushing into the dict. But we are about to tighten the input visitor, at which point the generated marshal code MUST follow the same paradigms as everyone else, of pushing into the struct before grabbing its keys, because the value of 'name' should be ignored on the top-level visit. Generated code grows as follows: |@@ -515,7 +695,15 @@ void qmp_marshal_blockdev_backup(QDict * | BlockdevBackup qapi = {0}; | | v = qmp_input_get_visitor(qiv); |+ visit_start_struct(v, NULL, NULL, 0, &err); |+ if (err) { |+ goto out; |+ } | visit_type_BlockdevBackup_members(v, &qapi, &err); |+ if (!err) { |+ visit_check_struct(v, &err); |+ } |+ visit_end_struct(v); | if (err) { | goto out; | } |@@ -527,7 +715,9 @@ out: | qmp_input_visitor_cleanup(qiv); | qdv = qapi_dealloc_visitor_new(); | v = qapi_dealloc_get_visitor(qdv); |+ visit_start_struct(v, NULL, NULL, 0, NULL); | visit_type_BlockdevBackup_members(v, &qapi, NULL); |+ visit_end_struct(v); | qapi_dealloc_visitor_cleanup(qdv); | } Note that this change could also make it possible for the marshalling code to automatically detect excess input at the top level, and not just in nested dictionaries. However, that checking is not currently useful (and we rely on the manual checking in monitor.c:qmp_check_client_args() instead) as long as qmp-commands.hx uses .args_type, and as long as we have 'name:O' as an arg-type that explicitly allows unknown top-level keys because we haven't yet converted 'device_add' and 'netdev_add' to introspectible use of 'any'. Signed-off-by: Eric Blake --- v13: rebase to earlier patches v12: new patch --- scripts/qapi-commands.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index 710e853..8b1a676 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -121,7 +121,15 @@ def gen_marshal(name, arg_type, ret_type): %(c_name)s qapi = {0}; v = qmp_input_get_visitor(qiv); + visit_start_struct(v, NULL, NULL, 0, &err); + if (err) { + goto out; + } visit_type_%(c_name)s_members(v, &qapi, &err); + if (!err) { + visit_check_struct(v, &err); + } + visit_end_struct(v); if (err) { goto out; } @@ -150,7 +158,9 @@ out: qmp_input_visitor_cleanup(qiv); qdv = qapi_dealloc_visitor_new(); v = qapi_dealloc_get_visitor(qdv); + visit_start_struct(v, NULL, NULL, 0, NULL); visit_type_%(c_name)s_members(v, &qapi, NULL); + visit_end_struct(v); qapi_dealloc_visitor_cleanup(qdv); ''', c_name=arg_type.c_name()) -- 2.5.0