blob: 9e18135b328db12ac896a89f789221a3a44ea45f [file] [log] [blame]
Nicolas Noble614c2bf2015-01-21 15:48:36 -08001/*
2 *
Craig Tiller9d290d52016-03-24 00:20:44 -07003 * Copyright 2015-2016, Google Inc.
Nicolas Noble614c2bf2015-01-21 15:48:36 -08004 * 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
Nicolas Noble8c2be9b2015-01-27 14:21:18 -080034#include <string.h>
35
Nicolas Noblee04455a2015-01-26 17:01:29 -080036#include <grpc/support/port_platform.h>
Nicolas Noble8c2be9b2015-01-27 14:21:18 -080037
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +010038#include <grpc/support/log.h>
39
Craig Tiller9533d042016-03-25 17:11:06 -070040#include "src/core/lib/json/json_reader.h"
Nicolas Noblee04455a2015-01-26 17:01:29 -080041
Craig Tillera82950e2015-09-22 12:33:20 -070042static void json_reader_string_clear(grpc_json_reader *reader) {
43 reader->vtable->string_clear(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080044}
45
Craig Tiller7536af02015-12-22 13:49:30 -080046static void json_reader_string_add_char(grpc_json_reader *reader, uint32_t c) {
Craig Tillera82950e2015-09-22 12:33:20 -070047 reader->vtable->string_add_char(reader->userdata, c);
Nicolas Noblee04455a2015-01-26 17:01:29 -080048}
49
Craig Tillera82950e2015-09-22 12:33:20 -070050static void json_reader_string_add_utf32(grpc_json_reader *reader,
Craig Tiller7536af02015-12-22 13:49:30 -080051 uint32_t utf32) {
Craig Tillera82950e2015-09-22 12:33:20 -070052 reader->vtable->string_add_utf32(reader->userdata, utf32);
Nicolas Noblee04455a2015-01-26 17:01:29 -080053}
54
Craig Tiller7536af02015-12-22 13:49:30 -080055static uint32_t grpc_json_reader_read_char(grpc_json_reader *reader) {
Craig Tillera82950e2015-09-22 12:33:20 -070056 return reader->vtable->read_char(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080057}
58
Craig Tillera82950e2015-09-22 12:33:20 -070059static void json_reader_container_begins(grpc_json_reader *reader,
60 grpc_json_type type) {
61 reader->vtable->container_begins(reader->userdata, type);
Nicolas Noblee04455a2015-01-26 17:01:29 -080062}
63
Craig Tillera82950e2015-09-22 12:33:20 -070064static grpc_json_type grpc_json_reader_container_ends(
65 grpc_json_reader *reader) {
66 return reader->vtable->container_ends(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080067}
68
Craig Tillera82950e2015-09-22 12:33:20 -070069static void json_reader_set_key(grpc_json_reader *reader) {
70 reader->vtable->set_key(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080071}
72
Craig Tillera82950e2015-09-22 12:33:20 -070073static void json_reader_set_string(grpc_json_reader *reader) {
74 reader->vtable->set_string(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080075}
76
Craig Tillera82950e2015-09-22 12:33:20 -070077static int json_reader_set_number(grpc_json_reader *reader) {
78 return reader->vtable->set_number(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080079}
80
Craig Tillera82950e2015-09-22 12:33:20 -070081static void json_reader_set_true(grpc_json_reader *reader) {
82 reader->vtable->set_true(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080083}
84
Craig Tillera82950e2015-09-22 12:33:20 -070085static void json_reader_set_false(grpc_json_reader *reader) {
86 reader->vtable->set_false(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080087}
88
Craig Tillera82950e2015-09-22 12:33:20 -070089static void json_reader_set_null(grpc_json_reader *reader) {
90 reader->vtable->set_null(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080091}
Nicolas Noble614c2bf2015-01-21 15:48:36 -080092
93/* Call this function to initialize the reader structure. */
Craig Tillera82950e2015-09-22 12:33:20 -070094void grpc_json_reader_init(grpc_json_reader *reader,
95 grpc_json_reader_vtable *vtable, void *userdata) {
96 memset(reader, 0, sizeof(*reader));
Nicolas Noble8c2be9b2015-01-27 14:21:18 -080097 reader->vtable = vtable;
98 reader->userdata = userdata;
Craig Tillera82950e2015-09-22 12:33:20 -070099 json_reader_string_clear(reader);
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800100 reader->state = GRPC_JSON_STATE_VALUE_BEGIN;
101}
102
Craig Tillera82950e2015-09-22 12:33:20 -0700103int 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)));
Nicolas Noblee04455a2015-01-26 17:01:29 -0800107}
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800108
Craig Tillera82950e2015-09-22 12:33:20 -0700109grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) {
Craig Tiller7536af02015-12-22 13:49:30 -0800110 uint32_t c, success;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800111
Nicolas Noblee04455a2015-01-26 17:01:29 -0800112 /* This state-machine is a strict implementation of ECMA-404 */
Craig Tillera82950e2015-09-22 12:33:20 -0700113 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800119
Craig Tillera82950e2015-09-22 12:33:20 -0700120 case GRPC_JSON_READ_CHAR_EAGAIN:
121 return GRPC_JSON_EAGAIN;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800122
Craig Tillera82950e2015-09-22 12:33:20 -0700123 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800130
Craig Tillera82950e2015-09-22 12:33:20 -0700131 /* 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800143
Craig Tillera82950e2015-09-22 12:33:20 -0700144 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800151
Craig Tillera82950e2015-09-22 12:33:20 -0700152 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:
Craig Tiller7536af02015-12-22 13:49:30 -0800156 success = (uint32_t)json_reader_set_number(reader);
Craig Tillera82950e2015-09-22 12:33:20 -0700157 if (!success) return GRPC_JSON_PARSE_ERROR;
158 json_reader_string_clear(reader);
159 reader->state = GRPC_JSON_STATE_VALUE_END;
160 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800161
Craig Tillera82950e2015-09-22 12:33:20 -0700162 default:
163 return GRPC_JSON_PARSE_ERROR;
164 }
165 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800166
Craig Tillera82950e2015-09-22 12:33:20 -0700167 /* 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800178
Craig Tillera82950e2015-09-22 12:33:20 -0700179 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:
Nicolas "Pixel" Noble82a91c92016-03-30 07:01:52 +0200183 if (reader->depth == 0) {
184 return GRPC_JSON_PARSE_ERROR;
185 } else if ((c == '}') && !reader->in_object) {
186 return GRPC_JSON_PARSE_ERROR;
187 } else if ((c == ']') && !reader->in_array) {
188 return GRPC_JSON_PARSE_ERROR;
189 }
Craig Tiller7536af02015-12-22 13:49:30 -0800190 success = (uint32_t)json_reader_set_number(reader);
Craig Tillera82950e2015-09-22 12:33:20 -0700191 if (!success) return GRPC_JSON_PARSE_ERROR;
192 json_reader_string_clear(reader);
193 reader->state = GRPC_JSON_STATE_VALUE_END;
194 /* The missing break here is intentional. */
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800195
Craig Tillera82950e2015-09-22 12:33:20 -0700196 case GRPC_JSON_STATE_VALUE_END:
197 case GRPC_JSON_STATE_OBJECT_KEY_BEGIN:
198 case GRPC_JSON_STATE_VALUE_BEGIN:
199 if (c == ',') {
200 if (reader->state != GRPC_JSON_STATE_VALUE_END) {
201 return GRPC_JSON_PARSE_ERROR;
202 }
203 if (reader->in_object) {
204 reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN;
Nicolas "Pixel" Noble959b6f52016-04-01 00:53:57 +0200205 } else if (reader->in_array) {
Craig Tillera82950e2015-09-22 12:33:20 -0700206 reader->state = GRPC_JSON_STATE_VALUE_BEGIN;
Nicolas "Pixel" Noble959b6f52016-04-01 00:53:57 +0200207 } else {
208 return GRPC_JSON_PARSE_ERROR;
Craig Tillera82950e2015-09-22 12:33:20 -0700209 }
210 } else {
211 if (reader->depth-- == 0) return GRPC_JSON_PARSE_ERROR;
212 if ((c == '}') && !reader->in_object) {
213 return GRPC_JSON_PARSE_ERROR;
214 }
215 if ((c == '}') &&
216 (reader->state == GRPC_JSON_STATE_OBJECT_KEY_BEGIN) &&
217 !reader->container_just_begun) {
218 return GRPC_JSON_PARSE_ERROR;
219 }
220 if ((c == ']') && !reader->in_array) return GRPC_JSON_PARSE_ERROR;
221 if ((c == ']') &&
222 (reader->state == GRPC_JSON_STATE_VALUE_BEGIN) &&
223 !reader->container_just_begun) {
224 return GRPC_JSON_PARSE_ERROR;
225 }
226 reader->state = GRPC_JSON_STATE_VALUE_END;
227 switch (grpc_json_reader_container_ends(reader)) {
228 case GRPC_JSON_OBJECT:
229 reader->in_object = 1;
230 reader->in_array = 0;
231 break;
232 case GRPC_JSON_ARRAY:
233 reader->in_object = 0;
234 reader->in_array = 1;
235 break;
236 case GRPC_JSON_TOP_LEVEL:
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +0100237 GPR_ASSERT(reader->depth == 0);
Craig Tillera82950e2015-09-22 12:33:20 -0700238 reader->in_object = 0;
239 reader->in_array = 0;
240 reader->state = GRPC_JSON_STATE_END;
241 break;
242 default:
Craig Tiller620e9652015-12-14 12:02:50 -0800243 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
Craig Tillera82950e2015-09-22 12:33:20 -0700244 }
245 }
246 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800247
Craig Tillera82950e2015-09-22 12:33:20 -0700248 default:
249 return GRPC_JSON_PARSE_ERROR;
250 }
251 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800252
Craig Tillera82950e2015-09-22 12:33:20 -0700253 /* In-string escaping. */
254 case '\\':
255 switch (reader->state) {
256 case GRPC_JSON_STATE_OBJECT_KEY_STRING:
257 reader->escaped_string_was_key = 1;
258 reader->state = GRPC_JSON_STATE_STRING_ESCAPE;
259 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800260
Craig Tillera82950e2015-09-22 12:33:20 -0700261 case GRPC_JSON_STATE_VALUE_STRING:
262 reader->escaped_string_was_key = 0;
263 reader->state = GRPC_JSON_STATE_STRING_ESCAPE;
264 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800265
Craig Tillera82950e2015-09-22 12:33:20 -0700266 /* This is the \\ case. */
267 case GRPC_JSON_STATE_STRING_ESCAPE:
268 if (reader->unicode_high_surrogate != 0)
269 return GRPC_JSON_PARSE_ERROR;
270 json_reader_string_add_char(reader, '\\');
271 if (reader->escaped_string_was_key) {
272 reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
273 } else {
274 reader->state = GRPC_JSON_STATE_VALUE_STRING;
275 }
276 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800277
Craig Tillera82950e2015-09-22 12:33:20 -0700278 default:
279 return GRPC_JSON_PARSE_ERROR;
280 }
281 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800282
Craig Tillera82950e2015-09-22 12:33:20 -0700283 default:
284 reader->container_just_begun = 0;
285 switch (reader->state) {
286 case GRPC_JSON_STATE_OBJECT_KEY_BEGIN:
287 if (c != '"') return GRPC_JSON_PARSE_ERROR;
288 reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
289 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800290
Craig Tillera82950e2015-09-22 12:33:20 -0700291 case GRPC_JSON_STATE_OBJECT_KEY_STRING:
Nicolas "Pixel" Noblec9088602016-03-18 00:24:33 +0100292 if (reader->unicode_high_surrogate != 0)
293 return GRPC_JSON_PARSE_ERROR;
Craig Tillera82950e2015-09-22 12:33:20 -0700294 if (c == '"') {
295 reader->state = GRPC_JSON_STATE_OBJECT_KEY_END;
296 json_reader_set_key(reader);
297 json_reader_string_clear(reader);
298 } else {
Nicolas "Pixel" Noblec9088602016-03-18 00:24:33 +0100299 if (c < 32) return GRPC_JSON_PARSE_ERROR;
Craig Tillera82950e2015-09-22 12:33:20 -0700300 json_reader_string_add_char(reader, c);
301 }
302 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800303
Craig Tillera82950e2015-09-22 12:33:20 -0700304 case GRPC_JSON_STATE_VALUE_STRING:
305 if (reader->unicode_high_surrogate != 0)
306 return GRPC_JSON_PARSE_ERROR;
307 if (c == '"') {
308 reader->state = GRPC_JSON_STATE_VALUE_END;
309 json_reader_set_string(reader);
310 json_reader_string_clear(reader);
311 } else {
312 if (c < 32) return GRPC_JSON_PARSE_ERROR;
313 json_reader_string_add_char(reader, c);
314 }
315 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800316
Craig Tillera82950e2015-09-22 12:33:20 -0700317 case GRPC_JSON_STATE_OBJECT_KEY_END:
318 if (c != ':') return GRPC_JSON_PARSE_ERROR;
319 reader->state = GRPC_JSON_STATE_VALUE_BEGIN;
320 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800321
Craig Tillera82950e2015-09-22 12:33:20 -0700322 case GRPC_JSON_STATE_VALUE_BEGIN:
323 switch (c) {
324 case 't':
325 reader->state = GRPC_JSON_STATE_VALUE_TRUE_R;
326 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800327
Craig Tillera82950e2015-09-22 12:33:20 -0700328 case 'f':
329 reader->state = GRPC_JSON_STATE_VALUE_FALSE_A;
330 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800331
Craig Tillera82950e2015-09-22 12:33:20 -0700332 case 'n':
333 reader->state = GRPC_JSON_STATE_VALUE_NULL_U;
334 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800335
Craig Tillera82950e2015-09-22 12:33:20 -0700336 case '"':
337 reader->state = GRPC_JSON_STATE_VALUE_STRING;
338 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800339
Craig Tillera82950e2015-09-22 12:33:20 -0700340 case '0':
341 json_reader_string_add_char(reader, c);
342 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_ZERO;
343 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800344
Craig Tillera82950e2015-09-22 12:33:20 -0700345 case '1':
346 case '2':
347 case '3':
348 case '4':
349 case '5':
350 case '6':
351 case '7':
352 case '8':
353 case '9':
354 case '-':
355 json_reader_string_add_char(reader, c);
356 reader->state = GRPC_JSON_STATE_VALUE_NUMBER;
357 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800358
Craig Tillera82950e2015-09-22 12:33:20 -0700359 case '{':
360 reader->container_just_begun = 1;
361 json_reader_container_begins(reader, GRPC_JSON_OBJECT);
362 reader->depth++;
363 reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN;
364 reader->in_object = 1;
365 reader->in_array = 0;
366 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800367
Craig Tillera82950e2015-09-22 12:33:20 -0700368 case '[':
369 reader->container_just_begun = 1;
370 json_reader_container_begins(reader, GRPC_JSON_ARRAY);
371 reader->depth++;
372 reader->in_object = 0;
373 reader->in_array = 1;
374 break;
Nicolas "Pixel" Noblec9088602016-03-18 00:24:33 +0100375 default:
376 return GRPC_JSON_PARSE_ERROR;
Craig Tillera82950e2015-09-22 12:33:20 -0700377 }
378 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800379
Craig Tillera82950e2015-09-22 12:33:20 -0700380 case GRPC_JSON_STATE_STRING_ESCAPE:
381 if (reader->escaped_string_was_key) {
382 reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
383 } else {
384 reader->state = GRPC_JSON_STATE_VALUE_STRING;
385 }
386 if (reader->unicode_high_surrogate && c != 'u')
387 return GRPC_JSON_PARSE_ERROR;
388 switch (c) {
389 case '"':
390 case '/':
391 json_reader_string_add_char(reader, c);
392 break;
393 case 'b':
394 json_reader_string_add_char(reader, '\b');
395 break;
396 case 'f':
397 json_reader_string_add_char(reader, '\f');
398 break;
399 case 'n':
400 json_reader_string_add_char(reader, '\n');
401 break;
402 case 'r':
403 json_reader_string_add_char(reader, '\r');
404 break;
405 case 't':
406 json_reader_string_add_char(reader, '\t');
407 break;
408 case 'u':
409 reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U1;
410 reader->unicode_char = 0;
411 break;
412 default:
413 return GRPC_JSON_PARSE_ERROR;
414 }
415 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800416
Craig Tillera82950e2015-09-22 12:33:20 -0700417 case GRPC_JSON_STATE_STRING_ESCAPE_U1:
418 case GRPC_JSON_STATE_STRING_ESCAPE_U2:
419 case GRPC_JSON_STATE_STRING_ESCAPE_U3:
420 case GRPC_JSON_STATE_STRING_ESCAPE_U4:
421 if ((c >= '0') && (c <= '9')) {
422 c -= '0';
423 } else if ((c >= 'A') && (c <= 'F')) {
424 c -= 'A' - 10;
425 } else if ((c >= 'a') && (c <= 'f')) {
426 c -= 'a' - 10;
427 } else {
428 return GRPC_JSON_PARSE_ERROR;
429 }
Craig Tiller7536af02015-12-22 13:49:30 -0800430 reader->unicode_char = (uint16_t)(reader->unicode_char << 4);
431 reader->unicode_char = (uint16_t)(reader->unicode_char | c);
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800432
Craig Tillera82950e2015-09-22 12:33:20 -0700433 switch (reader->state) {
434 case GRPC_JSON_STATE_STRING_ESCAPE_U1:
435 reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U2;
436 break;
437 case GRPC_JSON_STATE_STRING_ESCAPE_U2:
438 reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U3;
439 break;
440 case GRPC_JSON_STATE_STRING_ESCAPE_U3:
441 reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U4;
442 break;
443 case GRPC_JSON_STATE_STRING_ESCAPE_U4:
444 /* See grpc_json_writer_escape_string to have a description
445 * of what's going on here.
446 */
447 if ((reader->unicode_char & 0xfc00) == 0xd800) {
448 /* high surrogate utf-16 */
449 if (reader->unicode_high_surrogate != 0)
450 return GRPC_JSON_PARSE_ERROR;
451 reader->unicode_high_surrogate = reader->unicode_char;
452 } else if ((reader->unicode_char & 0xfc00) == 0xdc00) {
453 /* low surrogate utf-16 */
Craig Tiller7536af02015-12-22 13:49:30 -0800454 uint32_t utf32;
Craig Tillera82950e2015-09-22 12:33:20 -0700455 if (reader->unicode_high_surrogate == 0)
456 return GRPC_JSON_PARSE_ERROR;
457 utf32 = 0x10000;
Craig Tiller7536af02015-12-22 13:49:30 -0800458 utf32 += (uint32_t)(
Craig Tillera82950e2015-09-22 12:33:20 -0700459 (reader->unicode_high_surrogate - 0xd800) * 0x400);
Craig Tiller7536af02015-12-22 13:49:30 -0800460 utf32 += (uint32_t)(reader->unicode_char - 0xdc00);
Craig Tillera82950e2015-09-22 12:33:20 -0700461 json_reader_string_add_utf32(reader, utf32);
462 reader->unicode_high_surrogate = 0;
463 } else {
464 /* anything else */
465 if (reader->unicode_high_surrogate != 0)
466 return GRPC_JSON_PARSE_ERROR;
467 json_reader_string_add_utf32(reader, reader->unicode_char);
468 }
469 if (reader->escaped_string_was_key) {
470 reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
471 } else {
472 reader->state = GRPC_JSON_STATE_VALUE_STRING;
473 }
474 break;
475 default:
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +0100476 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
Craig Tillera82950e2015-09-22 12:33:20 -0700477 }
478 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800479
Craig Tillera82950e2015-09-22 12:33:20 -0700480 case GRPC_JSON_STATE_VALUE_NUMBER:
481 json_reader_string_add_char(reader, c);
482 switch (c) {
483 case '0':
484 case '1':
485 case '2':
486 case '3':
487 case '4':
488 case '5':
489 case '6':
490 case '7':
491 case '8':
492 case '9':
493 break;
494 case 'e':
495 case 'E':
496 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_E;
497 break;
498 case '.':
499 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT;
500 break;
501 default:
502 return GRPC_JSON_PARSE_ERROR;
503 }
504 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800505
Craig Tillera82950e2015-09-22 12:33:20 -0700506 case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
507 json_reader_string_add_char(reader, c);
508 switch (c) {
509 case '0':
510 case '1':
511 case '2':
512 case '3':
513 case '4':
514 case '5':
515 case '6':
516 case '7':
517 case '8':
518 case '9':
519 break;
520 case 'e':
521 case 'E':
522 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_E;
523 break;
524 default:
525 return GRPC_JSON_PARSE_ERROR;
526 }
527 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800528
Craig Tillera82950e2015-09-22 12:33:20 -0700529 case GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
530 if (c != '.') return GRPC_JSON_PARSE_ERROR;
531 json_reader_string_add_char(reader, c);
532 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT;
533 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800534
Craig Tillera82950e2015-09-22 12:33:20 -0700535 case GRPC_JSON_STATE_VALUE_NUMBER_DOT:
536 json_reader_string_add_char(reader, c);
537 switch (c) {
538 case '0':
539 case '1':
540 case '2':
541 case '3':
542 case '4':
543 case '5':
544 case '6':
545 case '7':
546 case '8':
547 case '9':
548 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL;
549 break;
550 default:
551 return GRPC_JSON_PARSE_ERROR;
552 }
553 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800554
Craig Tillera82950e2015-09-22 12:33:20 -0700555 case GRPC_JSON_STATE_VALUE_NUMBER_E:
556 json_reader_string_add_char(reader, c);
557 switch (c) {
558 case '0':
559 case '1':
560 case '2':
561 case '3':
562 case '4':
563 case '5':
564 case '6':
565 case '7':
566 case '8':
567 case '9':
568 case '+':
569 case '-':
570 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_EPM;
571 break;
572 default:
573 return GRPC_JSON_PARSE_ERROR;
574 }
575 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800576
Craig Tillera82950e2015-09-22 12:33:20 -0700577 case GRPC_JSON_STATE_VALUE_NUMBER_EPM:
578 json_reader_string_add_char(reader, c);
579 switch (c) {
580 case '0':
581 case '1':
582 case '2':
583 case '3':
584 case '4':
585 case '5':
586 case '6':
587 case '7':
588 case '8':
589 case '9':
590 break;
591 default:
592 return GRPC_JSON_PARSE_ERROR;
593 }
594 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800595
Craig Tillera82950e2015-09-22 12:33:20 -0700596 case GRPC_JSON_STATE_VALUE_TRUE_R:
597 if (c != 'r') return GRPC_JSON_PARSE_ERROR;
598 reader->state = GRPC_JSON_STATE_VALUE_TRUE_U;
599 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800600
Craig Tillera82950e2015-09-22 12:33:20 -0700601 case GRPC_JSON_STATE_VALUE_TRUE_U:
602 if (c != 'u') return GRPC_JSON_PARSE_ERROR;
603 reader->state = GRPC_JSON_STATE_VALUE_TRUE_E;
604 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800605
Craig Tillera82950e2015-09-22 12:33:20 -0700606 case GRPC_JSON_STATE_VALUE_TRUE_E:
607 if (c != 'e') return GRPC_JSON_PARSE_ERROR;
608 json_reader_set_true(reader);
609 reader->state = GRPC_JSON_STATE_VALUE_END;
610 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800611
Craig Tillera82950e2015-09-22 12:33:20 -0700612 case GRPC_JSON_STATE_VALUE_FALSE_A:
613 if (c != 'a') return GRPC_JSON_PARSE_ERROR;
614 reader->state = GRPC_JSON_STATE_VALUE_FALSE_L;
615 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800616
Craig Tillera82950e2015-09-22 12:33:20 -0700617 case GRPC_JSON_STATE_VALUE_FALSE_L:
618 if (c != 'l') return GRPC_JSON_PARSE_ERROR;
619 reader->state = GRPC_JSON_STATE_VALUE_FALSE_S;
620 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800621
Craig Tillera82950e2015-09-22 12:33:20 -0700622 case GRPC_JSON_STATE_VALUE_FALSE_S:
623 if (c != 's') return GRPC_JSON_PARSE_ERROR;
624 reader->state = GRPC_JSON_STATE_VALUE_FALSE_E;
625 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800626
Craig Tillera82950e2015-09-22 12:33:20 -0700627 case GRPC_JSON_STATE_VALUE_FALSE_E:
628 if (c != 'e') return GRPC_JSON_PARSE_ERROR;
629 json_reader_set_false(reader);
630 reader->state = GRPC_JSON_STATE_VALUE_END;
631 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800632
Craig Tillera82950e2015-09-22 12:33:20 -0700633 case GRPC_JSON_STATE_VALUE_NULL_U:
634 if (c != 'u') return GRPC_JSON_PARSE_ERROR;
635 reader->state = GRPC_JSON_STATE_VALUE_NULL_L1;
636 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800637
Craig Tillera82950e2015-09-22 12:33:20 -0700638 case GRPC_JSON_STATE_VALUE_NULL_L1:
639 if (c != 'l') return GRPC_JSON_PARSE_ERROR;
640 reader->state = GRPC_JSON_STATE_VALUE_NULL_L2;
641 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800642
Craig Tillera82950e2015-09-22 12:33:20 -0700643 case GRPC_JSON_STATE_VALUE_NULL_L2:
644 if (c != 'l') return GRPC_JSON_PARSE_ERROR;
645 json_reader_set_null(reader);
646 reader->state = GRPC_JSON_STATE_VALUE_END;
647 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800648
Craig Tillera82950e2015-09-22 12:33:20 -0700649 /* All of the VALUE_END cases are handled in the specialized case
650 * above. */
651 case GRPC_JSON_STATE_VALUE_END:
652 switch (c) {
653 case ',':
654 case '}':
655 case ']':
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +0100656 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
Craig Tillera82950e2015-09-22 12:33:20 -0700657 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800658
Craig Tillera82950e2015-09-22 12:33:20 -0700659 default:
660 return GRPC_JSON_PARSE_ERROR;
661 }
662 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800663
Craig Tillera82950e2015-09-22 12:33:20 -0700664 case GRPC_JSON_STATE_END:
665 return GRPC_JSON_PARSE_ERROR;
666 }
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800667 }
Craig Tillera82950e2015-09-22 12:33:20 -0700668 }
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800669
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +0100670 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
Craig Tiller190d3602015-02-18 09:23:38 -0800671}