• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * $Id: json_tokener.c,v 1.20 2006/07/25 03:24:50 mclark Exp $
3  *
4  * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
5  * Michael Clark <michael@metaparadigm.com>
6  *
7  * This library is free software; you can redistribute it and/or modify
8  * it under the terms of the MIT license. See COPYING for details.
9  *
10  *
11  * Copyright (c) 2008-2009 Yahoo! Inc.  All rights reserved.
12  * The copyrights to the contents of this file are licensed under the MIT License
13  * (http://www.opensource.org/licenses/mit-license.php)
14  */
15 
16 #include "config.h"
17 
18 #include <math.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <stddef.h>
22 #include <ctype.h>
23 #include <string.h>
24 #include <limits.h>
25 
26 #include "debug.h"
27 #include "printbuf.h"
28 #include "arraylist.h"
29 #include "json_inttypes.h"
30 #include "json_object.h"
31 #include "json_tokener.h"
32 #include "json_util.h"
33 
34 #ifdef HAVE_LOCALE_H
35 #include <locale.h>
36 #endif /* HAVE_LOCALE_H */
37 
38 #define jt_hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x) & 7) + 9)
39 
40 #if !HAVE_STRDUP && defined(_MSC_VER)
41   /* MSC has the version as _strdup */
42 # define strdup _strdup
43 #elif !HAVE_STRDUP
44 # error You do not have strdup on your system.
45 #endif /* HAVE_STRDUP */
46 
47 #if !HAVE_STRNCASECMP && defined(_MSC_VER)
48   /* MSC has the version as _strnicmp */
49 # define strncasecmp _strnicmp
50 #elif !HAVE_STRNCASECMP
51 # error You do not have strncasecmp on your system.
52 #endif /* HAVE_STRNCASECMP */
53 
54 /* Use C99 NAN by default; if not available, nan("") should work too. */
55 #ifndef NAN
56 #define NAN nan("")
57 #endif /* !NAN */
58 
59 static const char json_null_str[] = "null";
60 static const int json_null_str_len = sizeof(json_null_str) - 1;
61 static const char json_inf_str[] = "Infinity";
62 static const int json_inf_str_len = sizeof(json_inf_str) - 1;
63 static const char json_nan_str[] = "NaN";
64 static const int json_nan_str_len = sizeof(json_nan_str) - 1;
65 static const char json_true_str[] = "true";
66 static const int json_true_str_len = sizeof(json_true_str) - 1;
67 static const char json_false_str[] = "false";
68 static const int json_false_str_len = sizeof(json_false_str) - 1;
69 
70 static const char* json_tokener_errors[] = {
71   "success",
72   "continue",
73   "nesting too deep",
74   "unexpected end of data",
75   "unexpected character",
76   "null expected",
77   "boolean expected",
78   "number expected",
79   "array value separator ',' expected",
80   "quoted object property name expected",
81   "object property name separator ':' expected",
82   "object value separator ',' expected",
83   "invalid string sequence",
84   "expected comment",
85   "buffer size overflow"
86 };
87 
json_tokener_error_desc(enum json_tokener_error jerr)88 const char *json_tokener_error_desc(enum json_tokener_error jerr)
89 {
90 	int jerr_int = (int)jerr;
91 	if (jerr_int < 0 || jerr_int >= (int)(sizeof(json_tokener_errors) / sizeof(json_tokener_errors[0])))
92 		return "Unknown error, invalid json_tokener_error value passed to json_tokener_error_desc()";
93 	return json_tokener_errors[jerr];
94 }
95 
json_tokener_get_error(json_tokener * tok)96 enum json_tokener_error json_tokener_get_error(json_tokener *tok)
97 {
98 	return tok->err;
99 }
100 
101 /* Stuff for decoding unicode sequences */
102 #define IS_HIGH_SURROGATE(uc) (((uc) & 0xFC00) == 0xD800)
103 #define IS_LOW_SURROGATE(uc)  (((uc) & 0xFC00) == 0xDC00)
104 #define DECODE_SURROGATE_PAIR(hi,lo) ((((hi) & 0x3FF) << 10) + ((lo) & 0x3FF) + 0x10000)
105 static unsigned char utf8_replacement_char[3] = { 0xEF, 0xBF, 0xBD };
106 
json_tokener_new_ex(int depth)107 struct json_tokener* json_tokener_new_ex(int depth)
108 {
109   struct json_tokener *tok;
110 
111   tok = (struct json_tokener*)calloc(1, sizeof(struct json_tokener));
112   if (!tok) return NULL;
113   tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
114   if (!tok->stack) {
115     free(tok);
116     return NULL;
117   }
118   tok->pb = printbuf_new();
119   tok->max_depth = depth;
120   json_tokener_reset(tok);
121   return tok;
122 }
123 
json_tokener_new(void)124 struct json_tokener* json_tokener_new(void)
125 {
126   return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
127 }
128 
json_tokener_free(struct json_tokener * tok)129 void json_tokener_free(struct json_tokener *tok)
130 {
131   json_tokener_reset(tok);
132   if (tok->pb) printbuf_free(tok->pb);
133   if (tok->stack) free(tok->stack);
134   free(tok);
135 }
136 
json_tokener_reset_level(struct json_tokener * tok,int depth)137 static void json_tokener_reset_level(struct json_tokener *tok, int depth)
138 {
139   tok->stack[depth].state = json_tokener_state_eatws;
140   tok->stack[depth].saved_state = json_tokener_state_start;
141   json_object_put(tok->stack[depth].current);
142   tok->stack[depth].current = NULL;
143   free(tok->stack[depth].obj_field_name);
144   tok->stack[depth].obj_field_name = NULL;
145 }
146 
json_tokener_reset(struct json_tokener * tok)147 void json_tokener_reset(struct json_tokener *tok)
148 {
149   int i;
150   if (!tok)
151     return;
152 
153   for(i = tok->depth; i >= 0; i--)
154     json_tokener_reset_level(tok, i);
155   tok->depth = 0;
156   tok->err = json_tokener_success;
157 }
158 
json_tokener_parse(const char * str)159 struct json_object* json_tokener_parse(const char *str)
160 {
161     enum json_tokener_error jerr_ignored;
162     struct json_object* obj;
163     obj = json_tokener_parse_verbose(str, &jerr_ignored);
164     return obj;
165 }
166 
json_tokener_parse_verbose(const char * str,enum json_tokener_error * error)167 struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
168 {
169     struct json_tokener* tok;
170     struct json_object* obj;
171 
172     tok = json_tokener_new();
173     if (!tok)
174       return NULL;
175     obj = json_tokener_parse_ex(tok, str, -1);
176     *error = tok->err;
177     if(tok->err != json_tokener_success) {
178 		if (obj != NULL)
179 			json_object_put(obj);
180         obj = NULL;
181     }
182 
183     json_tokener_free(tok);
184     return obj;
185 }
186 
187 #define state  tok->stack[tok->depth].state
188 #define saved_state  tok->stack[tok->depth].saved_state
189 #define current tok->stack[tok->depth].current
190 #define obj_field_name tok->stack[tok->depth].obj_field_name
191 
192 /* Optimization:
193  * json_tokener_parse_ex() consumed a lot of CPU in its main loop,
194  * iterating character-by character.  A large performance boost is
195  * achieved by using tighter loops to locally handle units such as
196  * comments and strings.  Loops that handle an entire token within
197  * their scope also gather entire strings and pass them to
198  * printbuf_memappend() in a single call, rather than calling
199  * printbuf_memappend() one char at a time.
200  *
201  * PEEK_CHAR() and ADVANCE_CHAR() macros are used for code that is
202  * common to both the main loop and the tighter loops.
203  */
204 
205 /* PEEK_CHAR(dest, tok) macro:
206  *   Peeks at the current char and stores it in dest.
207  *   Returns 1 on success, sets tok->err and returns 0 if no more chars.
208  *   Implicit inputs:  str, len vars
209  */
210 #define PEEK_CHAR(dest, tok)                                                  \
211   (((tok)->char_offset == len) ?                                          \
212    (((tok)->depth == 0 && state == json_tokener_state_eatws && saved_state == json_tokener_state_finish) ? \
213     (((tok)->err = json_tokener_success), 0)                              \
214     :                                                                   \
215     (((tok)->err = json_tokener_continue), 0)                             \
216     ) :                                                                 \
217    (((dest) = *str), 1)                                                 \
218    )
219 
220 /* ADVANCE_CHAR() macro:
221  *   Incrementes str & tok->char_offset.
222  *   For convenience of existing conditionals, returns the old value of c (0 on eof)
223  *   Implicit inputs:  c var
224  */
225 #define ADVANCE_CHAR(str, tok) \
226   ( ++(str), ((tok)->char_offset)++, c)
227 
228 
229 /* End optimization macro defs */
230 
231 
json_tokener_parse_ex(struct json_tokener * tok,const char * str,int len)232 struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
233 					  const char *str, int len)
234 {
235   struct json_object *obj = NULL;
236   char c = '\1';
237 #ifdef HAVE_SETLOCALE
238   char *oldlocale=NULL, *tmplocale;
239 
240   tmplocale = setlocale(LC_NUMERIC, NULL);
241   if (tmplocale) oldlocale = strdup(tmplocale);
242   setlocale(LC_NUMERIC, "C");
243 #endif
244 
245   tok->char_offset = 0;
246   tok->err = json_tokener_success;
247 
248   /* this interface is presently not 64-bit clean due to the int len argument
249      and the internal printbuf interface that takes 32-bit int len arguments
250      so the function limits the maximum string size to INT32_MAX (2GB).
251      If the function is called with len == -1 then strlen is called to check
252      the string length is less than INT32_MAX (2GB) */
253   if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX)) {
254     tok->err = json_tokener_error_size;
255     return NULL;
256   }
257 
258   while (PEEK_CHAR(c, tok)) {
259 
260   redo_char:
261     switch(state) {
262 
263     case json_tokener_state_eatws:
264       /* Advance until we change state */
265       while (isspace((int)c)) {
266 	if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
267 	  goto out;
268       }
269       if(c == '/' && !(tok->flags & JSON_TOKENER_STRICT)) {
270 	printbuf_reset(tok->pb);
271 	printbuf_memappend_fast(tok->pb, &c, 1);
272 	state = json_tokener_state_comment_start;
273       } else {
274 	state = saved_state;
275 	goto redo_char;
276       }
277       break;
278 
279     case json_tokener_state_start:
280       switch(c) {
281       case '{':
282 	state = json_tokener_state_eatws;
283 	saved_state = json_tokener_state_object_field_start;
284 	current = json_object_new_object();
285 	break;
286       case '[':
287 	state = json_tokener_state_eatws;
288 	saved_state = json_tokener_state_array;
289 	current = json_object_new_array();
290 	break;
291       case 'I':
292       case 'i':
293 	state = json_tokener_state_inf;
294 	printbuf_reset(tok->pb);
295 	tok->st_pos = 0;
296 	goto redo_char;
297       case 'N':
298       case 'n':
299 	state = json_tokener_state_null; // or NaN
300 	printbuf_reset(tok->pb);
301 	tok->st_pos = 0;
302 	goto redo_char;
303       case '\'':
304         if (tok->flags & JSON_TOKENER_STRICT) {
305             /* in STRICT mode only double-quote are allowed */
306             tok->err = json_tokener_error_parse_unexpected;
307             goto out;
308         }
309       case '"':
310 	state = json_tokener_state_string;
311 	printbuf_reset(tok->pb);
312 	tok->quote_char = c;
313 	break;
314       case 'T':
315       case 't':
316       case 'F':
317       case 'f':
318 	state = json_tokener_state_boolean;
319 	printbuf_reset(tok->pb);
320 	tok->st_pos = 0;
321 	goto redo_char;
322 #if defined(__GNUC__)
323 	  case '0' ... '9':
324 #else
325 	  case '0':
326       case '1':
327       case '2':
328       case '3':
329       case '4':
330       case '5':
331       case '6':
332       case '7':
333       case '8':
334       case '9':
335 #endif
336       case '-':
337 	state = json_tokener_state_number;
338 	printbuf_reset(tok->pb);
339 	tok->is_double = 0;
340 	goto redo_char;
341       default:
342 	tok->err = json_tokener_error_parse_unexpected;
343 	goto out;
344       }
345       break;
346 
347     case json_tokener_state_finish:
348       if(tok->depth == 0) goto out;
349       obj = json_object_get(current);
350       json_tokener_reset_level(tok, tok->depth);
351       tok->depth--;
352       goto redo_char;
353 
354     case json_tokener_state_inf: /* aka starts with 'i' */
355       {
356 	int size_inf;
357 	int is_negative = 0;
358 
359 	printbuf_memappend_fast(tok->pb, &c, 1);
360 	size_inf = json_min(tok->st_pos+1, json_inf_str_len);
361 	char *infbuf = tok->pb->buf;
362 	if (*infbuf == '-')
363 	{
364 		infbuf++;
365 		is_negative = 1;
366 	}
367 	if ((!(tok->flags & JSON_TOKENER_STRICT) &&
368 	          strncasecmp(json_inf_str, infbuf, size_inf) == 0) ||
369 	         (strncmp(json_inf_str, infbuf, size_inf) == 0)
370 	        )
371 	{
372 		if (tok->st_pos == json_inf_str_len)
373 		{
374 			current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
375 			saved_state = json_tokener_state_finish;
376 			state = json_tokener_state_eatws;
377 			goto redo_char;
378 		}
379 	} else {
380 		tok->err = json_tokener_error_parse_unexpected;
381 		goto out;
382 	}
383 	tok->st_pos++;
384       }
385       break;
386     case json_tokener_state_null: /* aka starts with 'n' */
387       {
388 	int size;
389 	int size_nan;
390 	printbuf_memappend_fast(tok->pb, &c, 1);
391 	size = json_min(tok->st_pos+1, json_null_str_len);
392 	size_nan = json_min(tok->st_pos+1, json_nan_str_len);
393 	if((!(tok->flags & JSON_TOKENER_STRICT) &&
394 	  strncasecmp(json_null_str, tok->pb->buf, size) == 0)
395 	  || (strncmp(json_null_str, tok->pb->buf, size) == 0)
396 	  ) {
397 	  if (tok->st_pos == json_null_str_len) {
398 	    current = NULL;
399 	    saved_state = json_tokener_state_finish;
400 	    state = json_tokener_state_eatws;
401 	    goto redo_char;
402 	  }
403 	}
404 	else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
405 	          strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
406 	         (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0)
407 	        )
408 	{
409 		if (tok->st_pos == json_nan_str_len)
410 		{
411 			current = json_object_new_double(NAN);
412 			saved_state = json_tokener_state_finish;
413 			state = json_tokener_state_eatws;
414 			goto redo_char;
415 		}
416 	} else {
417 	  tok->err = json_tokener_error_parse_null;
418 	  goto out;
419 	}
420 	tok->st_pos++;
421       }
422       break;
423 
424     case json_tokener_state_comment_start:
425       if(c == '*') {
426 	state = json_tokener_state_comment;
427       } else if(c == '/') {
428 	state = json_tokener_state_comment_eol;
429       } else {
430 	tok->err = json_tokener_error_parse_comment;
431 	goto out;
432       }
433       printbuf_memappend_fast(tok->pb, &c, 1);
434       break;
435 
436     case json_tokener_state_comment:
437               {
438           /* Advance until we change state */
439           const char *case_start = str;
440           while(c != '*') {
441             if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
442               printbuf_memappend_fast(tok->pb, case_start, str-case_start);
443               goto out;
444             }
445           }
446           printbuf_memappend_fast(tok->pb, case_start, 1+str-case_start);
447           state = json_tokener_state_comment_end;
448         }
449             break;
450 
451     case json_tokener_state_comment_eol:
452       {
453 	/* Advance until we change state */
454 	const char *case_start = str;
455 	while(c != '\n') {
456 	  if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
457 	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
458 	    goto out;
459 	  }
460 	}
461 	printbuf_memappend_fast(tok->pb, case_start, str-case_start);
462 	MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
463 	state = json_tokener_state_eatws;
464       }
465       break;
466 
467     case json_tokener_state_comment_end:
468       printbuf_memappend_fast(tok->pb, &c, 1);
469       if(c == '/') {
470 	MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
471 	state = json_tokener_state_eatws;
472       } else {
473 	state = json_tokener_state_comment;
474       }
475       break;
476 
477     case json_tokener_state_string:
478       {
479 	/* Advance until we change state */
480 	const char *case_start = str;
481 	while(1) {
482 	  if(c == tok->quote_char) {
483 	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
484 	    current = json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
485 	    saved_state = json_tokener_state_finish;
486 	    state = json_tokener_state_eatws;
487 	    break;
488 	  } else if(c == '\\') {
489 	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
490 	    saved_state = json_tokener_state_string;
491 	    state = json_tokener_state_string_escape;
492 	    break;
493 	  }
494 	  if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
495 	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
496 	    goto out;
497 	  }
498 	}
499       }
500       break;
501 
502     case json_tokener_state_string_escape:
503       switch(c) {
504       case '"':
505       case '\\':
506       case '/':
507 	printbuf_memappend_fast(tok->pb, &c, 1);
508 	state = saved_state;
509 	break;
510       case 'b':
511       case 'n':
512       case 'r':
513       case 't':
514       case 'f':
515 	if(c == 'b') printbuf_memappend_fast(tok->pb, "\b", 1);
516 	else if(c == 'n') printbuf_memappend_fast(tok->pb, "\n", 1);
517 	else if(c == 'r') printbuf_memappend_fast(tok->pb, "\r", 1);
518 	else if(c == 't') printbuf_memappend_fast(tok->pb, "\t", 1);
519 	else if(c == 'f') printbuf_memappend_fast(tok->pb, "\f", 1);
520 	state = saved_state;
521 	break;
522       case 'u':
523 	tok->ucs_char = 0;
524 	tok->st_pos = 0;
525 	state = json_tokener_state_escape_unicode;
526 	break;
527       default:
528 	tok->err = json_tokener_error_parse_string;
529 	goto out;
530       }
531       break;
532 
533     case json_tokener_state_escape_unicode:
534 	{
535           unsigned int got_hi_surrogate = 0;
536 
537 	  /* Handle a 4-byte sequence, or two sequences if a surrogate pair */
538 	  while(1) {
539 	    if(strchr(json_hex_chars, c)) {
540 	      tok->ucs_char += ((unsigned int)jt_hexdigit(c) << ((3-tok->st_pos++)*4));
541 	      if(tok->st_pos == 4) {
542 		unsigned char unescaped_utf[4];
543 
544                 if (got_hi_surrogate) {
545 		  if (IS_LOW_SURROGATE(tok->ucs_char)) {
546                     /* Recalculate the ucs_char, then fall thru to process normally */
547                     tok->ucs_char = DECODE_SURROGATE_PAIR(got_hi_surrogate, tok->ucs_char);
548                   } else {
549                     /* Hi surrogate was not followed by a low surrogate */
550                     /* Replace the hi and process the rest normally */
551 		    printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
552                   }
553                   got_hi_surrogate = 0;
554                 }
555 
556 		if (tok->ucs_char < 0x80) {
557 		  unescaped_utf[0] = tok->ucs_char;
558 		  printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 1);
559 		} else if (tok->ucs_char < 0x800) {
560 		  unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
561 		  unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
562 		  printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 2);
563 		} else if (IS_HIGH_SURROGATE(tok->ucs_char)) {
564                   /* Got a high surrogate.  Remember it and look for the
565                    * the beginning of another sequence, which should be the
566                    * low surrogate.
567                    */
568                   got_hi_surrogate = tok->ucs_char;
569                   /* Not at end, and the next two chars should be "\u" */
570                   if ((tok->char_offset+1 != len) &&
571                       (tok->char_offset+2 != len) &&
572                       (str[1] == '\\') &&
573                       (str[2] == 'u'))
574                   {
575                 /* Advance through the 16 bit surrogate, and move on to the
576                  * next sequence. The next step is to process the following
577                  * characters.
578                  */
579 	            if( !ADVANCE_CHAR(str, tok) || !ADVANCE_CHAR(str, tok) ) {
580                     printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
581                 }
582                     /* Advance to the first char of the next sequence and
583                      * continue processing with the next sequence.
584                      */
585 	            if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
586 	              printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
587 	              goto out;
588                     }
589 	            tok->ucs_char = 0;
590                     tok->st_pos = 0;
591                     continue; /* other json_tokener_state_escape_unicode */
592                   } else {
593                     /* Got a high surrogate without another sequence following
594                      * it.  Put a replacement char in for the hi surrogate
595                      * and pretend we finished.
596                      */
597 		    printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
598                   }
599 		} else if (IS_LOW_SURROGATE(tok->ucs_char)) {
600                   /* Got a low surrogate not preceded by a high */
601 		  printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
602                 } else if (tok->ucs_char < 0x10000) {
603 		  unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
604 		  unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
605 		  unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
606 		  printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 3);
607 		} else if (tok->ucs_char < 0x110000) {
608 		  unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
609 		  unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
610 		  unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
611 		  unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
612 		  printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 4);
613 		} else {
614                   /* Don't know what we got--insert the replacement char */
615 		  printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
616                 }
617 		state = saved_state;
618 		break;
619 	      }
620 	    } else {
621 	      tok->err = json_tokener_error_parse_string;
622 	      goto out;
623 	    }
624 	  if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
625             if (got_hi_surrogate) /* Clean up any pending chars */
626 	      printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
627 	    goto out;
628 	  }
629 	}
630       }
631       break;
632 
633     case json_tokener_state_boolean:
634       {
635 	int size1, size2;
636 	printbuf_memappend_fast(tok->pb, &c, 1);
637 	size1 = json_min(tok->st_pos+1, json_true_str_len);
638 	size2 = json_min(tok->st_pos+1, json_false_str_len);
639 	if((!(tok->flags & JSON_TOKENER_STRICT) &&
640 	  strncasecmp(json_true_str, tok->pb->buf, size1) == 0)
641 	  || (strncmp(json_true_str, tok->pb->buf, size1) == 0)
642 	  ) {
643 	  if(tok->st_pos == json_true_str_len) {
644 	    current = json_object_new_boolean(1);
645 	    saved_state = json_tokener_state_finish;
646 	    state = json_tokener_state_eatws;
647 	    goto redo_char;
648 	  }
649 	} else if((!(tok->flags & JSON_TOKENER_STRICT) &&
650 	  strncasecmp(json_false_str, tok->pb->buf, size2) == 0)
651 	  || (strncmp(json_false_str, tok->pb->buf, size2) == 0)) {
652 	  if(tok->st_pos == json_false_str_len) {
653 	    current = json_object_new_boolean(0);
654 	    saved_state = json_tokener_state_finish;
655 	    state = json_tokener_state_eatws;
656 	    goto redo_char;
657 	  }
658 	} else {
659 	  tok->err = json_tokener_error_parse_boolean;
660 	  goto out;
661 	}
662 	tok->st_pos++;
663       }
664       break;
665 
666     case json_tokener_state_number:
667       {
668 	/* Advance until we change state */
669 	const char *case_start = str;
670 	int case_len=0;
671 	while(c && strchr(json_number_chars, c)) {
672 	  ++case_len;
673 	  if(c == '.' || c == 'e' || c == 'E')
674 	    tok->is_double = 1;
675 	  if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
676 	    printbuf_memappend_fast(tok->pb, case_start, case_len);
677 	    goto out;
678 	  }
679 	}
680         if (case_len>0)
681           printbuf_memappend_fast(tok->pb, case_start, case_len);
682 
683 	// Check for -Infinity
684 	if (tok->pb->buf[0] == '-' && case_len == 1 &&
685 	    (c == 'i' || c == 'I'))
686 	{
687 		state = json_tokener_state_inf;
688 		goto redo_char;
689 	}
690       }
691       {
692 	int64_t num64;
693 	double  numd;
694 	if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) {
695 		if (num64 && tok->pb->buf[0]=='0' && (tok->flags & JSON_TOKENER_STRICT)) {
696 			/* in strict mode, number must not start with 0 */
697 			tok->err = json_tokener_error_parse_number;
698 			goto out;
699 		}
700 		current = json_object_new_int64(num64);
701 	}
702 	else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0)
703 	{
704           current = json_object_new_double_s(numd, tok->pb->buf);
705         } else {
706           tok->err = json_tokener_error_parse_number;
707           goto out;
708         }
709         saved_state = json_tokener_state_finish;
710         state = json_tokener_state_eatws;
711         goto redo_char;
712       }
713       break;
714 
715     case json_tokener_state_array_after_sep:
716     case json_tokener_state_array:
717       if(c == ']') {
718 		if (state == json_tokener_state_array_after_sep &&
719 			(tok->flags & JSON_TOKENER_STRICT))
720 		{
721 			tok->err = json_tokener_error_parse_unexpected;
722 			goto out;
723 		}
724 	saved_state = json_tokener_state_finish;
725 	state = json_tokener_state_eatws;
726       } else {
727 	if(tok->depth >= tok->max_depth-1) {
728 	  tok->err = json_tokener_error_depth;
729 	  goto out;
730 	}
731 	state = json_tokener_state_array_add;
732 	tok->depth++;
733 	json_tokener_reset_level(tok, tok->depth);
734 	goto redo_char;
735       }
736       break;
737 
738     case json_tokener_state_array_add:
739       json_object_array_add(current, obj);
740       saved_state = json_tokener_state_array_sep;
741       state = json_tokener_state_eatws;
742       goto redo_char;
743 
744     case json_tokener_state_array_sep:
745       if(c == ']') {
746 	saved_state = json_tokener_state_finish;
747 	state = json_tokener_state_eatws;
748       } else if(c == ',') {
749 	saved_state = json_tokener_state_array_after_sep;
750 	state = json_tokener_state_eatws;
751       } else {
752 	tok->err = json_tokener_error_parse_array;
753 	goto out;
754       }
755       break;
756 
757     case json_tokener_state_object_field_start:
758     case json_tokener_state_object_field_start_after_sep:
759       if(c == '}') {
760 		if (state == json_tokener_state_object_field_start_after_sep &&
761 		    (tok->flags & JSON_TOKENER_STRICT))
762 		{
763 			tok->err = json_tokener_error_parse_unexpected;
764 			goto out;
765 		}
766 	saved_state = json_tokener_state_finish;
767 	state = json_tokener_state_eatws;
768       } else if (c == '"' || c == '\'') {
769 	tok->quote_char = c;
770 	printbuf_reset(tok->pb);
771 	state = json_tokener_state_object_field;
772       } else {
773 	tok->err = json_tokener_error_parse_object_key_name;
774 	goto out;
775       }
776       break;
777 
778     case json_tokener_state_object_field:
779       {
780 	/* Advance until we change state */
781 	const char *case_start = str;
782 	while(1) {
783 	  if(c == tok->quote_char) {
784 	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
785 	    obj_field_name = strdup(tok->pb->buf);
786 	    saved_state = json_tokener_state_object_field_end;
787 	    state = json_tokener_state_eatws;
788 	    break;
789 	  } else if(c == '\\') {
790 	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
791 	    saved_state = json_tokener_state_object_field;
792 	    state = json_tokener_state_string_escape;
793 	    break;
794 	  }
795 	  if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
796 	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
797 	    goto out;
798 	  }
799 	}
800       }
801       break;
802 
803     case json_tokener_state_object_field_end:
804       if(c == ':') {
805 	saved_state = json_tokener_state_object_value;
806 	state = json_tokener_state_eatws;
807       } else {
808 	tok->err = json_tokener_error_parse_object_key_sep;
809 	goto out;
810       }
811       break;
812 
813     case json_tokener_state_object_value:
814       if(tok->depth >= tok->max_depth-1) {
815 	tok->err = json_tokener_error_depth;
816 	goto out;
817       }
818       state = json_tokener_state_object_value_add;
819       tok->depth++;
820       json_tokener_reset_level(tok, tok->depth);
821       goto redo_char;
822 
823     case json_tokener_state_object_value_add:
824       json_object_object_add(current, obj_field_name, obj);
825       free(obj_field_name);
826       obj_field_name = NULL;
827       saved_state = json_tokener_state_object_sep;
828       state = json_tokener_state_eatws;
829       goto redo_char;
830 
831     case json_tokener_state_object_sep:
832       if(c == '}') {
833 	saved_state = json_tokener_state_finish;
834 	state = json_tokener_state_eatws;
835       } else if(c == ',') {
836 	saved_state = json_tokener_state_object_field_start_after_sep;
837 	state = json_tokener_state_eatws;
838       } else {
839 	tok->err = json_tokener_error_parse_object_value_sep;
840 	goto out;
841       }
842       break;
843 
844     }
845     if (!ADVANCE_CHAR(str, tok))
846       goto out;
847   } /* while(POP_CHAR) */
848 
849  out:
850   if (c &&
851      (state == json_tokener_state_finish) &&
852      (tok->depth == 0) &&
853      (tok->flags & JSON_TOKENER_STRICT)) {
854       /* unexpected char after JSON data */
855       tok->err = json_tokener_error_parse_unexpected;
856   }
857   if (!c) { /* We hit an eof char (0) */
858     if(state != json_tokener_state_finish &&
859        saved_state != json_tokener_state_finish)
860       tok->err = json_tokener_error_parse_eof;
861   }
862 
863 #ifdef HAVE_SETLOCALE
864   setlocale(LC_NUMERIC, oldlocale);
865   if (oldlocale) free(oldlocale);
866 #endif
867 
868   if (tok->err == json_tokener_success)
869   {
870     json_object *ret = json_object_get(current);
871 	int ii;
872 
873 	/* Partially reset, so we parse additional objects on subsequent calls. */
874     for(ii = tok->depth; ii >= 0; ii--)
875       json_tokener_reset_level(tok, ii);
876     return ret;
877   }
878 
879   MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n",
880 	   json_tokener_errors[tok->err], tok->char_offset);
881   return NULL;
882 }
883 
json_tokener_set_flags(struct json_tokener * tok,int flags)884 void json_tokener_set_flags(struct json_tokener *tok, int flags)
885 {
886 	tok->flags = flags;
887 }
888