json: Don't pass null @tokens to json_parser_parse()
json_parser_parse() normally returns the QObject on success. Except it returns null when its @tokens argument is null. Its only caller json_message_process_token() passes null @tokens when emitting a lexical error. The call is a rather opaque way to say json = NULL then. Simplify matters by lifting the assignment to json out of the emit path: initialize json to null, set it to the value of json_parser_parse() when there's no lexical error. Drop the special case from json_parser_parse(). Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180823164025.12553-36-armbru@redhat.com>
This commit is contained in:
parent
62815d85ae
commit
ff281a272f
@ -546,10 +546,6 @@ QObject *json_parser_parse(GQueue *tokens, va_list *ap, Error **errp)
|
|||||||
JSONParserContext ctxt = { .buf = tokens };
|
JSONParserContext ctxt = { .buf = tokens };
|
||||||
QObject *result;
|
QObject *result;
|
||||||
|
|
||||||
if (!tokens) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = parse_value(&ctxt, ap);
|
result = parse_value(&ctxt, ap);
|
||||||
|
|
||||||
error_propagate(errp, ctxt.err);
|
error_propagate(errp, ctxt.err);
|
||||||
|
@ -39,9 +39,9 @@ void json_message_process_token(JSONLexer *lexer, GString *input,
|
|||||||
JSONTokenType type, int x, int y)
|
JSONTokenType type, int x, int y)
|
||||||
{
|
{
|
||||||
JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
|
JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
|
||||||
|
QObject *json = NULL;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
JSONToken *token;
|
JSONToken *token;
|
||||||
QObject *json;
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case JSON_LCURLY:
|
case JSON_LCURLY:
|
||||||
@ -72,34 +72,33 @@ void json_message_process_token(JSONLexer *lexer, GString *input,
|
|||||||
g_queue_push_tail(parser->tokens, token);
|
g_queue_push_tail(parser->tokens, token);
|
||||||
|
|
||||||
if (type == JSON_ERROR) {
|
if (type == JSON_ERROR) {
|
||||||
goto out_emit_bad;
|
goto out_emit;
|
||||||
} else if (parser->brace_count < 0 ||
|
}
|
||||||
|
|
||||||
|
if (parser->brace_count < 0 ||
|
||||||
parser->bracket_count < 0 ||
|
parser->bracket_count < 0 ||
|
||||||
(parser->brace_count == 0 &&
|
(parser->brace_count == 0 &&
|
||||||
parser->bracket_count == 0)) {
|
parser->bracket_count == 0)) {
|
||||||
|
json = json_parser_parse(parser->tokens, parser->ap, &err);
|
||||||
|
parser->tokens = NULL;
|
||||||
goto out_emit;
|
goto out_emit;
|
||||||
} else if (parser->token_size > MAX_TOKEN_SIZE ||
|
}
|
||||||
|
|
||||||
|
if (parser->token_size > MAX_TOKEN_SIZE ||
|
||||||
g_queue_get_length(parser->tokens) > MAX_TOKEN_COUNT ||
|
g_queue_get_length(parser->tokens) > MAX_TOKEN_COUNT ||
|
||||||
parser->bracket_count + parser->brace_count > MAX_NESTING) {
|
parser->bracket_count + parser->brace_count > MAX_NESTING) {
|
||||||
/* Security consideration, we limit total memory allocated per object
|
/* Security consideration, we limit total memory allocated per object
|
||||||
* and the maximum recursion depth that a message can force.
|
* and the maximum recursion depth that a message can force.
|
||||||
*/
|
*/
|
||||||
goto out_emit_bad;
|
goto out_emit;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
out_emit_bad:
|
|
||||||
/*
|
|
||||||
* Clear out token list and tell the parser to emit an error
|
|
||||||
* indication by passing it a NULL list
|
|
||||||
*/
|
|
||||||
json_message_free_tokens(parser);
|
|
||||||
out_emit:
|
out_emit:
|
||||||
/* send current list of tokens to parser and reset tokenizer */
|
|
||||||
parser->brace_count = 0;
|
parser->brace_count = 0;
|
||||||
parser->bracket_count = 0;
|
parser->bracket_count = 0;
|
||||||
json = json_parser_parse(parser->tokens, parser->ap, &err);
|
json_message_free_tokens(parser);
|
||||||
parser->tokens = g_queue_new();
|
parser->tokens = g_queue_new();
|
||||||
parser->token_size = 0;
|
parser->token_size = 0;
|
||||||
parser->emit(parser->opaque, json, err);
|
parser->emit(parser->opaque, json, err);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user