Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : #include <string.h>
35 :
36 : #include <grpc/support/port_platform.h>
37 :
38 : #include "src/core/json/json_reader.h"
39 :
40 1949 : static void json_reader_string_clear(grpc_json_reader *reader) {
41 1949 : reader->vtable->string_clear(reader->userdata);
42 1949 : }
43 :
44 38992 : static void json_reader_string_add_char(grpc_json_reader *reader,
45 : gpr_uint32 c) {
46 38992 : reader->vtable->string_add_char(reader->userdata, c);
47 38992 : }
48 :
49 27 : static void json_reader_string_add_utf32(grpc_json_reader *reader,
50 : gpr_uint32 utf32) {
51 27 : reader->vtable->string_add_utf32(reader->userdata, utf32);
52 27 : }
53 :
54 77057 : static gpr_uint32 grpc_json_reader_read_char(grpc_json_reader *reader) {
55 77057 : return reader->vtable->read_char(reader->userdata);
56 : }
57 :
58 334 : static void json_reader_container_begins(grpc_json_reader *reader,
59 : grpc_json_type type) {
60 334 : reader->vtable->container_begins(reader->userdata, type);
61 334 : }
62 :
63 324 : static grpc_json_type grpc_json_reader_container_ends(
64 : grpc_json_reader *reader) {
65 324 : return reader->vtable->container_ends(reader->userdata);
66 : }
67 :
68 971 : static void json_reader_set_key(grpc_json_reader *reader) {
69 971 : reader->vtable->set_key(reader->userdata);
70 971 : }
71 :
72 720 : static void json_reader_set_string(grpc_json_reader *reader) {
73 720 : reader->vtable->set_string(reader->userdata);
74 720 : }
75 :
76 142 : static int json_reader_set_number(grpc_json_reader *reader) {
77 142 : return reader->vtable->set_number(reader->userdata);
78 : }
79 :
80 10 : static void json_reader_set_true(grpc_json_reader *reader) {
81 10 : reader->vtable->set_true(reader->userdata);
82 10 : }
83 :
84 5 : static void json_reader_set_false(grpc_json_reader *reader) {
85 5 : reader->vtable->set_false(reader->userdata);
86 5 : }
87 :
88 17 : static void json_reader_set_null(grpc_json_reader *reader) {
89 17 : reader->vtable->set_null(reader->userdata);
90 17 : }
91 :
92 : /* Call this function to initialize the reader structure. */
93 116 : void grpc_json_reader_init(grpc_json_reader *reader,
94 : grpc_json_reader_vtable *vtable, void *userdata) {
95 116 : memset(reader, 0, sizeof(*reader));
96 116 : reader->vtable = vtable;
97 116 : reader->userdata = userdata;
98 116 : json_reader_string_clear(reader);
99 116 : reader->state = GRPC_JSON_STATE_VALUE_BEGIN;
100 116 : }
101 :
102 89 : int grpc_json_reader_is_complete(grpc_json_reader *reader) {
103 255 : return ((reader->depth == 0) &&
104 103 : ((reader->state == GRPC_JSON_STATE_END) ||
105 17 : (reader->state == GRPC_JSON_STATE_VALUE_END)));
106 : }
107 :
108 77057 : grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) {
109 : gpr_uint32 c, success;
110 :
111 : /* This state-machine is a strict implementation of ECMA-404 */
112 : for (;;) {
113 77057 : c = grpc_json_reader_read_char(reader);
114 77057 : switch (c) {
115 : /* Let's process the error cases first. */
116 : case GRPC_JSON_READ_CHAR_ERROR:
117 0 : return GRPC_JSON_READ_ERROR;
118 :
119 : case GRPC_JSON_READ_CHAR_EAGAIN:
120 24717 : return GRPC_JSON_EAGAIN;
121 :
122 : case GRPC_JSON_READ_CHAR_EOF:
123 89 : if (grpc_json_reader_is_complete(reader)) {
124 80 : return GRPC_JSON_DONE;
125 : } else {
126 9 : return GRPC_JSON_PARSE_ERROR;
127 : }
128 : break;
129 :
130 : /* Processing whitespaces. */
131 : case ' ':
132 : case '\t':
133 : case '\n':
134 : case '\r':
135 7062 : switch (reader->state) {
136 : case GRPC_JSON_STATE_OBJECT_KEY_BEGIN:
137 : case GRPC_JSON_STATE_OBJECT_KEY_END:
138 : case GRPC_JSON_STATE_VALUE_BEGIN:
139 : case GRPC_JSON_STATE_VALUE_END:
140 : case GRPC_JSON_STATE_END:
141 6722 : break;
142 :
143 : case GRPC_JSON_STATE_OBJECT_KEY_STRING:
144 : case GRPC_JSON_STATE_VALUE_STRING:
145 331 : if (c != ' ') return GRPC_JSON_PARSE_ERROR;
146 329 : if (reader->unicode_high_surrogate != 0)
147 0 : return GRPC_JSON_PARSE_ERROR;
148 329 : json_reader_string_add_char(reader, c);
149 329 : break;
150 :
151 : case GRPC_JSON_STATE_VALUE_NUMBER:
152 : case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
153 : case GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
154 : case GRPC_JSON_STATE_VALUE_NUMBER_EPM:
155 8 : success = (gpr_uint32)json_reader_set_number(reader);
156 8 : if (!success) return GRPC_JSON_PARSE_ERROR;
157 8 : json_reader_string_clear(reader);
158 8 : reader->state = GRPC_JSON_STATE_VALUE_END;
159 8 : break;
160 :
161 : default:
162 1 : return GRPC_JSON_PARSE_ERROR;
163 : }
164 7059 : break;
165 :
166 : /* Value, object or array terminations. */
167 : case ',':
168 : case '}':
169 : case ']':
170 1173 : switch (reader->state) {
171 : case GRPC_JSON_STATE_OBJECT_KEY_STRING:
172 : case GRPC_JSON_STATE_VALUE_STRING:
173 13 : if (reader->unicode_high_surrogate != 0)
174 0 : return GRPC_JSON_PARSE_ERROR;
175 13 : json_reader_string_add_char(reader, c);
176 13 : break;
177 :
178 : case GRPC_JSON_STATE_VALUE_NUMBER:
179 : case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
180 : case GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
181 : case GRPC_JSON_STATE_VALUE_NUMBER_EPM:
182 134 : success = (gpr_uint32)json_reader_set_number(reader);
183 134 : if (!success) return GRPC_JSON_PARSE_ERROR;
184 134 : json_reader_string_clear(reader);
185 134 : reader->state = GRPC_JSON_STATE_VALUE_END;
186 : /* The missing break here is intentional. */
187 :
188 : case GRPC_JSON_STATE_VALUE_END:
189 : case GRPC_JSON_STATE_OBJECT_KEY_BEGIN:
190 : case GRPC_JSON_STATE_VALUE_BEGIN:
191 1157 : if (c == ',') {
192 829 : if (reader->state != GRPC_JSON_STATE_VALUE_END) {
193 1 : return GRPC_JSON_PARSE_ERROR;
194 : }
195 828 : if (reader->in_object) {
196 694 : reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN;
197 : } else {
198 134 : reader->state = GRPC_JSON_STATE_VALUE_BEGIN;
199 : }
200 : } else {
201 328 : if (reader->depth-- == 0) return GRPC_JSON_PARSE_ERROR;
202 328 : if ((c == '}') && !reader->in_object) {
203 1 : return GRPC_JSON_PARSE_ERROR;
204 : }
205 614 : if ((c == '}') &&
206 299 : (reader->state == GRPC_JSON_STATE_OBJECT_KEY_BEGIN) &&
207 12 : !reader->container_just_begun) {
208 1 : return GRPC_JSON_PARSE_ERROR;
209 : }
210 326 : if ((c == ']') && !reader->in_array) return GRPC_JSON_PARSE_ERROR;
211 364 : if ((c == ']') &&
212 50 : (reader->state == GRPC_JSON_STATE_VALUE_BEGIN) &&
213 11 : !reader->container_just_begun) {
214 1 : return GRPC_JSON_PARSE_ERROR;
215 : }
216 324 : reader->state = GRPC_JSON_STATE_VALUE_END;
217 324 : switch (grpc_json_reader_container_ends(reader)) {
218 : case GRPC_JSON_OBJECT:
219 127 : reader->in_object = 1;
220 127 : reader->in_array = 0;
221 127 : break;
222 : case GRPC_JSON_ARRAY:
223 125 : reader->in_object = 0;
224 125 : reader->in_array = 1;
225 125 : break;
226 : case GRPC_JSON_TOP_LEVEL:
227 72 : if (reader->depth != 0) return GRPC_JSON_INTERNAL_ERROR;
228 72 : reader->in_object = 0;
229 72 : reader->in_array = 0;
230 72 : reader->state = GRPC_JSON_STATE_END;
231 72 : break;
232 : default:
233 0 : return GRPC_JSON_INTERNAL_ERROR;
234 : }
235 : }
236 1152 : break;
237 :
238 : default:
239 3 : return GRPC_JSON_PARSE_ERROR;
240 : }
241 1165 : break;
242 :
243 : /* In-string escaping. */
244 : case '\\':
245 335 : switch (reader->state) {
246 : case GRPC_JSON_STATE_OBJECT_KEY_STRING:
247 6 : reader->escaped_string_was_key = 1;
248 6 : reader->state = GRPC_JSON_STATE_STRING_ESCAPE;
249 6 : break;
250 :
251 : case GRPC_JSON_STATE_VALUE_STRING:
252 326 : reader->escaped_string_was_key = 0;
253 326 : reader->state = GRPC_JSON_STATE_STRING_ESCAPE;
254 326 : break;
255 :
256 : /* This is the \\ case. */
257 : case GRPC_JSON_STATE_STRING_ESCAPE:
258 2 : if (reader->unicode_high_surrogate != 0)
259 0 : return GRPC_JSON_PARSE_ERROR;
260 2 : json_reader_string_add_char(reader, '\\');
261 2 : if (reader->escaped_string_was_key) {
262 1 : reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
263 : } else {
264 1 : reader->state = GRPC_JSON_STATE_VALUE_STRING;
265 : }
266 2 : break;
267 :
268 : default:
269 1 : return GRPC_JSON_PARSE_ERROR;
270 : }
271 334 : break;
272 :
273 : default:
274 43681 : reader->container_just_begun = 0;
275 43681 : switch (reader->state) {
276 : case GRPC_JSON_STATE_OBJECT_KEY_BEGIN:
277 972 : if (c != '"') return GRPC_JSON_PARSE_ERROR;
278 971 : reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
279 971 : break;
280 :
281 : case GRPC_JSON_STATE_OBJECT_KEY_STRING:
282 9972 : if (reader->unicode_high_surrogate != 0)
283 0 : return GRPC_JSON_PARSE_ERROR;
284 9972 : if (c == '"') {
285 971 : reader->state = GRPC_JSON_STATE_OBJECT_KEY_END;
286 971 : json_reader_set_key(reader);
287 971 : json_reader_string_clear(reader);
288 : } else {
289 9001 : if (c <= 0x001f) return GRPC_JSON_PARSE_ERROR;
290 9001 : json_reader_string_add_char(reader, c);
291 : }
292 9972 : break;
293 :
294 : case GRPC_JSON_STATE_VALUE_STRING:
295 29570 : if (reader->unicode_high_surrogate != 0)
296 1 : return GRPC_JSON_PARSE_ERROR;
297 29569 : if (c == '"') {
298 720 : reader->state = GRPC_JSON_STATE_VALUE_END;
299 720 : json_reader_set_string(reader);
300 720 : json_reader_string_clear(reader);
301 : } else {
302 28849 : if (c < 32) return GRPC_JSON_PARSE_ERROR;
303 28849 : json_reader_string_add_char(reader, c);
304 : }
305 29569 : break;
306 :
307 : case GRPC_JSON_STATE_OBJECT_KEY_END:
308 971 : if (c != ':') return GRPC_JSON_PARSE_ERROR;
309 971 : reader->state = GRPC_JSON_STATE_VALUE_BEGIN;
310 971 : break;
311 :
312 : case GRPC_JSON_STATE_VALUE_BEGIN:
313 1250 : switch (c) {
314 : case 't':
315 10 : reader->state = GRPC_JSON_STATE_VALUE_TRUE_R;
316 10 : break;
317 :
318 : case 'f':
319 6 : reader->state = GRPC_JSON_STATE_VALUE_FALSE_A;
320 6 : break;
321 :
322 : case 'n':
323 18 : reader->state = GRPC_JSON_STATE_VALUE_NULL_U;
324 18 : break;
325 :
326 : case '"':
327 729 : reader->state = GRPC_JSON_STATE_VALUE_STRING;
328 729 : break;
329 :
330 : case '0':
331 6 : json_reader_string_add_char(reader, c);
332 6 : reader->state = GRPC_JSON_STATE_VALUE_NUMBER_ZERO;
333 6 : break;
334 :
335 : case '1':
336 : case '2':
337 : case '3':
338 : case '4':
339 : case '5':
340 : case '6':
341 : case '7':
342 : case '8':
343 : case '9':
344 : case '-':
345 145 : json_reader_string_add_char(reader, c);
346 145 : reader->state = GRPC_JSON_STATE_VALUE_NUMBER;
347 145 : break;
348 :
349 : case '{':
350 292 : reader->container_just_begun = 1;
351 292 : json_reader_container_begins(reader, GRPC_JSON_OBJECT);
352 292 : reader->depth++;
353 292 : reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN;
354 292 : reader->in_object = 1;
355 292 : reader->in_array = 0;
356 292 : break;
357 :
358 : case '[':
359 42 : reader->container_just_begun = 1;
360 42 : json_reader_container_begins(reader, GRPC_JSON_ARRAY);
361 42 : reader->depth++;
362 42 : reader->in_object = 0;
363 42 : reader->in_array = 1;
364 42 : break;
365 : }
366 1250 : break;
367 :
368 : case GRPC_JSON_STATE_STRING_ESCAPE:
369 330 : if (reader->escaped_string_was_key) {
370 5 : reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
371 : } else {
372 325 : reader->state = GRPC_JSON_STATE_VALUE_STRING;
373 : }
374 330 : if (reader->unicode_high_surrogate && c != 'u')
375 1 : return GRPC_JSON_PARSE_ERROR;
376 329 : switch (c) {
377 : case '"':
378 : case '/':
379 0 : json_reader_string_add_char(reader, c);
380 0 : break;
381 : case 'b':
382 0 : json_reader_string_add_char(reader, '\b');
383 0 : break;
384 : case 'f':
385 0 : json_reader_string_add_char(reader, '\f');
386 0 : break;
387 : case 'n':
388 286 : json_reader_string_add_char(reader, '\n');
389 286 : break;
390 : case 'r':
391 0 : json_reader_string_add_char(reader, '\r');
392 0 : break;
393 : case 't':
394 4 : json_reader_string_add_char(reader, '\t');
395 4 : break;
396 : case 'u':
397 38 : reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U1;
398 38 : reader->unicode_char = 0;
399 38 : break;
400 : default:
401 1 : return GRPC_JSON_PARSE_ERROR;
402 : }
403 328 : break;
404 :
405 : case GRPC_JSON_STATE_STRING_ESCAPE_U1:
406 : case GRPC_JSON_STATE_STRING_ESCAPE_U2:
407 : case GRPC_JSON_STATE_STRING_ESCAPE_U3:
408 : case GRPC_JSON_STATE_STRING_ESCAPE_U4:
409 152 : if ((c >= '0') && (c <= '9')) {
410 104 : c -= '0';
411 48 : } else if ((c >= 'A') && (c <= 'F')) {
412 1 : c -= 'A' - 10;
413 47 : } else if ((c >= 'a') && (c <= 'f')) {
414 46 : c -= 'a' - 10;
415 : } else {
416 1 : return GRPC_JSON_PARSE_ERROR;
417 : }
418 151 : reader->unicode_char = (gpr_uint16)(reader->unicode_char << 4);
419 151 : reader->unicode_char = (gpr_uint16)(reader->unicode_char | c);
420 :
421 151 : switch (reader->state) {
422 : case GRPC_JSON_STATE_STRING_ESCAPE_U1:
423 38 : reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U2;
424 38 : break;
425 : case GRPC_JSON_STATE_STRING_ESCAPE_U2:
426 38 : reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U3;
427 38 : break;
428 : case GRPC_JSON_STATE_STRING_ESCAPE_U3:
429 38 : reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U4;
430 38 : break;
431 : case GRPC_JSON_STATE_STRING_ESCAPE_U4:
432 : /* See grpc_json_writer_escape_string to have a description
433 : * of what's going on here.
434 : */
435 37 : if ((reader->unicode_char & 0xfc00) == 0xd800) {
436 : /* high surrogate utf-16 */
437 8 : if (reader->unicode_high_surrogate != 0)
438 1 : return GRPC_JSON_PARSE_ERROR;
439 7 : reader->unicode_high_surrogate = reader->unicode_char;
440 29 : } else if ((reader->unicode_char & 0xfc00) == 0xdc00) {
441 : /* low surrogate utf-16 */
442 : gpr_uint32 utf32;
443 4 : if (reader->unicode_high_surrogate == 0)
444 1 : return GRPC_JSON_PARSE_ERROR;
445 3 : utf32 = 0x10000;
446 3 : utf32 += (gpr_uint32)(
447 3 : (reader->unicode_high_surrogate - 0xd800) * 0x400);
448 3 : utf32 += (gpr_uint32)(reader->unicode_char - 0xdc00);
449 3 : json_reader_string_add_utf32(reader, utf32);
450 3 : reader->unicode_high_surrogate = 0;
451 : } else {
452 : /* anything else */
453 25 : if (reader->unicode_high_surrogate != 0)
454 1 : return GRPC_JSON_PARSE_ERROR;
455 24 : json_reader_string_add_utf32(reader, reader->unicode_char);
456 : }
457 34 : if (reader->escaped_string_was_key) {
458 0 : reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
459 : } else {
460 34 : reader->state = GRPC_JSON_STATE_VALUE_STRING;
461 : }
462 34 : break;
463 : default:
464 0 : return GRPC_JSON_INTERNAL_ERROR;
465 : }
466 148 : break;
467 :
468 : case GRPC_JSON_STATE_VALUE_NUMBER:
469 328 : json_reader_string_add_char(reader, c);
470 328 : switch (c) {
471 : case '0':
472 : case '1':
473 : case '2':
474 : case '3':
475 : case '4':
476 : case '5':
477 : case '6':
478 : case '7':
479 : case '8':
480 : case '9':
481 318 : break;
482 : case 'e':
483 : case 'E':
484 4 : reader->state = GRPC_JSON_STATE_VALUE_NUMBER_E;
485 4 : break;
486 : case '.':
487 5 : reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT;
488 5 : break;
489 : default:
490 1 : return GRPC_JSON_PARSE_ERROR;
491 : }
492 327 : break;
493 :
494 : case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
495 11 : json_reader_string_add_char(reader, c);
496 11 : switch (c) {
497 : case '0':
498 : case '1':
499 : case '2':
500 : case '3':
501 : case '4':
502 : case '5':
503 : case '6':
504 : case '7':
505 : case '8':
506 : case '9':
507 8 : break;
508 : case 'e':
509 : case 'E':
510 2 : reader->state = GRPC_JSON_STATE_VALUE_NUMBER_E;
511 2 : break;
512 : default:
513 1 : return GRPC_JSON_PARSE_ERROR;
514 : }
515 10 : break;
516 :
517 : case GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
518 3 : if (c != '.') return GRPC_JSON_PARSE_ERROR;
519 2 : json_reader_string_add_char(reader, c);
520 2 : reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT;
521 2 : break;
522 :
523 : case GRPC_JSON_STATE_VALUE_NUMBER_DOT:
524 6 : json_reader_string_add_char(reader, c);
525 6 : switch (c) {
526 : case '0':
527 : case '1':
528 : case '2':
529 : case '3':
530 : case '4':
531 : case '5':
532 : case '6':
533 : case '7':
534 : case '8':
535 : case '9':
536 5 : reader->state = GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL;
537 5 : break;
538 : default:
539 1 : return GRPC_JSON_PARSE_ERROR;
540 : }
541 5 : break;
542 :
543 : case GRPC_JSON_STATE_VALUE_NUMBER_E:
544 5 : json_reader_string_add_char(reader, c);
545 5 : switch (c) {
546 : case '0':
547 : case '1':
548 : case '2':
549 : case '3':
550 : case '4':
551 : case '5':
552 : case '6':
553 : case '7':
554 : case '8':
555 : case '9':
556 : case '+':
557 : case '-':
558 4 : reader->state = GRPC_JSON_STATE_VALUE_NUMBER_EPM;
559 4 : break;
560 : default:
561 1 : return GRPC_JSON_PARSE_ERROR;
562 : }
563 4 : break;
564 :
565 : case GRPC_JSON_STATE_VALUE_NUMBER_EPM:
566 5 : json_reader_string_add_char(reader, c);
567 5 : switch (c) {
568 : case '0':
569 : case '1':
570 : case '2':
571 : case '3':
572 : case '4':
573 : case '5':
574 : case '6':
575 : case '7':
576 : case '8':
577 : case '9':
578 4 : break;
579 : default:
580 1 : return GRPC_JSON_PARSE_ERROR;
581 : }
582 4 : break;
583 :
584 : case GRPC_JSON_STATE_VALUE_TRUE_R:
585 10 : if (c != 'r') return GRPC_JSON_PARSE_ERROR;
586 10 : reader->state = GRPC_JSON_STATE_VALUE_TRUE_U;
587 10 : break;
588 :
589 : case GRPC_JSON_STATE_VALUE_TRUE_U:
590 10 : if (c != 'u') return GRPC_JSON_PARSE_ERROR;
591 10 : reader->state = GRPC_JSON_STATE_VALUE_TRUE_E;
592 10 : break;
593 :
594 : case GRPC_JSON_STATE_VALUE_TRUE_E:
595 10 : if (c != 'e') return GRPC_JSON_PARSE_ERROR;
596 10 : json_reader_set_true(reader);
597 10 : reader->state = GRPC_JSON_STATE_VALUE_END;
598 10 : break;
599 :
600 : case GRPC_JSON_STATE_VALUE_FALSE_A:
601 6 : if (c != 'a') return GRPC_JSON_PARSE_ERROR;
602 6 : reader->state = GRPC_JSON_STATE_VALUE_FALSE_L;
603 6 : break;
604 :
605 : case GRPC_JSON_STATE_VALUE_FALSE_L:
606 6 : if (c != 'l') return GRPC_JSON_PARSE_ERROR;
607 6 : reader->state = GRPC_JSON_STATE_VALUE_FALSE_S;
608 6 : break;
609 :
610 : case GRPC_JSON_STATE_VALUE_FALSE_S:
611 6 : if (c != 's') return GRPC_JSON_PARSE_ERROR;
612 6 : reader->state = GRPC_JSON_STATE_VALUE_FALSE_E;
613 6 : break;
614 :
615 : case GRPC_JSON_STATE_VALUE_FALSE_E:
616 5 : if (c != 'e') return GRPC_JSON_PARSE_ERROR;
617 5 : json_reader_set_false(reader);
618 5 : reader->state = GRPC_JSON_STATE_VALUE_END;
619 5 : break;
620 :
621 : case GRPC_JSON_STATE_VALUE_NULL_U:
622 18 : if (c != 'u') return GRPC_JSON_PARSE_ERROR;
623 18 : reader->state = GRPC_JSON_STATE_VALUE_NULL_L1;
624 18 : break;
625 :
626 : case GRPC_JSON_STATE_VALUE_NULL_L1:
627 17 : if (c != 'l') return GRPC_JSON_PARSE_ERROR;
628 17 : reader->state = GRPC_JSON_STATE_VALUE_NULL_L2;
629 17 : break;
630 :
631 : case GRPC_JSON_STATE_VALUE_NULL_L2:
632 17 : if (c != 'l') return GRPC_JSON_PARSE_ERROR;
633 17 : json_reader_set_null(reader);
634 17 : reader->state = GRPC_JSON_STATE_VALUE_END;
635 17 : break;
636 :
637 : /* All of the VALUE_END cases are handled in the specialized case
638 : * above. */
639 : case GRPC_JSON_STATE_VALUE_END:
640 1 : switch (c) {
641 : case ',':
642 : case '}':
643 : case ']':
644 0 : return GRPC_JSON_INTERNAL_ERROR;
645 : break;
646 :
647 : default:
648 1 : return GRPC_JSON_PARSE_ERROR;
649 : }
650 : break;
651 :
652 : case GRPC_JSON_STATE_END:
653 0 : return GRPC_JSON_PARSE_ERROR;
654 : }
655 : }
656 52224 : }
657 :
658 : return GRPC_JSON_INTERNAL_ERROR;
659 : }
|