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