From patchwork Thu May 12 07:58:55 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 9077431 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 86822BF29F for ; Thu, 12 May 2016 08:07:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 05704201F5 for ; Thu, 12 May 2016 08:07:18 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BA3A420155 for ; Thu, 12 May 2016 08:07:16 +0000 (UTC) Received: from localhost ([::1]:55910 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b0leN-00063y-Pb for patchwork-qemu-devel@patchwork.kernel.org; Thu, 12 May 2016 04:07:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54137) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b0lWj-0000tx-70 for qemu-devel@nongnu.org; Thu, 12 May 2016 03:59:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b0lWf-0006LF-Lv for qemu-devel@nongnu.org; Thu, 12 May 2016 03:59:21 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34385) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b0lWf-0006L8-CB for qemu-devel@nongnu.org; Thu, 12 May 2016 03:59:17 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CAA0A47047 for ; Thu, 12 May 2016 07:59:16 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-35.ams2.redhat.com [10.36.116.35]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u4C7xDMh011375 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 12 May 2016 03:59:15 -0400 Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 7CE94113295A; Thu, 12 May 2016 09:59:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 12 May 2016 09:58:55 +0200 Message-Id: <1463039950-4021-9-git-send-email-armbru@redhat.com> In-Reply-To: <1463039950-4021-1-git-send-email-armbru@redhat.com> References: <1463039950-4021-1-git-send-email-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 12 May 2016 07:59:16 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 08/23] qapi-commands: Wrap argument visit in visit_start_struct X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Blake The qmp-input visitor was allowing callers to play rather fast and loose: when visiting a QDict, you could grab members of the root dictionary without first pushing into the dict; among the culprit callers was the generated marshal code on the 'arguments' dictionary of a QMP command. 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. Generated code grows as follows: |@@ -515,7 +641,12 @@ void qmp_marshal_blockdev_backup(QDict * | BlockdevBackup arg = {0}; | | v = qmp_input_get_visitor(qiv); |+ visit_start_struct(v, NULL, NULL, 0, &err); |+ if (err) { |+ goto out; |+ } | visit_type_BlockdevBackup_members(v, &arg, &err); |+ visit_end_struct(v, err ? NULL : &err); | 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, &arg, NULL); |+ visit_end_struct(v, NULL); | qapi_dealloc_visitor_cleanup(qdv); | } The use of 'err ? NULL : &err' is temporary; a later patch will clean that up when it splits visit_end_struct(). Prior to this patch, the fact that there was no final visit_end_struct() meant that even though we are using a strict input visit, the marshalling code was not detecting excess input at the top level (only in nested levels). Fortunately, we have code in monitor.c:qmp_check_client_args() that also checks for no excess arguments at the top level. But as the generated code is more compact than the manual check, a later patch will clean up monitor.c to drop the redundancy added here. Signed-off-by: Eric Blake Message-Id: <1461879932-9020-9-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster --- docs/qapi-code-gen.txt | 7 +++++++ scripts/qapi-commands.py | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index 4a917f9..b4ae1be 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -1002,7 +1002,12 @@ Example: UserDefOneList *arg1 = NULL; v = qmp_input_get_visitor(qiv); + visit_start_struct(v, NULL, NULL, 0, &err); + if (err) { + goto out; + } visit_type_UserDefOneList(v, "arg1", &arg1, &err); + visit_end_struct(v, err ? NULL : &err); if (err) { goto out; } @@ -1019,7 +1024,9 @@ Example: 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_UserDefOneList(v, "arg1", &arg1, NULL); + visit_end_struct(v, NULL); qapi_dealloc_visitor_cleanup(qdv); } diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index 6261e44..04549fa 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -121,7 +121,12 @@ def gen_marshal(name, arg_type, ret_type): %(c_name)s arg = {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, &arg, &err); + visit_end_struct(v, err ? NULL : &err); if (err) { goto out; } @@ -150,7 +155,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, &arg, NULL); + visit_end_struct(v, NULL); qapi_dealloc_visitor_cleanup(qdv); ''', c_name=arg_type.c_name())