blob: 861323d10c2f49731624921443dfe0b5908e72a4 [file] [log] [blame]
Nicolas Noble614c2bf2015-01-21 15:48:36 -08001/*
2 *
Craig Tiller8a9fd522016-03-25 17:09:29 -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
Nicolas Noblee04455a2015-01-26 17:01:29 -080040#include "src/core/json/json_reader.h"
41
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:
Craig Tiller7536af02015-12-22 13:49:30 -0800183 success = (uint32_t)json_reader_set_number(reader);
Craig Tillera82950e2015-09-22 12:33:20 -0700184 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. */
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800188
Craig Tillera82950e2015-09-22 12:33:20 -0700189 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:
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +0100228 GPR_ASSERT(reader->depth == 0);
Craig Tillera82950e2015-09-22 12:33:20 -0700229 reader->in_object = 0;
230 reader->in_array = 0;
231 reader->state = GRPC_JSON_STATE_END;
232 break;
233 default:
Craig Tiller620e9652015-12-14 12:02:50 -0800234 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
Craig Tillera82950e2015-09-22 12:33:20 -0700235 }
236 }
237 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800238
Craig Tillera82950e2015-09-22 12:33:20 -0700239 default:
240 return GRPC_JSON_PARSE_ERROR;
241 }
242 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800243
Craig Tillera82950e2015-09-22 12:33:20 -0700244 /* 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800251
Craig Tillera82950e2015-09-22 12:33:20 -0700252 case GRPC_JSON_STATE_VALUE_STRING:
253 reader->escaped_string_was_key = 0;
254 reader->state = GRPC_JSON_STATE_STRING_ESCAPE;
255 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800256
Craig Tillera82950e2015-09-22 12:33:20 -0700257 /* 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800268
Craig Tillera82950e2015-09-22 12:33:20 -0700269 default:
270 return GRPC_JSON_PARSE_ERROR;
271 }
272 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800273
Craig Tillera82950e2015-09-22 12:33:20 -0700274 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800281
Craig Tillera82950e2015-09-22 12:33:20 -0700282 case GRPC_JSON_STATE_OBJECT_KEY_STRING:
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +0100283 GPR_ASSERT(reader->unicode_high_surrogate == 0);
Craig Tillera82950e2015-09-22 12:33:20 -0700284 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800293
Craig Tillera82950e2015-09-22 12:33:20 -0700294 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800306
Craig Tillera82950e2015-09-22 12:33:20 -0700307 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800311
Craig Tillera82950e2015-09-22 12:33:20 -0700312 case GRPC_JSON_STATE_VALUE_BEGIN:
313 switch (c) {
314 case 't':
315 reader->state = GRPC_JSON_STATE_VALUE_TRUE_R;
316 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800317
Craig Tillera82950e2015-09-22 12:33:20 -0700318 case 'f':
319 reader->state = GRPC_JSON_STATE_VALUE_FALSE_A;
320 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800321
Craig Tillera82950e2015-09-22 12:33:20 -0700322 case 'n':
323 reader->state = GRPC_JSON_STATE_VALUE_NULL_U;
324 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800325
Craig Tillera82950e2015-09-22 12:33:20 -0700326 case '"':
327 reader->state = GRPC_JSON_STATE_VALUE_STRING;
328 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800329
Craig Tillera82950e2015-09-22 12:33:20 -0700330 case '0':
331 json_reader_string_add_char(reader, c);
332 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_ZERO;
333 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800334
Craig Tillera82950e2015-09-22 12:33:20 -0700335 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800348
Craig Tillera82950e2015-09-22 12:33:20 -0700349 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800357
Craig Tillera82950e2015-09-22 12:33:20 -0700358 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800367
Craig Tillera82950e2015-09-22 12:33:20 -0700368 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800404
Craig Tillera82950e2015-09-22 12:33:20 -0700405 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 }
Craig Tiller7536af02015-12-22 13:49:30 -0800418 reader->unicode_char = (uint16_t)(reader->unicode_char << 4);
419 reader->unicode_char = (uint16_t)(reader->unicode_char | c);
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800420
Craig Tillera82950e2015-09-22 12:33:20 -0700421 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 */
Craig Tiller7536af02015-12-22 13:49:30 -0800442 uint32_t utf32;
Craig Tillera82950e2015-09-22 12:33:20 -0700443 if (reader->unicode_high_surrogate == 0)
444 return GRPC_JSON_PARSE_ERROR;
445 utf32 = 0x10000;
Craig Tiller7536af02015-12-22 13:49:30 -0800446 utf32 += (uint32_t)(
Craig Tillera82950e2015-09-22 12:33:20 -0700447 (reader->unicode_high_surrogate - 0xd800) * 0x400);
Craig Tiller7536af02015-12-22 13:49:30 -0800448 utf32 += (uint32_t)(reader->unicode_char - 0xdc00);
Craig Tillera82950e2015-09-22 12:33:20 -0700449 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:
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +0100464 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
Craig Tillera82950e2015-09-22 12:33:20 -0700465 }
466 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800467
Craig Tillera82950e2015-09-22 12:33:20 -0700468 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800493
Craig Tillera82950e2015-09-22 12:33:20 -0700494 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800516
Craig Tillera82950e2015-09-22 12:33:20 -0700517 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800522
Craig Tillera82950e2015-09-22 12:33:20 -0700523 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800542
Craig Tillera82950e2015-09-22 12:33:20 -0700543 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800564
Craig Tillera82950e2015-09-22 12:33:20 -0700565 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800583
Craig Tillera82950e2015-09-22 12:33:20 -0700584 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800588
Craig Tillera82950e2015-09-22 12:33:20 -0700589 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800593
Craig Tillera82950e2015-09-22 12:33:20 -0700594 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800599
Craig Tillera82950e2015-09-22 12:33:20 -0700600 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800604
Craig Tillera82950e2015-09-22 12:33:20 -0700605 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800609
Craig Tillera82950e2015-09-22 12:33:20 -0700610 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800614
Craig Tillera82950e2015-09-22 12:33:20 -0700615 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800620
Craig Tillera82950e2015-09-22 12:33:20 -0700621 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800625
Craig Tillera82950e2015-09-22 12:33:20 -0700626 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800630
Craig Tillera82950e2015-09-22 12:33:20 -0700631 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;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800636
Craig Tillera82950e2015-09-22 12:33:20 -0700637 /* 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 ']':
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +0100644 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
Craig Tillera82950e2015-09-22 12:33:20 -0700645 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800646
Craig Tillera82950e2015-09-22 12:33:20 -0700647 default:
648 return GRPC_JSON_PARSE_ERROR;
649 }
650 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800651
Craig Tillera82950e2015-09-22 12:33:20 -0700652 case GRPC_JSON_STATE_END:
653 return GRPC_JSON_PARSE_ERROR;
654 }
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800655 }
Craig Tillera82950e2015-09-22 12:33:20 -0700656 }
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800657
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +0100658 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
Craig Tiller190d3602015-02-18 09:23:38 -0800659}