LCOV - code coverage report
Current view: top level - core/json - json_reader.c (source / functions) Hit Total Coverage
Test: tmp.CaZ6RjdVn2 Lines: 299 317 94.3 %
Date: 2015-12-10 22:15:08 Functions: 15 15 100.0 %

          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             : }

Generated by: LCOV version 1.11