From patchwork Tue Jun 22 17:40:47 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Capitulino X-Patchwork-Id: 56553 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1DD2BB6F0C for ; Wed, 23 Jun 2010 03:53:24 +1000 (EST) Received: from localhost ([127.0.0.1]:41578 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OR7f0-0002qo-0v for incoming@patchwork.ozlabs.org; Tue, 22 Jun 2010 13:53:22 -0400 Received: from [140.186.70.92] (port=55612 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OR7Tg-0004YK-FN for qemu-devel@nongnu.org; Tue, 22 Jun 2010 13:41:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OR7TO-0000dn-St for qemu-devel@nongnu.org; Tue, 22 Jun 2010 13:41:24 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44244) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OR7TO-0000dh-KL for qemu-devel@nongnu.org; Tue, 22 Jun 2010 13:41:22 -0400 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o5MHfLtH019455 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 22 Jun 2010 13:41:21 -0400 Received: from localhost (vpn-10-15.rdu.redhat.com [10.11.10.15]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o5MHfK6m031374; Tue, 22 Jun 2010 13:41:21 -0400 From: Luiz Capitulino To: qemu-devel@nongnu.org Date: Tue, 22 Jun 2010 14:40:47 -0300 Message-Id: <1277228451-7741-10-git-send-email-lcapitulino@redhat.com> In-Reply-To: <1277228451-7741-1-git-send-email-lcapitulino@redhat.com> References: <1277228451-7741-1-git-send-email-lcapitulino@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: armbru@redhat.com Subject: [Qemu-devel] [PATCH 09/13] QMP: New argument checker (second part) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This commit introduces the second (and last) part of QMP's new argument checker. The job is done by check_client_args_type(), it iterates over the client's argument qdict and for for each argument it checks if it exists and if its type is valid. It's important to observe the following changes from the existing argument checker: - If the handler accepts an O-type argument, unknown arguments are passed down to it. It's up to O-type handlers to validate their arguments - Boolean types (eg. 'b' and '-') don't accept integers anymore, only json-bool - Argument types '/' and '.' are currently unsupported under QMP, thus they're not handled Signed-off-by: Luiz Capitulino --- monitor.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 99 insertions(+), 1 deletions(-) diff --git a/monitor.c b/monitor.c index b4fe5ba..8d074c2 100644 --- a/monitor.c +++ b/monitor.c @@ -4139,6 +4139,101 @@ static int invalid_qmp_mode(const Monitor *mon, const char *cmd_name) } /* + * Argument validation rules: + * + * 1. The argument must exist in cmd_args qdict + * 2. The argument type must be the expected one + * + * Special case: If the argument doesn't exist in cmd_args and + * the QMP_CHECKER_OTYPE flag is set, then the + * argument is considered an O-type one and the + * checking is skipped for it. + */ +static int check_client_args_type(const QDict *client_args, + const QDict *cmd_args, int flags) +{ + const QDictEntry *ent; + + for (ent = qdict_first(client_args); ent;ent = qdict_next(client_args,ent)){ + QObject *obj; + QString *arg_type; + const QObject *client_arg = qdict_entry_value(ent); + const char *client_arg_name = qdict_entry_key(ent); + + obj = qdict_get(cmd_args, client_arg_name); + if (!obj) { + if (flags & QMP_CHECKER_OTYPE) { + /* + * This handler accepts O-type arguments, it's up to it to + * check for unknowns and validate its type. + */ + continue; + } + /* client arg doesn't exist */ + qerror_report(QERR_INVALID_PARAMETER, client_arg_name); + return -1; + } + + arg_type = qobject_to_qstring(obj); + assert(arg_type != NULL); + + /* check if argument's type is correct */ + switch (qstring_get_str(arg_type)[0]) { + case 'F': + case 'B': + case 's': + if (qobject_type(client_arg) != QTYPE_QSTRING) { + qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name, + "string"); + return -1; + } + break; + case 'i': + case 'l': + case 'M': + if (qobject_type(client_arg) != QTYPE_QINT) { + qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name, + "int"); + return -1; + } + break; + case 'f': + case 'T': + if (qobject_type(client_arg) != QTYPE_QINT && + qobject_type(client_arg) != QTYPE_QFLOAT) { + qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name, + "number"); + return -1; + } + break; + case 'b': + case '-': + if (qobject_type(client_arg) != QTYPE_QBOOL) { + qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name, + "bool"); + return -1; + } + break; + case 'O': + /* XXX: this argument has the same name of the O-type defined in + in qemu-monitor.hx. This is not allowed, right? */ + qerror_report(QERR_INVALID_PARAMETER, client_arg_name); + return -1; + case '/': + case '.': + /* + * These types are not supported by QMP and thus are not + * handled here. Fall through. + */ + default: + abort(); + } + } + + return 0; +} + +/* * - Check if the client has passed all mandatory args * - Set special flags for argument validation */ @@ -4215,6 +4310,9 @@ out: * Client argument checking rules: * * 1. Client must provide all mandatory arguments + * 2. Each argument provided by the client must be expected + * 3. Each argument provided by the client must have the type expected + * by the command */ static int qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args) { @@ -4229,7 +4327,7 @@ static int qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args) goto out; } - /* TODO: Check client args type */ + err = check_client_args_type(client_args, cmd_args, flags); out: QDECREF(cmd_args);