diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2026-06-26 12:17:23 +0200 |
|---|---|---|
| committer | Markus Armbruster <armbru@redhat.com> | 2026-07-02 13:55:01 +0200 |
| commit | 19c04b99cad2aca987cda28671b1e959fc2cb6f7 (patch) | |
| tree | 70f02d83ec9f4a1629e4b2cbaa4524279aa288c5 | |
| parent | e8f8abcba14eecaf642f809e6ccf24feb547d6c7 (diff) | |
| download | qemu-19c04b99cad2aca987cda28671b1e959fc2cb6f7.tar.gz qemu-19c04b99cad2aca987cda28671b1e959fc2cb6f7.zip | |
json-streamer: make brace/bracket count unsigned
It makes no sense to let brace_count and bracket_count go negative,
also because it immediately ends error recovery and sets them both
back to zero. Instead set them to zero *before* choosing
whether to process the token queue; this makes it possible to
have the fields as unsigned.
Note that JSON_END_OF_INPUT now forces the parentheses to appear
balanced, so that the queue is emptied and an error is reported;
hence, the "type != JSON_END_OF_INPUT" condition can be removed.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-ID: <20260626101727.1727389-4-pbonzini@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Comment tweaked]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
| -rw-r--r-- | include/qobject/json-parser.h | 4 | ||||
| -rw-r--r-- | qobject/json-streamer.c | 24 |
2 files changed, 23 insertions, 5 deletions
diff --git a/include/qobject/json-parser.h b/include/qobject/json-parser.h index 4c3d89f751..0cf6932ecd 100644 --- a/include/qobject/json-parser.h +++ b/include/qobject/json-parser.h @@ -31,8 +31,8 @@ typedef struct JSONMessageParser { void *opaque; JSONLexer lexer; JSONParserContext parser; - int brace_count; - int bracket_count; + unsigned int brace_count; + unsigned int bracket_count; GQueue tokens; uint64_t token_size; } JSONMessageParser; diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c index 6c4f99b3e7..e18fd9bb0e 100644 --- a/qobject/json-streamer.c +++ b/qobject/json-streamer.c @@ -41,21 +41,41 @@ void json_message_process_token(JSONLexer *lexer, GString *input, parser->brace_count++; break; case JSON_RCURLY: + if (!parser->brace_count) { + goto end_error_recovery; + } parser->brace_count--; break; case JSON_LSQUARE: parser->bracket_count++; break; case JSON_RSQUARE: + if (!parser->bracket_count) { + goto end_error_recovery; + } parser->bracket_count--; break; case JSON_ERROR: error_setg(&err, "JSON parse error, stray '%s'", input->str); goto out_emit; case JSON_END_OF_INPUT: + /* + * Force the parentheses to appear balanced and the queue + * to be emptied, causing a parse error if it wasn't. + */ if (g_queue_is_empty(&parser->tokens)) { return; } + end_error_recovery: + /* + * We come here due to receiving either JSON_ERROR or a + * JSON_R{CURLY,SQUARE}) that is known to be unbalanced. + * If in error recovery, end it immediately. If not in + * error recovery, json_parser_feed() will raise an error + * but error recovery won't be entered at all. + */ + parser->brace_count = 0; + parser->bracket_count = 0; break; default: break; @@ -83,9 +103,7 @@ void json_message_process_token(JSONLexer *lexer, GString *input, g_queue_push_tail(&parser->tokens, token); - if ((parser->brace_count > 0 || parser->bracket_count > 0) - && parser->brace_count >= 0 && parser->bracket_count >= 0 - && type != JSON_END_OF_INPUT) { + if (parser->brace_count > 0 || parser->bracket_count > 0) { return; } |
