OLD | NEW |
(Empty) | |
| 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 <grpc/support/log.h> |
| 39 |
| 40 #include "src/core/json/json_reader.h" |
| 41 |
| 42 static void json_reader_string_clear(grpc_json_reader *reader) { |
| 43 reader->vtable->string_clear(reader->userdata); |
| 44 } |
| 45 |
| 46 static void json_reader_string_add_char(grpc_json_reader *reader, uint32_t c) { |
| 47 reader->vtable->string_add_char(reader->userdata, c); |
| 48 } |
| 49 |
| 50 static void json_reader_string_add_utf32(grpc_json_reader *reader, |
| 51 uint32_t utf32) { |
| 52 reader->vtable->string_add_utf32(reader->userdata, utf32); |
| 53 } |
| 54 |
| 55 static uint32_t grpc_json_reader_read_char(grpc_json_reader *reader) { |
| 56 return reader->vtable->read_char(reader->userdata); |
| 57 } |
| 58 |
| 59 static void json_reader_container_begins(grpc_json_reader *reader, |
| 60 grpc_json_type type) { |
| 61 reader->vtable->container_begins(reader->userdata, type); |
| 62 } |
| 63 |
| 64 static grpc_json_type grpc_json_reader_container_ends( |
| 65 grpc_json_reader *reader) { |
| 66 return reader->vtable->container_ends(reader->userdata); |
| 67 } |
| 68 |
| 69 static void json_reader_set_key(grpc_json_reader *reader) { |
| 70 reader->vtable->set_key(reader->userdata); |
| 71 } |
| 72 |
| 73 static void json_reader_set_string(grpc_json_reader *reader) { |
| 74 reader->vtable->set_string(reader->userdata); |
| 75 } |
| 76 |
| 77 static int json_reader_set_number(grpc_json_reader *reader) { |
| 78 return reader->vtable->set_number(reader->userdata); |
| 79 } |
| 80 |
| 81 static void json_reader_set_true(grpc_json_reader *reader) { |
| 82 reader->vtable->set_true(reader->userdata); |
| 83 } |
| 84 |
| 85 static void json_reader_set_false(grpc_json_reader *reader) { |
| 86 reader->vtable->set_false(reader->userdata); |
| 87 } |
| 88 |
| 89 static void json_reader_set_null(grpc_json_reader *reader) { |
| 90 reader->vtable->set_null(reader->userdata); |
| 91 } |
| 92 |
| 93 /* Call this function to initialize the reader structure. */ |
| 94 void grpc_json_reader_init(grpc_json_reader *reader, |
| 95 grpc_json_reader_vtable *vtable, void *userdata) { |
| 96 memset(reader, 0, sizeof(*reader)); |
| 97 reader->vtable = vtable; |
| 98 reader->userdata = userdata; |
| 99 json_reader_string_clear(reader); |
| 100 reader->state = GRPC_JSON_STATE_VALUE_BEGIN; |
| 101 } |
| 102 |
| 103 int grpc_json_reader_is_complete(grpc_json_reader *reader) { |
| 104 return ((reader->depth == 0) && |
| 105 ((reader->state == GRPC_JSON_STATE_END) || |
| 106 (reader->state == GRPC_JSON_STATE_VALUE_END))); |
| 107 } |
| 108 |
| 109 grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) { |
| 110 uint32_t c, success; |
| 111 |
| 112 /* This state-machine is a strict implementation of ECMA-404 */ |
| 113 for (;;) { |
| 114 c = grpc_json_reader_read_char(reader); |
| 115 switch (c) { |
| 116 /* Let's process the error cases first. */ |
| 117 case GRPC_JSON_READ_CHAR_ERROR: |
| 118 return GRPC_JSON_READ_ERROR; |
| 119 |
| 120 case GRPC_JSON_READ_CHAR_EAGAIN: |
| 121 return GRPC_JSON_EAGAIN; |
| 122 |
| 123 case GRPC_JSON_READ_CHAR_EOF: |
| 124 if (grpc_json_reader_is_complete(reader)) { |
| 125 return GRPC_JSON_DONE; |
| 126 } else { |
| 127 return GRPC_JSON_PARSE_ERROR; |
| 128 } |
| 129 break; |
| 130 |
| 131 /* Processing whitespaces. */ |
| 132 case ' ': |
| 133 case '\t': |
| 134 case '\n': |
| 135 case '\r': |
| 136 switch (reader->state) { |
| 137 case GRPC_JSON_STATE_OBJECT_KEY_BEGIN: |
| 138 case GRPC_JSON_STATE_OBJECT_KEY_END: |
| 139 case GRPC_JSON_STATE_VALUE_BEGIN: |
| 140 case GRPC_JSON_STATE_VALUE_END: |
| 141 case GRPC_JSON_STATE_END: |
| 142 break; |
| 143 |
| 144 case GRPC_JSON_STATE_OBJECT_KEY_STRING: |
| 145 case GRPC_JSON_STATE_VALUE_STRING: |
| 146 if (c != ' ') return GRPC_JSON_PARSE_ERROR; |
| 147 if (reader->unicode_high_surrogate != 0) |
| 148 return GRPC_JSON_PARSE_ERROR; |
| 149 json_reader_string_add_char(reader, c); |
| 150 break; |
| 151 |
| 152 case GRPC_JSON_STATE_VALUE_NUMBER: |
| 153 case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL: |
| 154 case GRPC_JSON_STATE_VALUE_NUMBER_ZERO: |
| 155 case GRPC_JSON_STATE_VALUE_NUMBER_EPM: |
| 156 success = (uint32_t)json_reader_set_number(reader); |
| 157 if (!success) return GRPC_JSON_PARSE_ERROR; |
| 158 json_reader_string_clear(reader); |
| 159 reader->state = GRPC_JSON_STATE_VALUE_END; |
| 160 break; |
| 161 |
| 162 default: |
| 163 return GRPC_JSON_PARSE_ERROR; |
| 164 } |
| 165 break; |
| 166 |
| 167 /* Value, object or array terminations. */ |
| 168 case ',': |
| 169 case '}': |
| 170 case ']': |
| 171 switch (reader->state) { |
| 172 case GRPC_JSON_STATE_OBJECT_KEY_STRING: |
| 173 case GRPC_JSON_STATE_VALUE_STRING: |
| 174 if (reader->unicode_high_surrogate != 0) |
| 175 return GRPC_JSON_PARSE_ERROR; |
| 176 json_reader_string_add_char(reader, c); |
| 177 break; |
| 178 |
| 179 case GRPC_JSON_STATE_VALUE_NUMBER: |
| 180 case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL: |
| 181 case GRPC_JSON_STATE_VALUE_NUMBER_ZERO: |
| 182 case GRPC_JSON_STATE_VALUE_NUMBER_EPM: |
| 183 success = (uint32_t)json_reader_set_number(reader); |
| 184 if (!success) return GRPC_JSON_PARSE_ERROR; |
| 185 json_reader_string_clear(reader); |
| 186 reader->state = GRPC_JSON_STATE_VALUE_END; |
| 187 /* The missing break here is intentional. */ |
| 188 |
| 189 case GRPC_JSON_STATE_VALUE_END: |
| 190 case GRPC_JSON_STATE_OBJECT_KEY_BEGIN: |
| 191 case GRPC_JSON_STATE_VALUE_BEGIN: |
| 192 if (c == ',') { |
| 193 if (reader->state != GRPC_JSON_STATE_VALUE_END) { |
| 194 return GRPC_JSON_PARSE_ERROR; |
| 195 } |
| 196 if (reader->in_object) { |
| 197 reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN; |
| 198 } else { |
| 199 reader->state = GRPC_JSON_STATE_VALUE_BEGIN; |
| 200 } |
| 201 } else { |
| 202 if (reader->depth-- == 0) return GRPC_JSON_PARSE_ERROR; |
| 203 if ((c == '}') && !reader->in_object) { |
| 204 return GRPC_JSON_PARSE_ERROR; |
| 205 } |
| 206 if ((c == '}') && |
| 207 (reader->state == GRPC_JSON_STATE_OBJECT_KEY_BEGIN) && |
| 208 !reader->container_just_begun) { |
| 209 return GRPC_JSON_PARSE_ERROR; |
| 210 } |
| 211 if ((c == ']') && !reader->in_array) return GRPC_JSON_PARSE_ERROR; |
| 212 if ((c == ']') && |
| 213 (reader->state == GRPC_JSON_STATE_VALUE_BEGIN) && |
| 214 !reader->container_just_begun) { |
| 215 return GRPC_JSON_PARSE_ERROR; |
| 216 } |
| 217 reader->state = GRPC_JSON_STATE_VALUE_END; |
| 218 switch (grpc_json_reader_container_ends(reader)) { |
| 219 case GRPC_JSON_OBJECT: |
| 220 reader->in_object = 1; |
| 221 reader->in_array = 0; |
| 222 break; |
| 223 case GRPC_JSON_ARRAY: |
| 224 reader->in_object = 0; |
| 225 reader->in_array = 1; |
| 226 break; |
| 227 case GRPC_JSON_TOP_LEVEL: |
| 228 GPR_ASSERT(reader->depth == 0); |
| 229 reader->in_object = 0; |
| 230 reader->in_array = 0; |
| 231 reader->state = GRPC_JSON_STATE_END; |
| 232 break; |
| 233 default: |
| 234 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR); |
| 235 } |
| 236 } |
| 237 break; |
| 238 |
| 239 default: |
| 240 return GRPC_JSON_PARSE_ERROR; |
| 241 } |
| 242 break; |
| 243 |
| 244 /* In-string escaping. */ |
| 245 case '\\': |
| 246 switch (reader->state) { |
| 247 case GRPC_JSON_STATE_OBJECT_KEY_STRING: |
| 248 reader->escaped_string_was_key = 1; |
| 249 reader->state = GRPC_JSON_STATE_STRING_ESCAPE; |
| 250 break; |
| 251 |
| 252 case GRPC_JSON_STATE_VALUE_STRING: |
| 253 reader->escaped_string_was_key = 0; |
| 254 reader->state = GRPC_JSON_STATE_STRING_ESCAPE; |
| 255 break; |
| 256 |
| 257 /* This is the \\ case. */ |
| 258 case GRPC_JSON_STATE_STRING_ESCAPE: |
| 259 if (reader->unicode_high_surrogate != 0) |
| 260 return GRPC_JSON_PARSE_ERROR; |
| 261 json_reader_string_add_char(reader, '\\'); |
| 262 if (reader->escaped_string_was_key) { |
| 263 reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; |
| 264 } else { |
| 265 reader->state = GRPC_JSON_STATE_VALUE_STRING; |
| 266 } |
| 267 break; |
| 268 |
| 269 default: |
| 270 return GRPC_JSON_PARSE_ERROR; |
| 271 } |
| 272 break; |
| 273 |
| 274 default: |
| 275 reader->container_just_begun = 0; |
| 276 switch (reader->state) { |
| 277 case GRPC_JSON_STATE_OBJECT_KEY_BEGIN: |
| 278 if (c != '"') return GRPC_JSON_PARSE_ERROR; |
| 279 reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; |
| 280 break; |
| 281 |
| 282 case GRPC_JSON_STATE_OBJECT_KEY_STRING: |
| 283 GPR_ASSERT(reader->unicode_high_surrogate == 0); |
| 284 if (c == '"') { |
| 285 reader->state = GRPC_JSON_STATE_OBJECT_KEY_END; |
| 286 json_reader_set_key(reader); |
| 287 json_reader_string_clear(reader); |
| 288 } else { |
| 289 if (c <= 0x001f) return GRPC_JSON_PARSE_ERROR; |
| 290 json_reader_string_add_char(reader, c); |
| 291 } |
| 292 break; |
| 293 |
| 294 case GRPC_JSON_STATE_VALUE_STRING: |
| 295 if (reader->unicode_high_surrogate != 0) |
| 296 return GRPC_JSON_PARSE_ERROR; |
| 297 if (c == '"') { |
| 298 reader->state = GRPC_JSON_STATE_VALUE_END; |
| 299 json_reader_set_string(reader); |
| 300 json_reader_string_clear(reader); |
| 301 } else { |
| 302 if (c < 32) return GRPC_JSON_PARSE_ERROR; |
| 303 json_reader_string_add_char(reader, c); |
| 304 } |
| 305 break; |
| 306 |
| 307 case GRPC_JSON_STATE_OBJECT_KEY_END: |
| 308 if (c != ':') return GRPC_JSON_PARSE_ERROR; |
| 309 reader->state = GRPC_JSON_STATE_VALUE_BEGIN; |
| 310 break; |
| 311 |
| 312 case GRPC_JSON_STATE_VALUE_BEGIN: |
| 313 switch (c) { |
| 314 case 't': |
| 315 reader->state = GRPC_JSON_STATE_VALUE_TRUE_R; |
| 316 break; |
| 317 |
| 318 case 'f': |
| 319 reader->state = GRPC_JSON_STATE_VALUE_FALSE_A; |
| 320 break; |
| 321 |
| 322 case 'n': |
| 323 reader->state = GRPC_JSON_STATE_VALUE_NULL_U; |
| 324 break; |
| 325 |
| 326 case '"': |
| 327 reader->state = GRPC_JSON_STATE_VALUE_STRING; |
| 328 break; |
| 329 |
| 330 case '0': |
| 331 json_reader_string_add_char(reader, c); |
| 332 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_ZERO; |
| 333 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 json_reader_string_add_char(reader, c); |
| 346 reader->state = GRPC_JSON_STATE_VALUE_NUMBER; |
| 347 break; |
| 348 |
| 349 case '{': |
| 350 reader->container_just_begun = 1; |
| 351 json_reader_container_begins(reader, GRPC_JSON_OBJECT); |
| 352 reader->depth++; |
| 353 reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN; |
| 354 reader->in_object = 1; |
| 355 reader->in_array = 0; |
| 356 break; |
| 357 |
| 358 case '[': |
| 359 reader->container_just_begun = 1; |
| 360 json_reader_container_begins(reader, GRPC_JSON_ARRAY); |
| 361 reader->depth++; |
| 362 reader->in_object = 0; |
| 363 reader->in_array = 1; |
| 364 break; |
| 365 } |
| 366 break; |
| 367 |
| 368 case GRPC_JSON_STATE_STRING_ESCAPE: |
| 369 if (reader->escaped_string_was_key) { |
| 370 reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; |
| 371 } else { |
| 372 reader->state = GRPC_JSON_STATE_VALUE_STRING; |
| 373 } |
| 374 if (reader->unicode_high_surrogate && c != 'u') |
| 375 return GRPC_JSON_PARSE_ERROR; |
| 376 switch (c) { |
| 377 case '"': |
| 378 case '/': |
| 379 json_reader_string_add_char(reader, c); |
| 380 break; |
| 381 case 'b': |
| 382 json_reader_string_add_char(reader, '\b'); |
| 383 break; |
| 384 case 'f': |
| 385 json_reader_string_add_char(reader, '\f'); |
| 386 break; |
| 387 case 'n': |
| 388 json_reader_string_add_char(reader, '\n'); |
| 389 break; |
| 390 case 'r': |
| 391 json_reader_string_add_char(reader, '\r'); |
| 392 break; |
| 393 case 't': |
| 394 json_reader_string_add_char(reader, '\t'); |
| 395 break; |
| 396 case 'u': |
| 397 reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U1; |
| 398 reader->unicode_char = 0; |
| 399 break; |
| 400 default: |
| 401 return GRPC_JSON_PARSE_ERROR; |
| 402 } |
| 403 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 if ((c >= '0') && (c <= '9')) { |
| 410 c -= '0'; |
| 411 } else if ((c >= 'A') && (c <= 'F')) { |
| 412 c -= 'A' - 10; |
| 413 } else if ((c >= 'a') && (c <= 'f')) { |
| 414 c -= 'a' - 10; |
| 415 } else { |
| 416 return GRPC_JSON_PARSE_ERROR; |
| 417 } |
| 418 reader->unicode_char = (uint16_t)(reader->unicode_char << 4); |
| 419 reader->unicode_char = (uint16_t)(reader->unicode_char | c); |
| 420 |
| 421 switch (reader->state) { |
| 422 case GRPC_JSON_STATE_STRING_ESCAPE_U1: |
| 423 reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U2; |
| 424 break; |
| 425 case GRPC_JSON_STATE_STRING_ESCAPE_U2: |
| 426 reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U3; |
| 427 break; |
| 428 case GRPC_JSON_STATE_STRING_ESCAPE_U3: |
| 429 reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U4; |
| 430 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 if ((reader->unicode_char & 0xfc00) == 0xd800) { |
| 436 /* high surrogate utf-16 */ |
| 437 if (reader->unicode_high_surrogate != 0) |
| 438 return GRPC_JSON_PARSE_ERROR; |
| 439 reader->unicode_high_surrogate = reader->unicode_char; |
| 440 } else if ((reader->unicode_char & 0xfc00) == 0xdc00) { |
| 441 /* low surrogate utf-16 */ |
| 442 uint32_t utf32; |
| 443 if (reader->unicode_high_surrogate == 0) |
| 444 return GRPC_JSON_PARSE_ERROR; |
| 445 utf32 = 0x10000; |
| 446 utf32 += (uint32_t)( |
| 447 (reader->unicode_high_surrogate - 0xd800) * 0x400); |
| 448 utf32 += (uint32_t)(reader->unicode_char - 0xdc00); |
| 449 json_reader_string_add_utf32(reader, utf32); |
| 450 reader->unicode_high_surrogate = 0; |
| 451 } else { |
| 452 /* anything else */ |
| 453 if (reader->unicode_high_surrogate != 0) |
| 454 return GRPC_JSON_PARSE_ERROR; |
| 455 json_reader_string_add_utf32(reader, reader->unicode_char); |
| 456 } |
| 457 if (reader->escaped_string_was_key) { |
| 458 reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; |
| 459 } else { |
| 460 reader->state = GRPC_JSON_STATE_VALUE_STRING; |
| 461 } |
| 462 break; |
| 463 default: |
| 464 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR); |
| 465 } |
| 466 break; |
| 467 |
| 468 case GRPC_JSON_STATE_VALUE_NUMBER: |
| 469 json_reader_string_add_char(reader, c); |
| 470 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 break; |
| 482 case 'e': |
| 483 case 'E': |
| 484 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_E; |
| 485 break; |
| 486 case '.': |
| 487 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT; |
| 488 break; |
| 489 default: |
| 490 return GRPC_JSON_PARSE_ERROR; |
| 491 } |
| 492 break; |
| 493 |
| 494 case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL: |
| 495 json_reader_string_add_char(reader, c); |
| 496 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 break; |
| 508 case 'e': |
| 509 case 'E': |
| 510 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_E; |
| 511 break; |
| 512 default: |
| 513 return GRPC_JSON_PARSE_ERROR; |
| 514 } |
| 515 break; |
| 516 |
| 517 case GRPC_JSON_STATE_VALUE_NUMBER_ZERO: |
| 518 if (c != '.') return GRPC_JSON_PARSE_ERROR; |
| 519 json_reader_string_add_char(reader, c); |
| 520 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT; |
| 521 break; |
| 522 |
| 523 case GRPC_JSON_STATE_VALUE_NUMBER_DOT: |
| 524 json_reader_string_add_char(reader, c); |
| 525 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 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL; |
| 537 break; |
| 538 default: |
| 539 return GRPC_JSON_PARSE_ERROR; |
| 540 } |
| 541 break; |
| 542 |
| 543 case GRPC_JSON_STATE_VALUE_NUMBER_E: |
| 544 json_reader_string_add_char(reader, c); |
| 545 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 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_EPM; |
| 559 break; |
| 560 default: |
| 561 return GRPC_JSON_PARSE_ERROR; |
| 562 } |
| 563 break; |
| 564 |
| 565 case GRPC_JSON_STATE_VALUE_NUMBER_EPM: |
| 566 json_reader_string_add_char(reader, c); |
| 567 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 break; |
| 579 default: |
| 580 return GRPC_JSON_PARSE_ERROR; |
| 581 } |
| 582 break; |
| 583 |
| 584 case GRPC_JSON_STATE_VALUE_TRUE_R: |
| 585 if (c != 'r') return GRPC_JSON_PARSE_ERROR; |
| 586 reader->state = GRPC_JSON_STATE_VALUE_TRUE_U; |
| 587 break; |
| 588 |
| 589 case GRPC_JSON_STATE_VALUE_TRUE_U: |
| 590 if (c != 'u') return GRPC_JSON_PARSE_ERROR; |
| 591 reader->state = GRPC_JSON_STATE_VALUE_TRUE_E; |
| 592 break; |
| 593 |
| 594 case GRPC_JSON_STATE_VALUE_TRUE_E: |
| 595 if (c != 'e') return GRPC_JSON_PARSE_ERROR; |
| 596 json_reader_set_true(reader); |
| 597 reader->state = GRPC_JSON_STATE_VALUE_END; |
| 598 break; |
| 599 |
| 600 case GRPC_JSON_STATE_VALUE_FALSE_A: |
| 601 if (c != 'a') return GRPC_JSON_PARSE_ERROR; |
| 602 reader->state = GRPC_JSON_STATE_VALUE_FALSE_L; |
| 603 break; |
| 604 |
| 605 case GRPC_JSON_STATE_VALUE_FALSE_L: |
| 606 if (c != 'l') return GRPC_JSON_PARSE_ERROR; |
| 607 reader->state = GRPC_JSON_STATE_VALUE_FALSE_S; |
| 608 break; |
| 609 |
| 610 case GRPC_JSON_STATE_VALUE_FALSE_S: |
| 611 if (c != 's') return GRPC_JSON_PARSE_ERROR; |
| 612 reader->state = GRPC_JSON_STATE_VALUE_FALSE_E; |
| 613 break; |
| 614 |
| 615 case GRPC_JSON_STATE_VALUE_FALSE_E: |
| 616 if (c != 'e') return GRPC_JSON_PARSE_ERROR; |
| 617 json_reader_set_false(reader); |
| 618 reader->state = GRPC_JSON_STATE_VALUE_END; |
| 619 break; |
| 620 |
| 621 case GRPC_JSON_STATE_VALUE_NULL_U: |
| 622 if (c != 'u') return GRPC_JSON_PARSE_ERROR; |
| 623 reader->state = GRPC_JSON_STATE_VALUE_NULL_L1; |
| 624 break; |
| 625 |
| 626 case GRPC_JSON_STATE_VALUE_NULL_L1: |
| 627 if (c != 'l') return GRPC_JSON_PARSE_ERROR; |
| 628 reader->state = GRPC_JSON_STATE_VALUE_NULL_L2; |
| 629 break; |
| 630 |
| 631 case GRPC_JSON_STATE_VALUE_NULL_L2: |
| 632 if (c != 'l') return GRPC_JSON_PARSE_ERROR; |
| 633 json_reader_set_null(reader); |
| 634 reader->state = GRPC_JSON_STATE_VALUE_END; |
| 635 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 switch (c) { |
| 641 case ',': |
| 642 case '}': |
| 643 case ']': |
| 644 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR); |
| 645 break; |
| 646 |
| 647 default: |
| 648 return GRPC_JSON_PARSE_ERROR; |
| 649 } |
| 650 break; |
| 651 |
| 652 case GRPC_JSON_STATE_END: |
| 653 return GRPC_JSON_PARSE_ERROR; |
| 654 } |
| 655 } |
| 656 } |
| 657 |
| 658 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR); |
| 659 } |
OLD | NEW |