blob: 19de8efc7a42a4b721535d7d0f4649a562e58a35 [file] [log] [blame]
Michael Clarkf0d08882007-03-13 08:26:18 +00001/*
Michael Clarka850f8e2007-03-13 08:26:26 +00002 * $Id: json_tokener.c,v 1.20 2006/07/25 03:24:50 mclark Exp $
Michael Clarkf0d08882007-03-13 08:26:18 +00003 *
Michael Clarkf6a6e482007-03-13 08:26:23 +00004 * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
Michael Clarkf0d08882007-03-13 08:26:18 +00005 * Michael Clark <michael@metaparadigm.com>
6 *
Michael Clarkf6a6e482007-03-13 08:26:23 +00007 * 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.
Michael Clarkf0d08882007-03-13 08:26:18 +00009 *
Michael Clark95f55a72009-04-27 08:16:58 +000010 *
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)
Michael Clarkf0d08882007-03-13 08:26:18 +000014 */
15
Michael Clark4504df72007-03-13 08:26:20 +000016#include "config.h"
17
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -040018#include <math.h>
Michael Clarkf0d08882007-03-13 08:26:18 +000019#include <stdio.h>
20#include <stdlib.h>
Michael Clarkc8f4a6e2007-12-07 02:44:24 +000021#include <stddef.h>
Michael Clarkf0d08882007-03-13 08:26:18 +000022#include <ctype.h>
23#include <string.h>
Michael Clarkc4dceae2010-10-06 16:39:20 +000024#include <limits.h>
Michael Clarkf0d08882007-03-13 08:26:18 +000025
26#include "bits.h"
27#include "debug.h"
28#include "printbuf.h"
29#include "arraylist.h"
Michael Clarkc4dceae2010-10-06 16:39:20 +000030#include "json_inttypes.h"
Michael Clarkf0d08882007-03-13 08:26:18 +000031#include "json_object.h"
32#include "json_tokener.h"
Michael Clarkc4dceae2010-10-06 16:39:20 +000033#include "json_util.h"
Michael Clarka850f8e2007-03-13 08:26:26 +000034
Remi Colleta01b6592012-12-13 09:47:33 +010035#ifdef HAVE_LOCALE_H
36#include <locale.h>
37#endif /* HAVE_LOCALE_H */
38
Mateusz Loskota6f39a32012-05-21 23:22:36 +010039#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
Michael Clark837240f2007-03-13 08:26:25 +000046#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
Markus Stenberga1c89912014-03-18 16:29:49 +020053/* Use C99 NAN by default; if not available, nan("") should work too. */
54#ifndef NAN
55#define NAN nan("")
56#endif /* !NAN */
57
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -040058static const char json_null_str[] = "null";
59static const int json_null_str_len = sizeof(json_null_str) - 1;
Eric Haszlakiewicz05da3162014-03-22 17:28:40 -040060static const char json_inf_str[] = "Infinity";
61static const int json_inf_str_len = sizeof(json_inf_str) - 1;
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -040062static 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;
Michael Clarkf0d08882007-03-13 08:26:18 +000068
Eric Haszlakiewiczf9136f62014-03-22 21:41:24 -040069static const char* json_tokener_errors[] = {
Michael Clarka850f8e2007-03-13 08:26:26 +000070 "success",
71 "continue",
Eric Haszlakiewicz3620cba2012-03-31 12:52:59 -050072 "nesting too deep",
Michael Clarka850f8e2007-03-13 08:26:26 +000073 "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",
Michael Clark64e36902014-04-09 13:48:21 +080084 "buffer size overflow"
Michael Clarka850f8e2007-03-13 08:26:26 +000085};
86
Eric Haszlakiewicz2f9091f2012-02-22 08:24:40 -060087const char *json_tokener_error_desc(enum json_tokener_error jerr)
88{
Eric Haszlakiewiczca8b27d2013-02-09 16:35:24 -060089 int jerr_int = (int)jerr;
Eric Haszlakiewicz56df93d2014-02-11 23:16:53 -050090 if (jerr_int < 0 || jerr_int >= (int)(sizeof(json_tokener_errors) / sizeof(json_tokener_errors[0])))
Eric Haszlakiewicz2f9091f2012-02-22 08:24:40 -060091 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
Brent Miller126ad952009-08-20 06:50:22 +0000100/* 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
Remi Collet197cb1d2012-11-27 09:01:45 +0100106struct json_tokener* json_tokener_new_ex(int depth)
Michael Clarkf0d08882007-03-13 08:26:18 +0000107{
Michael Clarkaaec1ef2009-02-25 02:31:32 +0000108 struct json_tokener *tok;
109
110 tok = (struct json_tokener*)calloc(1, sizeof(struct json_tokener));
Christopher Watford543bb142009-07-08 03:46:10 +0000111 if (!tok) return NULL;
Eric Haszlakiewiczca8b27d2013-02-09 16:35:24 -0600112 tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
Remi Collet197cb1d2012-11-27 09:01:45 +0100113 if (!tok->stack) {
114 free(tok);
115 return NULL;
116 }
Michael Clarka850f8e2007-03-13 08:26:26 +0000117 tok->pb = printbuf_new();
Remi Collet197cb1d2012-11-27 09:01:45 +0100118 tok->max_depth = depth;
Michael Clarka850f8e2007-03-13 08:26:26 +0000119 json_tokener_reset(tok);
120 return tok;
121}
122
Remi Collet197cb1d2012-11-27 09:01:45 +0100123struct json_tokener* json_tokener_new(void)
124{
125 return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
126}
127
Michael Clarka850f8e2007-03-13 08:26:26 +0000128void json_tokener_free(struct json_tokener *tok)
129{
130 json_tokener_reset(tok);
Remi Collet197cb1d2012-11-27 09:01:45 +0100131 if (tok->pb) printbuf_free(tok->pb);
132 if (tok->stack) free(tok->stack);
Michael Clarka850f8e2007-03-13 08:26:26 +0000133 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;
Michael Clark22dee7c2009-02-25 01:51:40 +0000149 if (!tok)
150 return;
151
Michael Clarka850f8e2007-03-13 08:26:26 +0000152 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
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000158struct json_object* json_tokener_parse(const char *str)
Michael Clarka850f8e2007-03-13 08:26:26 +0000159{
Eric Haszlakiewicz3620cba2012-03-31 12:52:59 -0500160 enum json_tokener_error jerr_ignored;
161 struct json_object* obj;
162 obj = json_tokener_parse_verbose(str, &jerr_ignored);
163 return obj;
Michael Clarkf0d08882007-03-13 08:26:18 +0000164}
165
Jehiah Czebotara503ee82010-12-08 03:52:07 +0000166struct 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();
Eric Haszlakiewicz3620cba2012-03-31 12:52:59 -0500172 if (!tok)
173 return NULL;
Jehiah Czebotara503ee82010-12-08 03:52:07 +0000174 obj = json_tokener_parse_ex(tok, str, -1);
175 *error = tok->err;
176 if(tok->err != json_tokener_success) {
Eric Haszlakiewicz3620cba2012-03-31 12:52:59 -0500177 if (obj != NULL)
178 json_object_put(obj);
Jehiah Czebotara503ee82010-12-08 03:52:07 +0000179 obj = NULL;
180 }
181
182 json_tokener_free(tok);
183 return obj;
184}
185
Michael Clarka850f8e2007-03-13 08:26:26 +0000186#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
Michael Clark95f55a72009-04-27 08:16:58 +0000191/* 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
William Dignaziobb492d42013-03-06 12:29:33 -0500195 * comments and strings. Loops that handle an entire token within
196 * their scope also gather entire strings and pass them to
Michael Clark95f55a72009-04-27 08:16:58 +0000197 * printbuf_memappend() in a single call, rather than calling
198 * printbuf_memappend() one char at a time.
199 *
William Dignaziobb492d42013-03-06 12:29:33 -0500200 * PEEK_CHAR() and ADVANCE_CHAR() macros are used for code that is
Michael Clark95f55a72009-04-27 08:16:58 +0000201 * common to both the main loop and the tighter loops.
202 */
203
William Dignaziobb492d42013-03-06 12:29:33 -0500204/* PEEK_CHAR(dest, tok) macro:
205 * Peeks at the current char and stores it in dest.
Michael Clark95f55a72009-04-27 08:16:58 +0000206 * Returns 1 on success, sets tok->err and returns 0 if no more chars.
207 * Implicit inputs: str, len vars
208 */
William Dignaziobb492d42013-03-06 12:29:33 -0500209#define PEEK_CHAR(dest, tok) \
Michael Clark95f55a72009-04-27 08:16:58 +0000210 (((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 )
William Dignaziobb492d42013-03-06 12:29:33 -0500218
Michael Clark95f55a72009-04-27 08:16:58 +0000219/* 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
Brent Miller126ad952009-08-20 06:50:22 +0000227
Michael Clark95f55a72009-04-27 08:16:58 +0000228/* End optimization macro defs */
229
230
Michael Clarka850f8e2007-03-13 08:26:26 +0000231struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000232 const char *str, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000233{
Michael Clarka850f8e2007-03-13 08:26:26 +0000234 struct json_object *obj = NULL;
Michael Clark95f55a72009-04-27 08:16:58 +0000235 char c = '\1';
Remi Colleta01b6592012-12-13 09:47:33 +0100236#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
Michael Clarkf0d08882007-03-13 08:26:18 +0000243
Michael Clarka850f8e2007-03-13 08:26:26 +0000244 tok->char_offset = 0;
245 tok->err = json_tokener_success;
Michael Clarkf0d08882007-03-13 08:26:18 +0000246
Michael Clark64e36902014-04-09 13:48:21 +0800247 /* 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
William Dignaziobb492d42013-03-06 12:29:33 -0500257 while (PEEK_CHAR(c, tok)) {
Michael Clarka850f8e2007-03-13 08:26:26 +0000258
Michael Clarka850f8e2007-03-13 08:26:26 +0000259 redo_char:
Michael Clarkf0d08882007-03-13 08:26:18 +0000260 switch(state) {
261
262 case json_tokener_state_eatws:
Michael Clark95f55a72009-04-27 08:16:58 +0000263 /* Advance until we change state */
ehaszla252669c2010-12-07 18:15:35 +0000264 while (isspace((int)c)) {
William Dignaziobb492d42013-03-06 12:29:33 -0500265 if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
Michael Clark95f55a72009-04-27 08:16:58 +0000266 goto out;
267 }
Remi Collet87fa32d2013-08-21 15:41:40 +0200268 if(c == '/' && !(tok->flags & JSON_TOKENER_STRICT)) {
Michael Clarka850f8e2007-03-13 08:26:26 +0000269 printbuf_reset(tok->pb);
Michael Clark95f55a72009-04-27 08:16:58 +0000270 printbuf_memappend_fast(tok->pb, &c, 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000271 state = json_tokener_state_comment_start;
Michael Clarkf0d08882007-03-13 08:26:18 +0000272 } else {
273 state = saved_state;
Michael Clarka850f8e2007-03-13 08:26:26 +0000274 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000275 }
276 break;
277
278 case json_tokener_state_start:
279 switch(c) {
280 case '{':
281 state = json_tokener_state_eatws;
Michael Clarka850f8e2007-03-13 08:26:26 +0000282 saved_state = json_tokener_state_object_field_start;
Michael Clarkf0d08882007-03-13 08:26:18 +0000283 current = json_object_new_object();
Michael Clarkf0d08882007-03-13 08:26:18 +0000284 break;
285 case '[':
286 state = json_tokener_state_eatws;
287 saved_state = json_tokener_state_array;
288 current = json_object_new_array();
Michael Clarkf0d08882007-03-13 08:26:18 +0000289 break;
Eric Haszlakiewicz05da3162014-03-22 17:28:40 -0400290 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;
Michael Clarkf0d08882007-03-13 08:26:18 +0000296 case 'N':
297 case 'n':
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400298 state = json_tokener_state_null; // or NaN
Michael Clarka850f8e2007-03-13 08:26:26 +0000299 printbuf_reset(tok->pb);
300 tok->st_pos = 0;
301 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000302 case '\'':
Remi Colleta07ef3d2013-08-06 10:41:14 +0200303 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 '"':
Michael Clarkf0d08882007-03-13 08:26:18 +0000309 state = json_tokener_state_string;
Michael Clarka850f8e2007-03-13 08:26:26 +0000310 printbuf_reset(tok->pb);
311 tok->quote_char = c;
Michael Clarkf0d08882007-03-13 08:26:18 +0000312 break;
313 case 'T':
314 case 't':
315 case 'F':
316 case 'f':
317 state = json_tokener_state_boolean;
Michael Clarka850f8e2007-03-13 08:26:26 +0000318 printbuf_reset(tok->pb);
319 tok->st_pos = 0;
320 goto redo_char;
Michael Clark4504df72007-03-13 08:26:20 +0000321#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
Michael Clarkf0d08882007-03-13 08:26:18 +0000335 case '-':
Michael Clarkf0d08882007-03-13 08:26:18 +0000336 state = json_tokener_state_number;
Michael Clarka850f8e2007-03-13 08:26:26 +0000337 printbuf_reset(tok->pb);
338 tok->is_double = 0;
339 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000340 default:
Michael Clarka850f8e2007-03-13 08:26:26 +0000341 tok->err = json_tokener_error_parse_unexpected;
Michael Clarkf0d08882007-03-13 08:26:18 +0000342 goto out;
343 }
344 break;
345
346 case json_tokener_state_finish:
Michael Clarka850f8e2007-03-13 08:26:26 +0000347 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;
Michael Clarkf0d08882007-03-13 08:26:18 +0000352
Eric Haszlakiewicz05da3162014-03-22 17:28:40 -0400353 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' */
Andrea Fauldsbda05402013-11-14 21:13:32 +0000388 {
389 int size;
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400390 int size_nan;
Andrea Fauldsbda05402013-11-14 21:13:32 +0000391 printbuf_memappend_fast(tok->pb, &c, 1);
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400392 size = json_min(tok->st_pos+1, json_null_str_len);
393 size_nan = json_min(tok->st_pos+1, json_nan_str_len);
Andrea Fauldsbda05402013-11-14 21:13:32 +0000394 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 ) {
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400398 if (tok->st_pos == json_null_str_len) {
Andrea Fauldsbda05402013-11-14 21:13:32 +0000399 current = NULL;
400 saved_state = json_tokener_state_finish;
401 state = json_tokener_state_eatws;
402 goto redo_char;
403 }
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400404 }
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 {
Markus Stenberga1c89912014-03-18 16:29:49 +0200412 current = json_object_new_double(NAN);
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400413 saved_state = json_tokener_state_finish;
414 state = json_tokener_state_eatws;
415 goto redo_char;
416 }
Andrea Fauldsbda05402013-11-14 21:13:32 +0000417 } else {
418 tok->err = json_tokener_error_parse_null;
419 goto out;
Michael Clarka850f8e2007-03-13 08:26:26 +0000420 }
Andrea Fauldsbda05402013-11-14 21:13:32 +0000421 tok->st_pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000422 }
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 {
Michael Clarka850f8e2007-03-13 08:26:26 +0000431 tok->err = json_tokener_error_parse_comment;
Michael Clarkf0d08882007-03-13 08:26:18 +0000432 goto out;
433 }
Michael Clark95f55a72009-04-27 08:16:58 +0000434 printbuf_memappend_fast(tok->pb, &c, 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000435 break;
436
437 case json_tokener_state_comment:
Michael Clark95f55a72009-04-27 08:16:58 +0000438 {
439 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000440 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000441 while(c != '*') {
William Dignaziobb492d42013-03-06 12:29:33 -0500442 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000443 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
444 goto out;
William Dignaziobb492d42013-03-06 12:29:33 -0500445 }
Michael Clark95f55a72009-04-27 08:16:58 +0000446 }
447 printbuf_memappend_fast(tok->pb, case_start, 1+str-case_start);
448 state = json_tokener_state_comment_end;
449 }
450 break;
Michael Clarkf0d08882007-03-13 08:26:18 +0000451
452 case json_tokener_state_comment_eol:
Michael Clark95f55a72009-04-27 08:16:58 +0000453 {
454 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000455 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000456 while(c != '\n') {
William Dignaziobb492d42013-03-06 12:29:33 -0500457 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000458 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);
Michael Clarkdfaf6702007-10-25 02:26:00 +0000463 MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
Michael Clarkf0d08882007-03-13 08:26:18 +0000464 state = json_tokener_state_eatws;
465 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000466 break;
467
468 case json_tokener_state_comment_end:
Michael Clark95f55a72009-04-27 08:16:58 +0000469 printbuf_memappend_fast(tok->pb, &c, 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000470 if(c == '/') {
Michael Clarkdfaf6702007-10-25 02:26:00 +0000471 MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
Michael Clarkf0d08882007-03-13 08:26:18 +0000472 state = json_tokener_state_eatws;
473 } else {
474 state = json_tokener_state_comment;
475 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000476 break;
477
478 case json_tokener_state_string:
Michael Clark95f55a72009-04-27 08:16:58 +0000479 {
480 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000481 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000482 while(1) {
483 if(c == tok->quote_char) {
484 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
Eric Haszlakiewicz4e4af932012-12-09 16:32:11 -0600485 current = json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
Michael Clark95f55a72009-04-27 08:16:58 +0000486 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 }
William Dignaziobb492d42013-03-06 12:29:33 -0500495 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000496 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
497 goto out;
498 }
499 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000500 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000501 break;
502
503 case json_tokener_state_string_escape:
504 switch(c) {
505 case '"':
506 case '\\':
Michael Clarka850f8e2007-03-13 08:26:26 +0000507 case '/':
Michael Clark95f55a72009-04-27 08:16:58 +0000508 printbuf_memappend_fast(tok->pb, &c, 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000509 state = saved_state;
510 break;
511 case 'b':
512 case 'n':
513 case 'r':
514 case 't':
Eric Haszlakiewicz92f31bd2012-07-29 12:31:07 -0500515 case 'f':
Michael Clark95f55a72009-04-27 08:16:58 +0000516 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);
Eric Haszlakiewicz92f31bd2012-07-29 12:31:07 -0500520 else if(c == 'f') printbuf_memappend_fast(tok->pb, "\f", 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000521 state = saved_state;
522 break;
523 case 'u':
Michael Clarka850f8e2007-03-13 08:26:26 +0000524 tok->ucs_char = 0;
525 tok->st_pos = 0;
Michael Clarkf0d08882007-03-13 08:26:18 +0000526 state = json_tokener_state_escape_unicode;
527 break;
528 default:
Michael Clarka850f8e2007-03-13 08:26:26 +0000529 tok->err = json_tokener_error_parse_string;
Michael Clarkf0d08882007-03-13 08:26:18 +0000530 goto out;
531 }
532 break;
533
534 case json_tokener_state_escape_unicode:
Michael Clark95f55a72009-04-27 08:16:58 +0000535 {
Brent Miller126ad952009-08-20 06:50:22 +0000536 unsigned int got_hi_surrogate = 0;
537
538 /* Handle a 4-byte sequence, or two sequences if a surrogate pair */
Michael Clark95f55a72009-04-27 08:16:58 +0000539 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) {
Brent Miller126ad952009-08-20 06:50:22 +0000543 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
Michael Clark95f55a72009-04-27 08:16:58 +0000557 if (tok->ucs_char < 0x80) {
Brent Miller126ad952009-08-20 06:50:22 +0000558 unescaped_utf[0] = tok->ucs_char;
559 printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 1);
Michael Clark95f55a72009-04-27 08:16:58 +0000560 } else if (tok->ucs_char < 0x800) {
Brent Miller126ad952009-08-20 06:50:22 +0000561 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 {
William Dignazio32eddd62013-03-06 20:18:14 -0500576 /* 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 }
Brent Miller126ad952009-08-20 06:50:22 +0000583 /* Advance to the first char of the next sequence and
584 * continue processing with the next sequence.
585 */
William Dignaziobb492d42013-03-06 12:29:33 -0500586 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Brent Miller126ad952009-08-20 06:50:22 +0000587 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);
Michael Clark95f55a72009-04-27 08:16:58 +0000614 } else {
Brent Miller126ad952009-08-20 06:50:22 +0000615 /* Don't know what we got--insert the replacement char */
616 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
617 }
Michael Clark95f55a72009-04-27 08:16:58 +0000618 state = saved_state;
619 break;
620 }
621 } else {
622 tok->err = json_tokener_error_parse_string;
623 goto out;
Brent Miller126ad952009-08-20 06:50:22 +0000624 }
William Dignaziobb492d42013-03-06 12:29:33 -0500625 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Brent Miller126ad952009-08-20 06:50:22 +0000626 if (got_hi_surrogate) /* Clean up any pending chars */
627 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
Michael Clark95f55a72009-04-27 08:16:58 +0000628 goto out;
Brent Miller126ad952009-08-20 06:50:22 +0000629 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000630 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000631 }
632 break;
633
634 case json_tokener_state_boolean:
Andrea Fauldsbda05402013-11-14 21:13:32 +0000635 {
636 int size1, size2;
637 printbuf_memappend_fast(tok->pb, &c, 1);
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400638 size1 = json_min(tok->st_pos+1, json_true_str_len);
639 size2 = json_min(tok->st_pos+1, json_false_str_len);
Andrea Fauldsbda05402013-11-14 21:13:32 +0000640 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 ) {
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400644 if(tok->st_pos == json_true_str_len) {
Andrea Fauldsbda05402013-11-14 21:13:32 +0000645 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)) {
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400653 if(tok->st_pos == json_false_str_len) {
Andrea Fauldsbda05402013-11-14 21:13:32 +0000654 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;
Michael Clarkf0d08882007-03-13 08:26:18 +0000662 }
Andrea Fauldsbda05402013-11-14 21:13:32 +0000663 tok->st_pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000664 }
665 break;
666
667 case json_tokener_state_number:
Michael Clark95f55a72009-04-27 08:16:58 +0000668 {
669 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000670 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000671 int case_len=0;
672 while(c && strchr(json_number_chars, c)) {
673 ++case_len;
Eric Haszlakiewiczf931f612012-04-24 22:17:13 -0500674 if(c == '.' || c == 'e' || c == 'E')
675 tok->is_double = 1;
William Dignaziobb492d42013-03-06 12:29:33 -0500676 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000677 printbuf_memappend_fast(tok->pb, case_start, case_len);
678 goto out;
679 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000680 }
Michael Clark95f55a72009-04-27 08:16:58 +0000681 if (case_len>0)
682 printbuf_memappend_fast(tok->pb, case_start, case_len);
Eric Haszlakiewicz05da3162014-03-22 17:28:40 -0400683
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 }
Michael Clark95f55a72009-04-27 08:16:58 +0000691 }
692 {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000693 int64_t num64;
694 double numd;
695 if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) {
Remi Collete9ee4ae2013-06-13 13:40:01 +0200696 if (num64 && tok->pb->buf[0]=='0' && (tok->flags & JSON_TOKENER_STRICT)) {
Eric Haszlakiewiczd032aad2013-06-19 09:14:19 -0500697 /* in strict mode, number must not start with 0 */
Remi Collete9ee4ae2013-06-13 13:40:01 +0200698 tok->err = json_tokener_error_parse_number;
699 goto out;
700 }
ehaszla252669c2010-12-07 18:15:35 +0000701 current = json_object_new_int64(num64);
Eric Haszlakiewicz51993c22013-09-11 20:27:39 -0500702 }
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);
Michael Clark95f55a72009-04-27 08:16:58 +0000706 } 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;
Michael Clarkf0d08882007-03-13 08:26:18 +0000713 }
714 break;
715
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500716 case json_tokener_state_array_after_sep:
Michael Clarkf0d08882007-03-13 08:26:18 +0000717 case json_tokener_state_array:
718 if(c == ']') {
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500719 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 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000725 saved_state = json_tokener_state_finish;
726 state = json_tokener_state_eatws;
727 } else {
Remi Collet197cb1d2012-11-27 09:01:45 +0100728 if(tok->depth >= tok->max_depth-1) {
Michael Clarka850f8e2007-03-13 08:26:26 +0000729 tok->err = json_tokener_error_depth;
Michael Clarkf0d08882007-03-13 08:26:18 +0000730 goto out;
731 }
Michael Clarka850f8e2007-03-13 08:26:26 +0000732 state = json_tokener_state_array_add;
733 tok->depth++;
734 json_tokener_reset_level(tok, tok->depth);
735 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000736 }
737 break;
738
Michael Clarka850f8e2007-03-13 08:26:26 +0000739 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
Michael Clarkf0d08882007-03-13 08:26:18 +0000745 case json_tokener_state_array_sep:
746 if(c == ']') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000747 saved_state = json_tokener_state_finish;
748 state = json_tokener_state_eatws;
749 } else if(c == ',') {
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500750 saved_state = json_tokener_state_array_after_sep;
Michael Clarkf0d08882007-03-13 08:26:18 +0000751 state = json_tokener_state_eatws;
752 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000753 tok->err = json_tokener_error_parse_array;
754 goto out;
Michael Clarkf0d08882007-03-13 08:26:18 +0000755 }
756 break;
757
Michael Clarkf0d08882007-03-13 08:26:18 +0000758 case json_tokener_state_object_field_start:
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500759 case json_tokener_state_object_field_start_after_sep:
Michael Clarkf0d08882007-03-13 08:26:18 +0000760 if(c == '}') {
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500761 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 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000767 saved_state = json_tokener_state_finish;
768 state = json_tokener_state_eatws;
769 } else if (c == '"' || c == '\'') {
Michael Clarka850f8e2007-03-13 08:26:26 +0000770 tok->quote_char = c;
771 printbuf_reset(tok->pb);
Michael Clarkf0d08882007-03-13 08:26:18 +0000772 state = json_tokener_state_object_field;
Michael Clark0370baa2007-03-13 08:26:22 +0000773 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000774 tok->err = json_tokener_error_parse_object_key_name;
Michael Clark0370baa2007-03-13 08:26:22 +0000775 goto out;
Michael Clarkf0d08882007-03-13 08:26:18 +0000776 }
777 break;
778
779 case json_tokener_state_object_field:
Michael Clark95f55a72009-04-27 08:16:58 +0000780 {
781 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000782 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000783 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 }
William Dignaziobb492d42013-03-06 12:29:33 -0500796 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000797 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
798 goto out;
799 }
800 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000801 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000802 break;
803
804 case json_tokener_state_object_field_end:
805 if(c == ':') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000806 saved_state = json_tokener_state_object_value;
807 state = json_tokener_state_eatws;
808 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000809 tok->err = json_tokener_error_parse_object_key_sep;
810 goto out;
Michael Clarkf0d08882007-03-13 08:26:18 +0000811 }
812 break;
813
814 case json_tokener_state_object_value:
Remi Collet197cb1d2012-11-27 09:01:45 +0100815 if(tok->depth >= tok->max_depth-1) {
Michael Clarka850f8e2007-03-13 08:26:26 +0000816 tok->err = json_tokener_error_depth;
Michael Clarkf0d08882007-03-13 08:26:18 +0000817 goto out;
818 }
Michael Clarka850f8e2007-03-13 08:26:26 +0000819 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:
Michael Clarkf0d08882007-03-13 08:26:18 +0000825 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;
Michael Clarka850f8e2007-03-13 08:26:26 +0000830 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000831
832 case json_tokener_state_object_sep:
833 if(c == '}') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000834 saved_state = json_tokener_state_finish;
835 state = json_tokener_state_eatws;
836 } else if(c == ',') {
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500837 saved_state = json_tokener_state_object_field_start_after_sep;
Michael Clarkf0d08882007-03-13 08:26:18 +0000838 state = json_tokener_state_eatws;
839 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000840 tok->err = json_tokener_error_parse_object_value_sep;
Michael Clarkf0d08882007-03-13 08:26:18 +0000841 goto out;
842 }
843 break;
844
845 }
Michael Clark95f55a72009-04-27 08:16:58 +0000846 if (!ADVANCE_CHAR(str, tok))
847 goto out;
848 } /* while(POP_CHAR) */
Michael Clarkf0d08882007-03-13 08:26:18 +0000849
850 out:
Remi Collet4039f912013-08-23 13:40:01 +0200851 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 }
Michael Clark95f55a72009-04-27 08:16:58 +0000858 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
Remi Colleta01b6592012-12-13 09:47:33 +0100864#ifdef HAVE_SETLOCALE
865 setlocale(LC_NUMERIC, oldlocale);
866 if (oldlocale) free(oldlocale);
867#endif
868
William Dignaziobb492d42013-03-06 12:29:33 -0500869 if (tok->err == json_tokener_success)
Eric Haszlakiewiczd809fa62012-03-31 22:53:43 -0500870 {
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
Michael Clarkdfaf6702007-10-25 02:26:00 +0000880 MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n",
Michael Clarka850f8e2007-03-13 08:26:26 +0000881 json_tokener_errors[tok->err], tok->char_offset);
882 return NULL;
Michael Clarkf0d08882007-03-13 08:26:18 +0000883}
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500884
885void json_tokener_set_flags(struct json_tokener *tok, int flags)
886{
887 tok->flags = flags;
888}