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