1
/*
2
- * JSON streaming support
2
+ * JSON parser - callback interface and error recovery
3
*
4
* Copyright IBM, Corp. 2009
5
*
19
#define MAX_TOKEN_COUNT (2ULL << 20)
20
#define MAX_NESTING (1 << 10)
21
22
-static void json_message_free_tokens(JSONMessageParser *parser)
23
-{
24
- JSONToken *token;
25
-
26
- while ((token = g_queue_pop_head(&parser->tokens))) {
27
- g_free(token);
28
- }
29
-}
30
-
22
void json_message_process_token(JSONLexer *lexer, GString *input,
23
JSONTokenType type, int x, int y)
24
{
25
JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
35
- QObject *json = NULL;
26
Error *err = NULL;
37
- JSONToken *token;
27
28
+ parser->token_size += input->len;
29
+ parser->token_count++;
30
+
31
+ /* Detect message boundaries for error recovery purposes. */
32
switch (type) {
33
case JSON_LCURLY:
34
parser->brace_count++;
49
parser->bracket_count--;
50
break;
51
case JSON_ERROR:
59
- error_setg(&err, "JSON parse error, stray '%s'", input->str);
60
- goto out_emit;
61
- case JSON_END_OF_INPUT:
62
- /*
63
- * Force the parentheses to appear balanced and the queue
64
- * to be emptied, causing a parse error if it wasn't.
65
- */
66
- if (g_queue_is_empty(&parser->tokens)) {
67
- return;
68
- }
52
end_error_recovery:
53
/*
54
* We come here due to receiving either JSON_ERROR or a
64
break;
65
}
66
84
- /*
85
- * Security consideration, we limit total memory allocated per object
86
- * and the maximum recursion depth that a message can force.
87
- */
88
- if (parser->token_size + input->len + 1 > MAX_TOKEN_SIZE) {
89
- error_setg(&err, "JSON token size limit exceeded");
90
- goto out_emit;
91
- }
92
- if (g_queue_get_length(&parser->tokens) + 1 > MAX_TOKEN_COUNT) {
93
- error_setg(&err, "JSON token count limit exceeded");
94
- goto out_emit;
95
- }
96
- if (parser->bracket_count + parser->brace_count > MAX_NESTING) {
97
- error_setg(&err, "JSON nesting depth limit exceeded");
98
- goto out_emit;
99
- }
100
-
101
- token = json_token(type, x, y, input);
102
- parser->token_size += input->len;
103
-
104
- g_queue_push_tail(&parser->tokens, token);
105
-
106
- if (parser->brace_count > 0 || parser->bracket_count > 0) {
107
- return;
108
- }
67
+ if (parser->error) {
68
+ /* error recovery, eat tokens until parentheses balance */
69
+ } else {
70
+ /*
71
+ * Safety consideration, we limit total memory allocated per object
72
+ * and the maximum nesting depth that a message can force.
73
+ */
74
+ if (parser->token_size >= MAX_TOKEN_SIZE) {
75
+ error_setg(&err, "JSON token size limit exceeded");
76
+ } else if (parser->token_count > MAX_TOKEN_COUNT) {
77
+ error_setg(&err, "JSON token count limit exceeded");
78
+ } else if (parser->bracket_count + parser->brace_count > MAX_NESTING) {
79
+ error_setg(&err, "JSON nesting depth limit exceeded");
80
+ } else {
81
+ g_autofree JSONToken *token = json_token(type, x, y, input);
82
+ QObject *json = json_parser_feed(&parser->parser, token, &err);
83
+ if (json) {
84
+ parser->emit(parser->opaque, json, NULL);
85
+ }
86
+ }
87
110
- /* Process all tokens in the queue */
111
- while (!g_queue_is_empty(&parser->tokens)) {
112
- token = g_queue_pop_head(&parser->tokens);
113
- json = json_parser_feed(&parser->parser, token, &err);
114
- g_free(token);
115
- if (json || err) {
116
- break;
88
+ if (err) {
89
+ parser->emit(parser->opaque, NULL, err);
90
+ /* start recovery */
91
+ parser->error = true;
92
}
93
}
94
120
-out_emit:
121
- json_parser_reset(&parser->parser);
122
- parser->brace_count = 0;
123
- parser->bracket_count = 0;
124
- json_message_free_tokens(parser);
125
- parser->token_size = 0;
126
- parser->emit(parser->opaque, json, err);
95
+ if ((parser->brace_count == 0 && parser->bracket_count == 0)
96
+ || type == JSON_END_OF_INPUT) {
97
+ json_parser_reset(&parser->parser);
98
+ parser->error = false;
99
+ parser->brace_count = 0;
100
+ parser->bracket_count = 0;
101
+ parser->token_count = 0;
102
+ parser->token_size = 0;
103
+ }
104
}
105
106
void json_message_parser_init(JSONMessageParser *parser,
110
{
111
parser->emit = emit;
112
parser->opaque = opaque;
113
+ parser->error = false;
114
parser->brace_count = 0;
115
parser->bracket_count = 0;
138
- g_queue_init(&parser->tokens);
116
+ parser->token_count = 0;
117
parser->token_size = 0;
118
119
json_parser_init(&parser->parser, ap);
129
void json_message_parser_flush(JSONMessageParser *parser)
130
{
131
json_lexer_flush(&parser->lexer);
154
- assert(g_queue_is_empty(&parser->tokens));
132
}
133
134
void json_message_parser_destroy(JSONMessageParser *parser)
135
{
136
json_lexer_destroy(&parser->lexer);
160
- json_message_free_tokens(parser);
137
json_parser_destroy(&parser->parser);
138
}