json-parser: detect premature EOI
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
eca7db46ff
commit
11e8a46cc3
@ -275,10 +275,15 @@ out:
|
|||||||
*/
|
*/
|
||||||
static int parse_pair(JSONParserContext *ctxt, QDict *dict, QList **tokens, va_list *ap)
|
static int parse_pair(JSONParserContext *ctxt, QDict *dict, QList **tokens, va_list *ap)
|
||||||
{
|
{
|
||||||
QObject *key, *token = NULL, *value, *peek;
|
QObject *key = NULL, *token = NULL, *value, *peek;
|
||||||
QList *working = qlist_copy(*tokens);
|
QList *working = qlist_copy(*tokens);
|
||||||
|
|
||||||
peek = qlist_peek(working);
|
peek = qlist_peek(working);
|
||||||
|
if (peek == NULL) {
|
||||||
|
parse_error(ctxt, NULL, "premature EOI");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
key = parse_value(ctxt, &working, ap);
|
key = parse_value(ctxt, &working, ap);
|
||||||
if (!key || qobject_type(key) != QTYPE_QSTRING) {
|
if (!key || qobject_type(key) != QTYPE_QSTRING) {
|
||||||
parse_error(ctxt, peek, "key is not a string in object");
|
parse_error(ctxt, peek, "key is not a string in object");
|
||||||
@ -286,6 +291,11 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict, QList **tokens, va_l
|
|||||||
}
|
}
|
||||||
|
|
||||||
token = qlist_pop(working);
|
token = qlist_pop(working);
|
||||||
|
if (token == NULL) {
|
||||||
|
parse_error(ctxt, NULL, "premature EOI");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!token_is_operator(token, ':')) {
|
if (!token_is_operator(token, ':')) {
|
||||||
parse_error(ctxt, token, "missing : in object pair");
|
parse_error(ctxt, token, "missing : in object pair");
|
||||||
goto out;
|
goto out;
|
||||||
@ -321,6 +331,10 @@ static QObject *parse_object(JSONParserContext *ctxt, QList **tokens, va_list *a
|
|||||||
QList *working = qlist_copy(*tokens);
|
QList *working = qlist_copy(*tokens);
|
||||||
|
|
||||||
token = qlist_pop(working);
|
token = qlist_pop(working);
|
||||||
|
if (token == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!token_is_operator(token, '{')) {
|
if (!token_is_operator(token, '{')) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -330,12 +344,22 @@ static QObject *parse_object(JSONParserContext *ctxt, QList **tokens, va_list *a
|
|||||||
dict = qdict_new();
|
dict = qdict_new();
|
||||||
|
|
||||||
peek = qlist_peek(working);
|
peek = qlist_peek(working);
|
||||||
|
if (peek == NULL) {
|
||||||
|
parse_error(ctxt, NULL, "premature EOI");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!token_is_operator(peek, '}')) {
|
if (!token_is_operator(peek, '}')) {
|
||||||
if (parse_pair(ctxt, dict, &working, ap) == -1) {
|
if (parse_pair(ctxt, dict, &working, ap) == -1) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
token = qlist_pop(working);
|
token = qlist_pop(working);
|
||||||
|
if (token == NULL) {
|
||||||
|
parse_error(ctxt, NULL, "premature EOI");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
while (!token_is_operator(token, '}')) {
|
while (!token_is_operator(token, '}')) {
|
||||||
if (!token_is_operator(token, ',')) {
|
if (!token_is_operator(token, ',')) {
|
||||||
parse_error(ctxt, token, "expected separator in dict");
|
parse_error(ctxt, token, "expected separator in dict");
|
||||||
@ -349,6 +373,10 @@ static QObject *parse_object(JSONParserContext *ctxt, QList **tokens, va_list *a
|
|||||||
}
|
}
|
||||||
|
|
||||||
token = qlist_pop(working);
|
token = qlist_pop(working);
|
||||||
|
if (token == NULL) {
|
||||||
|
parse_error(ctxt, NULL, "premature EOI");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
qobject_decref(token);
|
qobject_decref(token);
|
||||||
token = NULL;
|
token = NULL;
|
||||||
@ -377,6 +405,10 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap
|
|||||||
QList *working = qlist_copy(*tokens);
|
QList *working = qlist_copy(*tokens);
|
||||||
|
|
||||||
token = qlist_pop(working);
|
token = qlist_pop(working);
|
||||||
|
if (token == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!token_is_operator(token, '[')) {
|
if (!token_is_operator(token, '[')) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -386,6 +418,11 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap
|
|||||||
list = qlist_new();
|
list = qlist_new();
|
||||||
|
|
||||||
peek = qlist_peek(working);
|
peek = qlist_peek(working);
|
||||||
|
if (peek == NULL) {
|
||||||
|
parse_error(ctxt, NULL, "premature EOI");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!token_is_operator(peek, ']')) {
|
if (!token_is_operator(peek, ']')) {
|
||||||
QObject *obj;
|
QObject *obj;
|
||||||
|
|
||||||
@ -398,6 +435,11 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap
|
|||||||
qlist_append_obj(list, obj);
|
qlist_append_obj(list, obj);
|
||||||
|
|
||||||
token = qlist_pop(working);
|
token = qlist_pop(working);
|
||||||
|
if (token == NULL) {
|
||||||
|
parse_error(ctxt, NULL, "premature EOI");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
while (!token_is_operator(token, ']')) {
|
while (!token_is_operator(token, ']')) {
|
||||||
if (!token_is_operator(token, ',')) {
|
if (!token_is_operator(token, ',')) {
|
||||||
parse_error(ctxt, token, "expected separator in list");
|
parse_error(ctxt, token, "expected separator in list");
|
||||||
@ -416,6 +458,10 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap
|
|||||||
qlist_append_obj(list, obj);
|
qlist_append_obj(list, obj);
|
||||||
|
|
||||||
token = qlist_pop(working);
|
token = qlist_pop(working);
|
||||||
|
if (token == NULL) {
|
||||||
|
parse_error(ctxt, NULL, "premature EOI");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qobject_decref(token);
|
qobject_decref(token);
|
||||||
@ -444,6 +490,9 @@ static QObject *parse_keyword(JSONParserContext *ctxt, QList **tokens)
|
|||||||
QList *working = qlist_copy(*tokens);
|
QList *working = qlist_copy(*tokens);
|
||||||
|
|
||||||
token = qlist_pop(working);
|
token = qlist_pop(working);
|
||||||
|
if (token == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (token_get_type(token) != JSON_KEYWORD) {
|
if (token_get_type(token) != JSON_KEYWORD) {
|
||||||
goto out;
|
goto out;
|
||||||
@ -481,6 +530,9 @@ static QObject *parse_escape(JSONParserContext *ctxt, QList **tokens, va_list *a
|
|||||||
}
|
}
|
||||||
|
|
||||||
token = qlist_pop(working);
|
token = qlist_pop(working);
|
||||||
|
if (token == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (token_is_escape(token, "%p")) {
|
if (token_is_escape(token, "%p")) {
|
||||||
obj = va_arg(*ap, QObject *);
|
obj = va_arg(*ap, QObject *);
|
||||||
@ -520,6 +572,10 @@ static QObject *parse_literal(JSONParserContext *ctxt, QList **tokens)
|
|||||||
QList *working = qlist_copy(*tokens);
|
QList *working = qlist_copy(*tokens);
|
||||||
|
|
||||||
token = qlist_pop(working);
|
token = qlist_pop(working);
|
||||||
|
if (token == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
switch (token_get_type(token)) {
|
switch (token_get_type(token)) {
|
||||||
case JSON_STRING:
|
case JSON_STRING:
|
||||||
obj = QOBJECT(qstring_from_escaped_str(ctxt, token));
|
obj = QOBJECT(qstring_from_escaped_str(ctxt, token));
|
||||||
|
Loading…
Reference in New Issue
Block a user