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 }; | ||||
|     QObject *result; | ||||
| 
 | ||||
|     if (!tokens) { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     result = parse_value(&ctxt, ap); | ||||
| 
 | ||||
|     error_propagate(errp, ctxt.err); | ||||
|  | ||||
| @ -39,9 +39,9 @@ void json_message_process_token(JSONLexer *lexer, GString *input, | ||||
|                                 JSONTokenType type, int x, int y) | ||||
| { | ||||
|     JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer); | ||||
|     QObject *json = NULL; | ||||
|     Error *err = NULL; | ||||
|     JSONToken *token; | ||||
|     QObject *json; | ||||
| 
 | ||||
|     switch (type) { | ||||
|     case JSON_LCURLY: | ||||
| @ -72,34 +72,33 @@ void json_message_process_token(JSONLexer *lexer, GString *input, | ||||
|     g_queue_push_tail(parser->tokens, token); | ||||
| 
 | ||||
|     if (type == JSON_ERROR) { | ||||
|         goto out_emit_bad; | ||||
|     } else if (parser->brace_count < 0 || | ||||
|         goto out_emit; | ||||
|     } | ||||
| 
 | ||||
|     if (parser->brace_count < 0 || | ||||
|         parser->bracket_count < 0 || | ||||
|         (parser->brace_count == 0 && | ||||
|          parser->bracket_count == 0)) { | ||||
|         json = json_parser_parse(parser->tokens, parser->ap, &err); | ||||
|         parser->tokens = NULL; | ||||
|         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 || | ||||
|                parser->bracket_count + parser->brace_count > MAX_NESTING) { | ||||
|         /* Security consideration, we limit total memory allocated per object
 | ||||
|          * and the maximum recursion depth that a message can force. | ||||
|          */ | ||||
|         goto out_emit_bad; | ||||
|         goto out_emit; | ||||
|     } | ||||
| 
 | ||||
|     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: | ||||
|     /* send current list of tokens to parser and reset tokenizer */ | ||||
|     parser->brace_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->token_size = 0; | ||||
|     parser->emit(parser->opaque, json, err); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Markus Armbruster
						Markus Armbruster