json-parser: Accept 'null' in QMP
We document that in QMP, the client may send any json-value for the optional "id" key, and then return that same value on reply (both success and failures, insofar as the failure happened after parsing the id). [Note that the output may not be identical to the input, as whitespace may change and since we may reorder keys within a json-object, but that this still constitutes the same json-value]. However, we were not handling the JSON literal null, which counts as a json-value per RFC 7159. Also, down the road, given the QAPI schema of {'*foo':'str'} or {'*foo':'ComplexType'}, we could decide to allow the QMP client to pass { "foo":null } instead of the current representation of { } where omitting the key is the only way to get at the default NULL value. Such a change might be useful for argument introspection (if a type in older qemu lacks 'foo' altogether, then an explicit "foo":null probe will force an easily distinguished error message for whether the optional "foo" key is even understood in newer qemu). And if we add default values to optional arguments, allowing an explicit null would be required for getting a NULL value associated with an optional string that has a non-null default. But all that can come at a later day. The 'check-unit' testsuite is enhanced to test that parsing produces the same object as explicitly requesting a reference to the special qnull object. In addition, I tested with: $ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio -nodefaults {"QMP": {"version": {"qemu": {"micro": 91, "minor": 2, "major": 2}, "package": ""}, "capabilities": []}} {"execute":"qmp_capabilities","id":null} {"return": {}, "id": null} {"id":{"a":null,"b":[1,null]},"execute":"quit"} {"return": {}, "id": {"a": null, "b": [1, null]}} {"timestamp": {"seconds": 1427742379, "microseconds": 423128}, "event": "SHUTDOWN"} Signed-off-by: Eric Blake <eblake@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
This commit is contained in:
parent
481b002cc8
commit
e549e7161f
@ -561,6 +561,8 @@ static QObject *parse_keyword(JSONParserContext *ctxt)
|
||||
ret = QOBJECT(qbool_from_int(true));
|
||||
} else if (token_is_keyword(token, "false")) {
|
||||
ret = QOBJECT(qbool_from_int(false));
|
||||
} else if (token_is_keyword(token, "null")) {
|
||||
ret = qnull();
|
||||
} else {
|
||||
parse_error(ctxt, token, "invalid keyword `%s'", token_get_value(token));
|
||||
goto out;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright IBM, Corp. 2009
|
||||
* Copyright (c) 2013 Red Hat Inc.
|
||||
* Copyright (c) 2013, 2015 Red Hat Inc.
|
||||
*
|
||||
* Authors:
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
@ -1005,6 +1005,7 @@ static void keyword_literal(void)
|
||||
{
|
||||
QObject *obj;
|
||||
QBool *qbool;
|
||||
QObject *null;
|
||||
QString *str;
|
||||
|
||||
obj = qobject_from_json("true");
|
||||
@ -1050,6 +1051,16 @@ static void keyword_literal(void)
|
||||
g_assert(qbool_get_int(qbool) != 0);
|
||||
|
||||
QDECREF(qbool);
|
||||
|
||||
obj = qobject_from_json("null");
|
||||
g_assert(obj != NULL);
|
||||
g_assert(qobject_type(obj) == QTYPE_QNULL);
|
||||
|
||||
null = qnull();
|
||||
g_assert(null == obj);
|
||||
|
||||
qobject_decref(obj);
|
||||
qobject_decref(null);
|
||||
}
|
||||
|
||||
typedef struct LiteralQDictEntry LiteralQDictEntry;
|
||||
|
Loading…
Reference in New Issue
Block a user