blob: 094a35176cf4b5bc058a830e3bcb78a442b69ead [file] [log] [blame]
Nicolas Noble614c2bf2015-01-21 15:48:36 -08001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2015-2016 gRPC authors.
Nicolas Noble614c2bf2015-01-21 15:48:36 -08004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
Nicolas Noble614c2bf2015-01-21 15:48:36 -08008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Nicolas Noble614c2bf2015-01-21 15:48:36 -080010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
Nicolas Noble614c2bf2015-01-21 15:48:36 -080016 *
17 */
18
Nicolas Noble8c2be9b2015-01-27 14:21:18 -080019#include <string.h>
20
Nicolas Noblee04455a2015-01-26 17:01:29 -080021#include <grpc/support/port_platform.h>
Nicolas Noble8c2be9b2015-01-27 14:21:18 -080022
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +010023#include <grpc/support/log.h>
24
Craig Tiller9533d042016-03-25 17:11:06 -070025#include "src/core/lib/json/json_reader.h"
Nicolas Noblee04455a2015-01-26 17:01:29 -080026
Craig Tillera82950e2015-09-22 12:33:20 -070027static void json_reader_string_clear(grpc_json_reader *reader) {
28 reader->vtable->string_clear(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080029}
30
Craig Tiller7536af02015-12-22 13:49:30 -080031static void json_reader_string_add_char(grpc_json_reader *reader, uint32_t c) {
Craig Tillera82950e2015-09-22 12:33:20 -070032 reader->vtable->string_add_char(reader->userdata, c);
Nicolas Noblee04455a2015-01-26 17:01:29 -080033}
34
Craig Tillera82950e2015-09-22 12:33:20 -070035static void json_reader_string_add_utf32(grpc_json_reader *reader,
Craig Tiller7536af02015-12-22 13:49:30 -080036 uint32_t utf32) {
Craig Tillera82950e2015-09-22 12:33:20 -070037 reader->vtable->string_add_utf32(reader->userdata, utf32);
Nicolas Noblee04455a2015-01-26 17:01:29 -080038}
39
Craig Tiller7536af02015-12-22 13:49:30 -080040static uint32_t grpc_json_reader_read_char(grpc_json_reader *reader) {
Craig Tillera82950e2015-09-22 12:33:20 -070041 return reader->vtable->read_char(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080042}
43
Craig Tillera82950e2015-09-22 12:33:20 -070044static void json_reader_container_begins(grpc_json_reader *reader,
45 grpc_json_type type) {
46 reader->vtable->container_begins(reader->userdata, type);
Nicolas Noblee04455a2015-01-26 17:01:29 -080047}
48
Craig Tillera82950e2015-09-22 12:33:20 -070049static grpc_json_type grpc_json_reader_container_ends(
50 grpc_json_reader *reader) {
51 return reader->vtable->container_ends(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080052}
53
Craig Tillera82950e2015-09-22 12:33:20 -070054static void json_reader_set_key(grpc_json_reader *reader) {
55 reader->vtable->set_key(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080056}
57
Craig Tillera82950e2015-09-22 12:33:20 -070058static void json_reader_set_string(grpc_json_reader *reader) {
59 reader->vtable->set_string(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080060}
61
Craig Tillera82950e2015-09-22 12:33:20 -070062static int json_reader_set_number(grpc_json_reader *reader) {
63 return reader->vtable->set_number(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080064}
65
Craig Tillera82950e2015-09-22 12:33:20 -070066static void json_reader_set_true(grpc_json_reader *reader) {
67 reader->vtable->set_true(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080068}
69
Craig Tillera82950e2015-09-22 12:33:20 -070070static void json_reader_set_false(grpc_json_reader *reader) {
71 reader->vtable->set_false(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080072}
73
Craig Tillera82950e2015-09-22 12:33:20 -070074static void json_reader_set_null(grpc_json_reader *reader) {
75 reader->vtable->set_null(reader->userdata);
Nicolas Noblee04455a2015-01-26 17:01:29 -080076}
Nicolas Noble614c2bf2015-01-21 15:48:36 -080077
78/* Call this function to initialize the reader structure. */
Craig Tillera82950e2015-09-22 12:33:20 -070079void grpc_json_reader_init(grpc_json_reader *reader,
80 grpc_json_reader_vtable *vtable, void *userdata) {
81 memset(reader, 0, sizeof(*reader));
Nicolas Noble8c2be9b2015-01-27 14:21:18 -080082 reader->vtable = vtable;
83 reader->userdata = userdata;
Craig Tillera82950e2015-09-22 12:33:20 -070084 json_reader_string_clear(reader);
Nicolas Noble614c2bf2015-01-21 15:48:36 -080085 reader->state = GRPC_JSON_STATE_VALUE_BEGIN;
86}
87
Craig Tillera82950e2015-09-22 12:33:20 -070088int grpc_json_reader_is_complete(grpc_json_reader *reader) {
89 return ((reader->depth == 0) &&
90 ((reader->state == GRPC_JSON_STATE_END) ||
91 (reader->state == GRPC_JSON_STATE_VALUE_END)));
Nicolas Noblee04455a2015-01-26 17:01:29 -080092}
Nicolas Noble614c2bf2015-01-21 15:48:36 -080093
Craig Tillera82950e2015-09-22 12:33:20 -070094grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) {
Craig Tiller7536af02015-12-22 13:49:30 -080095 uint32_t c, success;
Nicolas Noble614c2bf2015-01-21 15:48:36 -080096
Nicolas Noblee04455a2015-01-26 17:01:29 -080097 /* This state-machine is a strict implementation of ECMA-404 */
Craig Tillera82950e2015-09-22 12:33:20 -070098 for (;;) {
99 c = grpc_json_reader_read_char(reader);
100 switch (c) {
101 /* Let's process the error cases first. */
102 case GRPC_JSON_READ_CHAR_ERROR:
103 return GRPC_JSON_READ_ERROR;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800104
Craig Tillera82950e2015-09-22 12:33:20 -0700105 case GRPC_JSON_READ_CHAR_EAGAIN:
106 return GRPC_JSON_EAGAIN;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800107
Craig Tillera82950e2015-09-22 12:33:20 -0700108 case GRPC_JSON_READ_CHAR_EOF:
109 if (grpc_json_reader_is_complete(reader)) {
110 return GRPC_JSON_DONE;
111 } else {
112 return GRPC_JSON_PARSE_ERROR;
113 }
114 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800115
Craig Tillera82950e2015-09-22 12:33:20 -0700116 /* Processing whitespaces. */
117 case ' ':
118 case '\t':
119 case '\n':
120 case '\r':
121 switch (reader->state) {
122 case GRPC_JSON_STATE_OBJECT_KEY_BEGIN:
123 case GRPC_JSON_STATE_OBJECT_KEY_END:
124 case GRPC_JSON_STATE_VALUE_BEGIN:
125 case GRPC_JSON_STATE_VALUE_END:
126 case GRPC_JSON_STATE_END:
127 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800128
Craig Tillera82950e2015-09-22 12:33:20 -0700129 case GRPC_JSON_STATE_OBJECT_KEY_STRING:
130 case GRPC_JSON_STATE_VALUE_STRING:
131 if (c != ' ') return GRPC_JSON_PARSE_ERROR;
132 if (reader->unicode_high_surrogate != 0)
133 return GRPC_JSON_PARSE_ERROR;
134 json_reader_string_add_char(reader, c);
135 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800136
Craig Tillera82950e2015-09-22 12:33:20 -0700137 case GRPC_JSON_STATE_VALUE_NUMBER:
138 case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
139 case GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
140 case GRPC_JSON_STATE_VALUE_NUMBER_EPM:
Craig Tiller7536af02015-12-22 13:49:30 -0800141 success = (uint32_t)json_reader_set_number(reader);
Craig Tillera82950e2015-09-22 12:33:20 -0700142 if (!success) return GRPC_JSON_PARSE_ERROR;
143 json_reader_string_clear(reader);
144 reader->state = GRPC_JSON_STATE_VALUE_END;
145 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800146
Craig Tillera82950e2015-09-22 12:33:20 -0700147 default:
148 return GRPC_JSON_PARSE_ERROR;
149 }
150 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800151
Craig Tillera82950e2015-09-22 12:33:20 -0700152 /* Value, object or array terminations. */
153 case ',':
154 case '}':
155 case ']':
156 switch (reader->state) {
157 case GRPC_JSON_STATE_OBJECT_KEY_STRING:
158 case GRPC_JSON_STATE_VALUE_STRING:
Nicolas "Pixel" Nobleacbd8672016-04-28 00:01:16 +0200159 if (reader->unicode_high_surrogate != 0) {
Craig Tillera82950e2015-09-22 12:33:20 -0700160 return GRPC_JSON_PARSE_ERROR;
Nicolas "Pixel" Nobleacbd8672016-04-28 00:01:16 +0200161 }
Craig Tillera82950e2015-09-22 12:33:20 -0700162 json_reader_string_add_char(reader, c);
163 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800164
Craig Tillera82950e2015-09-22 12:33:20 -0700165 case GRPC_JSON_STATE_VALUE_NUMBER:
166 case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
167 case GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
168 case GRPC_JSON_STATE_VALUE_NUMBER_EPM:
Nicolas "Pixel" Noble82a91c92016-03-30 07:01:52 +0200169 if (reader->depth == 0) {
170 return GRPC_JSON_PARSE_ERROR;
171 } else if ((c == '}') && !reader->in_object) {
172 return GRPC_JSON_PARSE_ERROR;
173 } else if ((c == ']') && !reader->in_array) {
174 return GRPC_JSON_PARSE_ERROR;
175 }
Craig Tiller7536af02015-12-22 13:49:30 -0800176 success = (uint32_t)json_reader_set_number(reader);
Craig Tillera82950e2015-09-22 12:33:20 -0700177 if (!success) return GRPC_JSON_PARSE_ERROR;
178 json_reader_string_clear(reader);
179 reader->state = GRPC_JSON_STATE_VALUE_END;
180 /* The missing break here is intentional. */
Alexey Firagod50e01d2017-07-13 18:37:49 +0300181 /* fallthrough */
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800182
Craig Tillera82950e2015-09-22 12:33:20 -0700183 case GRPC_JSON_STATE_VALUE_END:
184 case GRPC_JSON_STATE_OBJECT_KEY_BEGIN:
185 case GRPC_JSON_STATE_VALUE_BEGIN:
186 if (c == ',') {
187 if (reader->state != GRPC_JSON_STATE_VALUE_END) {
188 return GRPC_JSON_PARSE_ERROR;
189 }
190 if (reader->in_object) {
191 reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN;
Nicolas "Pixel" Noble959b6f52016-04-01 00:53:57 +0200192 } else if (reader->in_array) {
Craig Tillera82950e2015-09-22 12:33:20 -0700193 reader->state = GRPC_JSON_STATE_VALUE_BEGIN;
Nicolas "Pixel" Noble959b6f52016-04-01 00:53:57 +0200194 } else {
195 return GRPC_JSON_PARSE_ERROR;
Craig Tillera82950e2015-09-22 12:33:20 -0700196 }
197 } else {
198 if (reader->depth-- == 0) return GRPC_JSON_PARSE_ERROR;
199 if ((c == '}') && !reader->in_object) {
200 return GRPC_JSON_PARSE_ERROR;
201 }
202 if ((c == '}') &&
203 (reader->state == GRPC_JSON_STATE_OBJECT_KEY_BEGIN) &&
204 !reader->container_just_begun) {
205 return GRPC_JSON_PARSE_ERROR;
206 }
207 if ((c == ']') && !reader->in_array) return GRPC_JSON_PARSE_ERROR;
208 if ((c == ']') &&
209 (reader->state == GRPC_JSON_STATE_VALUE_BEGIN) &&
210 !reader->container_just_begun) {
211 return GRPC_JSON_PARSE_ERROR;
212 }
213 reader->state = GRPC_JSON_STATE_VALUE_END;
214 switch (grpc_json_reader_container_ends(reader)) {
215 case GRPC_JSON_OBJECT:
216 reader->in_object = 1;
217 reader->in_array = 0;
218 break;
219 case GRPC_JSON_ARRAY:
220 reader->in_object = 0;
221 reader->in_array = 1;
222 break;
223 case GRPC_JSON_TOP_LEVEL:
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +0100224 GPR_ASSERT(reader->depth == 0);
Craig Tillera82950e2015-09-22 12:33:20 -0700225 reader->in_object = 0;
226 reader->in_array = 0;
227 reader->state = GRPC_JSON_STATE_END;
228 break;
229 default:
Craig Tiller620e9652015-12-14 12:02:50 -0800230 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
Craig Tillera82950e2015-09-22 12:33:20 -0700231 }
232 }
233 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800234
Craig Tillera82950e2015-09-22 12:33:20 -0700235 default:
236 return GRPC_JSON_PARSE_ERROR;
237 }
238 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800239
Craig Tillera82950e2015-09-22 12:33:20 -0700240 /* In-string escaping. */
241 case '\\':
242 switch (reader->state) {
243 case GRPC_JSON_STATE_OBJECT_KEY_STRING:
244 reader->escaped_string_was_key = 1;
245 reader->state = GRPC_JSON_STATE_STRING_ESCAPE;
246 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800247
Craig Tillera82950e2015-09-22 12:33:20 -0700248 case GRPC_JSON_STATE_VALUE_STRING:
249 reader->escaped_string_was_key = 0;
250 reader->state = GRPC_JSON_STATE_STRING_ESCAPE;
251 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800252
Craig Tillera82950e2015-09-22 12:33:20 -0700253 /* This is the \\ case. */
254 case GRPC_JSON_STATE_STRING_ESCAPE:
255 if (reader->unicode_high_surrogate != 0)
256 return GRPC_JSON_PARSE_ERROR;
257 json_reader_string_add_char(reader, '\\');
258 if (reader->escaped_string_was_key) {
259 reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
260 } else {
261 reader->state = GRPC_JSON_STATE_VALUE_STRING;
262 }
263 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800264
Craig Tillera82950e2015-09-22 12:33:20 -0700265 default:
266 return GRPC_JSON_PARSE_ERROR;
267 }
268 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800269
Craig Tillera82950e2015-09-22 12:33:20 -0700270 default:
271 reader->container_just_begun = 0;
272 switch (reader->state) {
273 case GRPC_JSON_STATE_OBJECT_KEY_BEGIN:
274 if (c != '"') return GRPC_JSON_PARSE_ERROR;
275 reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
276 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800277
Craig Tillera82950e2015-09-22 12:33:20 -0700278 case GRPC_JSON_STATE_OBJECT_KEY_STRING:
Nicolas "Pixel" Nobleacbd8672016-04-28 00:01:16 +0200279 if (reader->unicode_high_surrogate != 0) {
Nicolas "Pixel" Noblec9088602016-03-18 00:24:33 +0100280 return GRPC_JSON_PARSE_ERROR;
Nicolas "Pixel" Nobleacbd8672016-04-28 00:01:16 +0200281 }
Craig Tillera82950e2015-09-22 12:33:20 -0700282 if (c == '"') {
283 reader->state = GRPC_JSON_STATE_OBJECT_KEY_END;
284 json_reader_set_key(reader);
285 json_reader_string_clear(reader);
286 } else {
Nicolas "Pixel" Noblec9088602016-03-18 00:24:33 +0100287 if (c < 32) return GRPC_JSON_PARSE_ERROR;
Craig Tillera82950e2015-09-22 12:33:20 -0700288 json_reader_string_add_char(reader, c);
289 }
290 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800291
Craig Tillera82950e2015-09-22 12:33:20 -0700292 case GRPC_JSON_STATE_VALUE_STRING:
Nicolas "Pixel" Nobleacbd8672016-04-28 00:01:16 +0200293 if (reader->unicode_high_surrogate != 0) {
Craig Tillera82950e2015-09-22 12:33:20 -0700294 return GRPC_JSON_PARSE_ERROR;
Nicolas "Pixel" Nobleacbd8672016-04-28 00:01:16 +0200295 }
Craig Tillera82950e2015-09-22 12:33:20 -0700296 if (c == '"') {
297 reader->state = GRPC_JSON_STATE_VALUE_END;
298 json_reader_set_string(reader);
299 json_reader_string_clear(reader);
300 } else {
301 if (c < 32) return GRPC_JSON_PARSE_ERROR;
302 json_reader_string_add_char(reader, c);
303 }
304 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800305
Craig Tillera82950e2015-09-22 12:33:20 -0700306 case GRPC_JSON_STATE_OBJECT_KEY_END:
307 if (c != ':') return GRPC_JSON_PARSE_ERROR;
308 reader->state = GRPC_JSON_STATE_VALUE_BEGIN;
309 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800310
Craig Tillera82950e2015-09-22 12:33:20 -0700311 case GRPC_JSON_STATE_VALUE_BEGIN:
312 switch (c) {
313 case 't':
314 reader->state = GRPC_JSON_STATE_VALUE_TRUE_R;
315 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800316
Craig Tillera82950e2015-09-22 12:33:20 -0700317 case 'f':
318 reader->state = GRPC_JSON_STATE_VALUE_FALSE_A;
319 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800320
Craig Tillera82950e2015-09-22 12:33:20 -0700321 case 'n':
322 reader->state = GRPC_JSON_STATE_VALUE_NULL_U;
323 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800324
Craig Tillera82950e2015-09-22 12:33:20 -0700325 case '"':
326 reader->state = GRPC_JSON_STATE_VALUE_STRING;
327 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800328
Craig Tillera82950e2015-09-22 12:33:20 -0700329 case '0':
330 json_reader_string_add_char(reader, c);
331 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_ZERO;
332 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800333
Craig Tillera82950e2015-09-22 12:33:20 -0700334 case '1':
335 case '2':
336 case '3':
337 case '4':
338 case '5':
339 case '6':
340 case '7':
341 case '8':
342 case '9':
343 case '-':
344 json_reader_string_add_char(reader, c);
345 reader->state = GRPC_JSON_STATE_VALUE_NUMBER;
346 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800347
Craig Tillera82950e2015-09-22 12:33:20 -0700348 case '{':
349 reader->container_just_begun = 1;
350 json_reader_container_begins(reader, GRPC_JSON_OBJECT);
351 reader->depth++;
352 reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN;
353 reader->in_object = 1;
354 reader->in_array = 0;
355 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800356
Craig Tillera82950e2015-09-22 12:33:20 -0700357 case '[':
358 reader->container_just_begun = 1;
359 json_reader_container_begins(reader, GRPC_JSON_ARRAY);
360 reader->depth++;
361 reader->in_object = 0;
362 reader->in_array = 1;
363 break;
Nicolas "Pixel" Noblec9088602016-03-18 00:24:33 +0100364 default:
365 return GRPC_JSON_PARSE_ERROR;
Craig Tillera82950e2015-09-22 12:33:20 -0700366 }
367 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800368
Craig Tillera82950e2015-09-22 12:33:20 -0700369 case GRPC_JSON_STATE_STRING_ESCAPE:
370 if (reader->escaped_string_was_key) {
371 reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
372 } else {
373 reader->state = GRPC_JSON_STATE_VALUE_STRING;
374 }
Nicolas "Pixel" Nobleacbd8672016-04-28 00:01:16 +0200375 if (reader->unicode_high_surrogate && c != 'u') {
Craig Tillera82950e2015-09-22 12:33:20 -0700376 return GRPC_JSON_PARSE_ERROR;
Nicolas "Pixel" Nobleacbd8672016-04-28 00:01:16 +0200377 }
Craig Tillera82950e2015-09-22 12:33:20 -0700378 switch (c) {
379 case '"':
380 case '/':
381 json_reader_string_add_char(reader, c);
382 break;
383 case 'b':
384 json_reader_string_add_char(reader, '\b');
385 break;
386 case 'f':
387 json_reader_string_add_char(reader, '\f');
388 break;
389 case 'n':
390 json_reader_string_add_char(reader, '\n');
391 break;
392 case 'r':
393 json_reader_string_add_char(reader, '\r');
394 break;
395 case 't':
396 json_reader_string_add_char(reader, '\t');
397 break;
398 case 'u':
399 reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U1;
400 reader->unicode_char = 0;
401 break;
402 default:
403 return GRPC_JSON_PARSE_ERROR;
404 }
405 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800406
Craig Tillera82950e2015-09-22 12:33:20 -0700407 case GRPC_JSON_STATE_STRING_ESCAPE_U1:
408 case GRPC_JSON_STATE_STRING_ESCAPE_U2:
409 case GRPC_JSON_STATE_STRING_ESCAPE_U3:
410 case GRPC_JSON_STATE_STRING_ESCAPE_U4:
411 if ((c >= '0') && (c <= '9')) {
412 c -= '0';
413 } else if ((c >= 'A') && (c <= 'F')) {
414 c -= 'A' - 10;
415 } else if ((c >= 'a') && (c <= 'f')) {
416 c -= 'a' - 10;
417 } else {
418 return GRPC_JSON_PARSE_ERROR;
419 }
Craig Tiller7536af02015-12-22 13:49:30 -0800420 reader->unicode_char = (uint16_t)(reader->unicode_char << 4);
421 reader->unicode_char = (uint16_t)(reader->unicode_char | c);
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800422
Craig Tillera82950e2015-09-22 12:33:20 -0700423 switch (reader->state) {
424 case GRPC_JSON_STATE_STRING_ESCAPE_U1:
425 reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U2;
426 break;
427 case GRPC_JSON_STATE_STRING_ESCAPE_U2:
428 reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U3;
429 break;
430 case GRPC_JSON_STATE_STRING_ESCAPE_U3:
431 reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U4;
432 break;
433 case GRPC_JSON_STATE_STRING_ESCAPE_U4:
434 /* See grpc_json_writer_escape_string to have a description
435 * of what's going on here.
436 */
437 if ((reader->unicode_char & 0xfc00) == 0xd800) {
438 /* high surrogate utf-16 */
439 if (reader->unicode_high_surrogate != 0)
440 return GRPC_JSON_PARSE_ERROR;
441 reader->unicode_high_surrogate = reader->unicode_char;
442 } else if ((reader->unicode_char & 0xfc00) == 0xdc00) {
443 /* low surrogate utf-16 */
Craig Tiller7536af02015-12-22 13:49:30 -0800444 uint32_t utf32;
Craig Tillera82950e2015-09-22 12:33:20 -0700445 if (reader->unicode_high_surrogate == 0)
446 return GRPC_JSON_PARSE_ERROR;
447 utf32 = 0x10000;
Craig Tiller7536af02015-12-22 13:49:30 -0800448 utf32 += (uint32_t)(
Craig Tillera82950e2015-09-22 12:33:20 -0700449 (reader->unicode_high_surrogate - 0xd800) * 0x400);
Craig Tiller7536af02015-12-22 13:49:30 -0800450 utf32 += (uint32_t)(reader->unicode_char - 0xdc00);
Craig Tillera82950e2015-09-22 12:33:20 -0700451 json_reader_string_add_utf32(reader, utf32);
452 reader->unicode_high_surrogate = 0;
453 } else {
454 /* anything else */
455 if (reader->unicode_high_surrogate != 0)
456 return GRPC_JSON_PARSE_ERROR;
457 json_reader_string_add_utf32(reader, reader->unicode_char);
458 }
459 if (reader->escaped_string_was_key) {
460 reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
461 } else {
462 reader->state = GRPC_JSON_STATE_VALUE_STRING;
463 }
464 break;
465 default:
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +0100466 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
Craig Tillera82950e2015-09-22 12:33:20 -0700467 }
468 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800469
Craig Tillera82950e2015-09-22 12:33:20 -0700470 case GRPC_JSON_STATE_VALUE_NUMBER:
471 json_reader_string_add_char(reader, c);
472 switch (c) {
473 case '0':
474 case '1':
475 case '2':
476 case '3':
477 case '4':
478 case '5':
479 case '6':
480 case '7':
481 case '8':
482 case '9':
483 break;
484 case 'e':
485 case 'E':
486 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_E;
487 break;
488 case '.':
489 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT;
490 break;
491 default:
492 return GRPC_JSON_PARSE_ERROR;
493 }
494 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800495
Craig Tillera82950e2015-09-22 12:33:20 -0700496 case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
497 json_reader_string_add_char(reader, c);
498 switch (c) {
499 case '0':
500 case '1':
501 case '2':
502 case '3':
503 case '4':
504 case '5':
505 case '6':
506 case '7':
507 case '8':
508 case '9':
509 break;
510 case 'e':
511 case 'E':
512 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_E;
513 break;
514 default:
515 return GRPC_JSON_PARSE_ERROR;
516 }
517 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800518
Craig Tillera82950e2015-09-22 12:33:20 -0700519 case GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
520 if (c != '.') return GRPC_JSON_PARSE_ERROR;
521 json_reader_string_add_char(reader, c);
522 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT;
523 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800524
Craig Tillera82950e2015-09-22 12:33:20 -0700525 case GRPC_JSON_STATE_VALUE_NUMBER_DOT:
526 json_reader_string_add_char(reader, c);
527 switch (c) {
528 case '0':
529 case '1':
530 case '2':
531 case '3':
532 case '4':
533 case '5':
534 case '6':
535 case '7':
536 case '8':
537 case '9':
538 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL;
539 break;
540 default:
541 return GRPC_JSON_PARSE_ERROR;
542 }
543 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800544
Craig Tillera82950e2015-09-22 12:33:20 -0700545 case GRPC_JSON_STATE_VALUE_NUMBER_E:
546 json_reader_string_add_char(reader, c);
547 switch (c) {
548 case '0':
549 case '1':
550 case '2':
551 case '3':
552 case '4':
553 case '5':
554 case '6':
555 case '7':
556 case '8':
557 case '9':
558 case '+':
559 case '-':
560 reader->state = GRPC_JSON_STATE_VALUE_NUMBER_EPM;
561 break;
562 default:
563 return GRPC_JSON_PARSE_ERROR;
564 }
565 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800566
Craig Tillera82950e2015-09-22 12:33:20 -0700567 case GRPC_JSON_STATE_VALUE_NUMBER_EPM:
568 json_reader_string_add_char(reader, c);
569 switch (c) {
570 case '0':
571 case '1':
572 case '2':
573 case '3':
574 case '4':
575 case '5':
576 case '6':
577 case '7':
578 case '8':
579 case '9':
580 break;
581 default:
582 return GRPC_JSON_PARSE_ERROR;
583 }
584 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800585
Craig Tillera82950e2015-09-22 12:33:20 -0700586 case GRPC_JSON_STATE_VALUE_TRUE_R:
587 if (c != 'r') return GRPC_JSON_PARSE_ERROR;
588 reader->state = GRPC_JSON_STATE_VALUE_TRUE_U;
589 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800590
Craig Tillera82950e2015-09-22 12:33:20 -0700591 case GRPC_JSON_STATE_VALUE_TRUE_U:
592 if (c != 'u') return GRPC_JSON_PARSE_ERROR;
593 reader->state = GRPC_JSON_STATE_VALUE_TRUE_E;
594 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800595
Craig Tillera82950e2015-09-22 12:33:20 -0700596 case GRPC_JSON_STATE_VALUE_TRUE_E:
597 if (c != 'e') return GRPC_JSON_PARSE_ERROR;
598 json_reader_set_true(reader);
599 reader->state = GRPC_JSON_STATE_VALUE_END;
600 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800601
Craig Tillera82950e2015-09-22 12:33:20 -0700602 case GRPC_JSON_STATE_VALUE_FALSE_A:
603 if (c != 'a') return GRPC_JSON_PARSE_ERROR;
604 reader->state = GRPC_JSON_STATE_VALUE_FALSE_L;
605 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800606
Craig Tillera82950e2015-09-22 12:33:20 -0700607 case GRPC_JSON_STATE_VALUE_FALSE_L:
608 if (c != 'l') return GRPC_JSON_PARSE_ERROR;
609 reader->state = GRPC_JSON_STATE_VALUE_FALSE_S;
610 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800611
Craig Tillera82950e2015-09-22 12:33:20 -0700612 case GRPC_JSON_STATE_VALUE_FALSE_S:
613 if (c != 's') return GRPC_JSON_PARSE_ERROR;
614 reader->state = GRPC_JSON_STATE_VALUE_FALSE_E;
615 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800616
Craig Tillera82950e2015-09-22 12:33:20 -0700617 case GRPC_JSON_STATE_VALUE_FALSE_E:
618 if (c != 'e') return GRPC_JSON_PARSE_ERROR;
619 json_reader_set_false(reader);
620 reader->state = GRPC_JSON_STATE_VALUE_END;
621 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800622
Craig Tillera82950e2015-09-22 12:33:20 -0700623 case GRPC_JSON_STATE_VALUE_NULL_U:
624 if (c != 'u') return GRPC_JSON_PARSE_ERROR;
625 reader->state = GRPC_JSON_STATE_VALUE_NULL_L1;
626 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800627
Craig Tillera82950e2015-09-22 12:33:20 -0700628 case GRPC_JSON_STATE_VALUE_NULL_L1:
629 if (c != 'l') return GRPC_JSON_PARSE_ERROR;
630 reader->state = GRPC_JSON_STATE_VALUE_NULL_L2;
631 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800632
Craig Tillera82950e2015-09-22 12:33:20 -0700633 case GRPC_JSON_STATE_VALUE_NULL_L2:
634 if (c != 'l') return GRPC_JSON_PARSE_ERROR;
635 json_reader_set_null(reader);
636 reader->state = GRPC_JSON_STATE_VALUE_END;
637 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800638
Craig Tillera82950e2015-09-22 12:33:20 -0700639 /* All of the VALUE_END cases are handled in the specialized case
640 * above. */
641 case GRPC_JSON_STATE_VALUE_END:
642 switch (c) {
643 case ',':
644 case '}':
645 case ']':
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +0100646 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
Craig Tillera82950e2015-09-22 12:33:20 -0700647 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800648
Craig Tillera82950e2015-09-22 12:33:20 -0700649 default:
650 return GRPC_JSON_PARSE_ERROR;
651 }
652 break;
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800653
Craig Tillera82950e2015-09-22 12:33:20 -0700654 case GRPC_JSON_STATE_END:
655 return GRPC_JSON_PARSE_ERROR;
656 }
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800657 }
Craig Tillera82950e2015-09-22 12:33:20 -0700658 }
Nicolas Noble614c2bf2015-01-21 15:48:36 -0800659
Nicolas "Pixel" Noble11c320d2015-12-12 01:47:36 +0100660 GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
Craig Tiller190d3602015-02-18 09:23:38 -0800661}