From ae11e9174df142cdede593a5b6b36b53b6b42f57 Mon Sep 17 00:00:00 2001 From: Jeffrey Cody Date: Tue, 20 Mar 2012 14:07:27 -0300 Subject: [RHEL6 qemu-kvm PATCH 07/21] QMP: Introduce qmp_check_input_obj() RH-Author: Jeffrey Cody Message-id: Patchwork-id: 38631 O-Subject: [RHEL6.3 qemu-kvm PATCH v3 07/21] QMP: Introduce qmp_check_input_obj() Bugzilla: 784153 RH-Acked-by: Kevin Wolf RH-Acked-by: Paolo Bonzini RH-Acked-by: Markus Armbruster From: Luiz Capitulino This is similar to qmp_check_client_args(), but it checks if the input object follows the specification (QMP/qmp-spec.txt section 2.3). As we're limited to three keys, the work here is quite simple: we iterate over the input object, checking each time if the current argument complies to the specification. Signed-off-by: Luiz Capitulino (cherry picked from commit c917c8f3d07816f018a96121422de3b53f525fe4) Signed-off-by: Jeff Cody --- monitor.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 61 insertions(+), 1 deletions(-) Signed-off-by: Eduardo Habkost --- monitor.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 61 insertions(+), 1 deletions(-) diff --git a/monitor.c b/monitor.c index 3ff955b..a1342ea 100644 --- a/monitor.c +++ b/monitor.c @@ -4608,6 +4608,62 @@ out: return err; } +/* + * Input object checking rules + * + * 1. Input object must be a dict + * 2. The "execute" key must exist + * 3. The "execute" key must be a string + * 4. If the "arguments" key exists, it must be a dict + * 5. If the "id" key exists, it can be anything (ie. json-value) + * 6. Any argument not listed above is considered invalid + */ +static QDict *qmp_check_input_obj(QObject *input_obj) +{ + const QDictEntry *ent; + int has_exec_key = 0; + QDict *input_dict; + + if (qobject_type(input_obj) != QTYPE_QDICT) { + qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "object"); + return NULL; + } + + input_dict = qobject_to_qdict(input_obj); + + for (ent = qdict_first(input_dict); ent; ent = qdict_next(input_dict, ent)){ + const char *arg_name = qdict_entry_key(ent); + const QObject *arg_obj = qdict_entry_value(ent); + + if (!strcmp(arg_name, "execute")) { + if (qobject_type(arg_obj) != QTYPE_QSTRING) { + qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "execute", + "string"); + return NULL; + } + has_exec_key = 1; + } else if (!strcmp(arg_name, "arguments")) { + if (qobject_type(arg_obj) != QTYPE_QDICT) { + qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "arguments", + "object"); + return NULL; + } + } else if (!strcmp(arg_name, "id")) { + /* FIXME: check duplicated IDs for async commands */ + } else { + qerror_report(QERR_QMP_EXTRA_MEMBER, arg_name); + return NULL; + } + } + + if (!has_exec_key) { + qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "execute"); + return NULL; + } + + return input_dict; +} + static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) { int err; @@ -4630,7 +4686,11 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) goto err_out; } - input = qobject_to_qdict(obj); + input = qmp_check_input_obj(obj); + if (!input) { + qobject_decref(obj); + goto err_out; + } mon->mc->id = qdict_get(input, "id"); qobject_incref(mon->mc->id); -- 1.7.3.2