blob: e4710e48e04f649204cb863ed6c1591ae54f9f63 [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 Haszlakiewicz2f9091f2012-02-22 08:24:40 -060069// XXX after v0.10 this array will become static:
Michael Clarka850f8e2007-03-13 08:26:26 +000070const char* json_tokener_errors[] = {
71 "success",
72 "continue",
Eric Haszlakiewicz3620cba2012-03-31 12:52:59 -050073 "nesting too deep",
Michael Clarka850f8e2007-03-13 08:26:26 +000074 "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};
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
William Dignaziobb492d42013-03-06 12:29:33 -0500247 while (PEEK_CHAR(c, tok)) {
Michael Clarka850f8e2007-03-13 08:26:26 +0000248
Michael Clarka850f8e2007-03-13 08:26:26 +0000249 redo_char:
Michael Clarkf0d08882007-03-13 08:26:18 +0000250 switch(state) {
251
252 case json_tokener_state_eatws:
Michael Clark95f55a72009-04-27 08:16:58 +0000253 /* Advance until we change state */
ehaszla252669c2010-12-07 18:15:35 +0000254 while (isspace((int)c)) {
William Dignaziobb492d42013-03-06 12:29:33 -0500255 if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
Michael Clark95f55a72009-04-27 08:16:58 +0000256 goto out;
257 }
Remi Collet87fa32d2013-08-21 15:41:40 +0200258 if(c == '/' && !(tok->flags & JSON_TOKENER_STRICT)) {
Michael Clarka850f8e2007-03-13 08:26:26 +0000259 printbuf_reset(tok->pb);
Michael Clark95f55a72009-04-27 08:16:58 +0000260 printbuf_memappend_fast(tok->pb, &c, 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000261 state = json_tokener_state_comment_start;
Michael Clarkf0d08882007-03-13 08:26:18 +0000262 } else {
263 state = saved_state;
Michael Clarka850f8e2007-03-13 08:26:26 +0000264 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000265 }
266 break;
267
268 case json_tokener_state_start:
269 switch(c) {
270 case '{':
271 state = json_tokener_state_eatws;
Michael Clarka850f8e2007-03-13 08:26:26 +0000272 saved_state = json_tokener_state_object_field_start;
Michael Clarkf0d08882007-03-13 08:26:18 +0000273 current = json_object_new_object();
Michael Clarkf0d08882007-03-13 08:26:18 +0000274 break;
275 case '[':
276 state = json_tokener_state_eatws;
277 saved_state = json_tokener_state_array;
278 current = json_object_new_array();
Michael Clarkf0d08882007-03-13 08:26:18 +0000279 break;
Eric Haszlakiewicz05da3162014-03-22 17:28:40 -0400280 case 'I':
281 case 'i':
282 state = json_tokener_state_inf;
283 printbuf_reset(tok->pb);
284 tok->st_pos = 0;
285 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000286 case 'N':
287 case 'n':
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400288 state = json_tokener_state_null; // or NaN
Michael Clarka850f8e2007-03-13 08:26:26 +0000289 printbuf_reset(tok->pb);
290 tok->st_pos = 0;
291 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000292 case '\'':
Remi Colleta07ef3d2013-08-06 10:41:14 +0200293 if (tok->flags & JSON_TOKENER_STRICT) {
294 /* in STRICT mode only double-quote are allowed */
295 tok->err = json_tokener_error_parse_unexpected;
296 goto out;
297 }
298 case '"':
Michael Clarkf0d08882007-03-13 08:26:18 +0000299 state = json_tokener_state_string;
Michael Clarka850f8e2007-03-13 08:26:26 +0000300 printbuf_reset(tok->pb);
301 tok->quote_char = c;
Michael Clarkf0d08882007-03-13 08:26:18 +0000302 break;
303 case 'T':
304 case 't':
305 case 'F':
306 case 'f':
307 state = json_tokener_state_boolean;
Michael Clarka850f8e2007-03-13 08:26:26 +0000308 printbuf_reset(tok->pb);
309 tok->st_pos = 0;
310 goto redo_char;
Michael Clark4504df72007-03-13 08:26:20 +0000311#if defined(__GNUC__)
312 case '0' ... '9':
313#else
314 case '0':
315 case '1':
316 case '2':
317 case '3':
318 case '4':
319 case '5':
320 case '6':
321 case '7':
322 case '8':
323 case '9':
324#endif
Michael Clarkf0d08882007-03-13 08:26:18 +0000325 case '-':
Michael Clarkf0d08882007-03-13 08:26:18 +0000326 state = json_tokener_state_number;
Michael Clarka850f8e2007-03-13 08:26:26 +0000327 printbuf_reset(tok->pb);
328 tok->is_double = 0;
329 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000330 default:
Michael Clarka850f8e2007-03-13 08:26:26 +0000331 tok->err = json_tokener_error_parse_unexpected;
Michael Clarkf0d08882007-03-13 08:26:18 +0000332 goto out;
333 }
334 break;
335
336 case json_tokener_state_finish:
Michael Clarka850f8e2007-03-13 08:26:26 +0000337 if(tok->depth == 0) goto out;
338 obj = json_object_get(current);
339 json_tokener_reset_level(tok, tok->depth);
340 tok->depth--;
341 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000342
Eric Haszlakiewicz05da3162014-03-22 17:28:40 -0400343 case json_tokener_state_inf: /* aka starts with 'i' */
344 {
345 int size;
346 int size_inf;
347 int is_negative = 0;
348
349 printbuf_memappend_fast(tok->pb, &c, 1);
350 size = json_min(tok->st_pos+1, json_null_str_len);
351 size_inf = json_min(tok->st_pos+1, json_inf_str_len);
352 char *infbuf = tok->pb->buf;
353 if (*infbuf == '-')
354 {
355 infbuf++;
356 is_negative = 1;
357 }
358 if ((!(tok->flags & JSON_TOKENER_STRICT) &&
359 strncasecmp(json_inf_str, infbuf, size_inf) == 0) ||
360 (strncmp(json_inf_str, infbuf, size_inf) == 0)
361 )
362 {
363 if (tok->st_pos == json_inf_str_len)
364 {
365 current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
366 saved_state = json_tokener_state_finish;
367 state = json_tokener_state_eatws;
368 goto redo_char;
369 }
370 } else {
371 tok->err = json_tokener_error_parse_unexpected;
372 goto out;
373 }
374 tok->st_pos++;
375 }
376 break;
377 case json_tokener_state_null: /* aka starts with 'n' */
Andrea Fauldsbda05402013-11-14 21:13:32 +0000378 {
379 int size;
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400380 int size_nan;
Andrea Fauldsbda05402013-11-14 21:13:32 +0000381 printbuf_memappend_fast(tok->pb, &c, 1);
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400382 size = json_min(tok->st_pos+1, json_null_str_len);
383 size_nan = json_min(tok->st_pos+1, json_nan_str_len);
Andrea Fauldsbda05402013-11-14 21:13:32 +0000384 if((!(tok->flags & JSON_TOKENER_STRICT) &&
385 strncasecmp(json_null_str, tok->pb->buf, size) == 0)
386 || (strncmp(json_null_str, tok->pb->buf, size) == 0)
387 ) {
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400388 if (tok->st_pos == json_null_str_len) {
Andrea Fauldsbda05402013-11-14 21:13:32 +0000389 current = NULL;
390 saved_state = json_tokener_state_finish;
391 state = json_tokener_state_eatws;
392 goto redo_char;
393 }
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400394 }
395 else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
396 strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
397 (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0)
398 )
399 {
400 if (tok->st_pos == json_nan_str_len)
401 {
Markus Stenberga1c89912014-03-18 16:29:49 +0200402 current = json_object_new_double(NAN);
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400403 saved_state = json_tokener_state_finish;
404 state = json_tokener_state_eatws;
405 goto redo_char;
406 }
Andrea Fauldsbda05402013-11-14 21:13:32 +0000407 } else {
408 tok->err = json_tokener_error_parse_null;
409 goto out;
Michael Clarka850f8e2007-03-13 08:26:26 +0000410 }
Andrea Fauldsbda05402013-11-14 21:13:32 +0000411 tok->st_pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000412 }
413 break;
414
415 case json_tokener_state_comment_start:
416 if(c == '*') {
417 state = json_tokener_state_comment;
418 } else if(c == '/') {
419 state = json_tokener_state_comment_eol;
420 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000421 tok->err = json_tokener_error_parse_comment;
Michael Clarkf0d08882007-03-13 08:26:18 +0000422 goto out;
423 }
Michael Clark95f55a72009-04-27 08:16:58 +0000424 printbuf_memappend_fast(tok->pb, &c, 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000425 break;
426
427 case json_tokener_state_comment:
Michael Clark95f55a72009-04-27 08:16:58 +0000428 {
429 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000430 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000431 while(c != '*') {
William Dignaziobb492d42013-03-06 12:29:33 -0500432 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000433 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
434 goto out;
William Dignaziobb492d42013-03-06 12:29:33 -0500435 }
Michael Clark95f55a72009-04-27 08:16:58 +0000436 }
437 printbuf_memappend_fast(tok->pb, case_start, 1+str-case_start);
438 state = json_tokener_state_comment_end;
439 }
440 break;
Michael Clarkf0d08882007-03-13 08:26:18 +0000441
442 case json_tokener_state_comment_eol:
Michael Clark95f55a72009-04-27 08:16:58 +0000443 {
444 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000445 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000446 while(c != '\n') {
William Dignaziobb492d42013-03-06 12:29:33 -0500447 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000448 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
449 goto out;
450 }
451 }
452 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
Michael Clarkdfaf6702007-10-25 02:26:00 +0000453 MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
Michael Clarkf0d08882007-03-13 08:26:18 +0000454 state = json_tokener_state_eatws;
455 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000456 break;
457
458 case json_tokener_state_comment_end:
Michael Clark95f55a72009-04-27 08:16:58 +0000459 printbuf_memappend_fast(tok->pb, &c, 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000460 if(c == '/') {
Michael Clarkdfaf6702007-10-25 02:26:00 +0000461 MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
Michael Clarkf0d08882007-03-13 08:26:18 +0000462 state = json_tokener_state_eatws;
463 } else {
464 state = json_tokener_state_comment;
465 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000466 break;
467
468 case json_tokener_state_string:
Michael Clark95f55a72009-04-27 08:16:58 +0000469 {
470 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000471 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000472 while(1) {
473 if(c == tok->quote_char) {
474 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
Eric Haszlakiewicz4e4af932012-12-09 16:32:11 -0600475 current = json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
Michael Clark95f55a72009-04-27 08:16:58 +0000476 saved_state = json_tokener_state_finish;
477 state = json_tokener_state_eatws;
478 break;
479 } else if(c == '\\') {
480 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
481 saved_state = json_tokener_state_string;
482 state = json_tokener_state_string_escape;
483 break;
484 }
William Dignaziobb492d42013-03-06 12:29:33 -0500485 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000486 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
487 goto out;
488 }
489 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000490 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000491 break;
492
493 case json_tokener_state_string_escape:
494 switch(c) {
495 case '"':
496 case '\\':
Michael Clarka850f8e2007-03-13 08:26:26 +0000497 case '/':
Michael Clark95f55a72009-04-27 08:16:58 +0000498 printbuf_memappend_fast(tok->pb, &c, 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000499 state = saved_state;
500 break;
501 case 'b':
502 case 'n':
503 case 'r':
504 case 't':
Eric Haszlakiewicz92f31bd2012-07-29 12:31:07 -0500505 case 'f':
Michael Clark95f55a72009-04-27 08:16:58 +0000506 if(c == 'b') printbuf_memappend_fast(tok->pb, "\b", 1);
507 else if(c == 'n') printbuf_memappend_fast(tok->pb, "\n", 1);
508 else if(c == 'r') printbuf_memappend_fast(tok->pb, "\r", 1);
509 else if(c == 't') printbuf_memappend_fast(tok->pb, "\t", 1);
Eric Haszlakiewicz92f31bd2012-07-29 12:31:07 -0500510 else if(c == 'f') printbuf_memappend_fast(tok->pb, "\f", 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000511 state = saved_state;
512 break;
513 case 'u':
Michael Clarka850f8e2007-03-13 08:26:26 +0000514 tok->ucs_char = 0;
515 tok->st_pos = 0;
Michael Clarkf0d08882007-03-13 08:26:18 +0000516 state = json_tokener_state_escape_unicode;
517 break;
518 default:
Michael Clarka850f8e2007-03-13 08:26:26 +0000519 tok->err = json_tokener_error_parse_string;
Michael Clarkf0d08882007-03-13 08:26:18 +0000520 goto out;
521 }
522 break;
523
524 case json_tokener_state_escape_unicode:
Michael Clark95f55a72009-04-27 08:16:58 +0000525 {
Brent Miller126ad952009-08-20 06:50:22 +0000526 unsigned int got_hi_surrogate = 0;
527
528 /* Handle a 4-byte sequence, or two sequences if a surrogate pair */
Michael Clark95f55a72009-04-27 08:16:58 +0000529 while(1) {
530 if(strchr(json_hex_chars, c)) {
531 tok->ucs_char += ((unsigned int)hexdigit(c) << ((3-tok->st_pos++)*4));
532 if(tok->st_pos == 4) {
Brent Miller126ad952009-08-20 06:50:22 +0000533 unsigned char unescaped_utf[4];
534
535 if (got_hi_surrogate) {
536 if (IS_LOW_SURROGATE(tok->ucs_char)) {
537 /* Recalculate the ucs_char, then fall thru to process normally */
538 tok->ucs_char = DECODE_SURROGATE_PAIR(got_hi_surrogate, tok->ucs_char);
539 } else {
540 /* Hi surrogate was not followed by a low surrogate */
541 /* Replace the hi and process the rest normally */
542 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
543 }
544 got_hi_surrogate = 0;
545 }
546
Michael Clark95f55a72009-04-27 08:16:58 +0000547 if (tok->ucs_char < 0x80) {
Brent Miller126ad952009-08-20 06:50:22 +0000548 unescaped_utf[0] = tok->ucs_char;
549 printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 1);
Michael Clark95f55a72009-04-27 08:16:58 +0000550 } else if (tok->ucs_char < 0x800) {
Brent Miller126ad952009-08-20 06:50:22 +0000551 unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
552 unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
553 printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 2);
554 } else if (IS_HIGH_SURROGATE(tok->ucs_char)) {
555 /* Got a high surrogate. Remember it and look for the
556 * the beginning of another sequence, which should be the
557 * low surrogate.
558 */
559 got_hi_surrogate = tok->ucs_char;
560 /* Not at end, and the next two chars should be "\u" */
561 if ((tok->char_offset+1 != len) &&
562 (tok->char_offset+2 != len) &&
563 (str[1] == '\\') &&
564 (str[2] == 'u'))
565 {
William Dignazio32eddd62013-03-06 20:18:14 -0500566 /* Advance through the 16 bit surrogate, and move on to the
567 * next sequence. The next step is to process the following
568 * characters.
569 */
570 if( !ADVANCE_CHAR(str, tok) || !ADVANCE_CHAR(str, tok) ) {
571 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
572 }
Brent Miller126ad952009-08-20 06:50:22 +0000573 /* Advance to the first char of the next sequence and
574 * continue processing with the next sequence.
575 */
William Dignaziobb492d42013-03-06 12:29:33 -0500576 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Brent Miller126ad952009-08-20 06:50:22 +0000577 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
578 goto out;
579 }
580 tok->ucs_char = 0;
581 tok->st_pos = 0;
582 continue; /* other json_tokener_state_escape_unicode */
583 } else {
584 /* Got a high surrogate without another sequence following
585 * it. Put a replacement char in for the hi surrogate
586 * and pretend we finished.
587 */
588 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
589 }
590 } else if (IS_LOW_SURROGATE(tok->ucs_char)) {
591 /* Got a low surrogate not preceded by a high */
592 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
593 } else if (tok->ucs_char < 0x10000) {
594 unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
595 unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
596 unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
597 printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 3);
598 } else if (tok->ucs_char < 0x110000) {
599 unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
600 unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
601 unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
602 unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
603 printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 4);
Michael Clark95f55a72009-04-27 08:16:58 +0000604 } else {
Brent Miller126ad952009-08-20 06:50:22 +0000605 /* Don't know what we got--insert the replacement char */
606 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
607 }
Michael Clark95f55a72009-04-27 08:16:58 +0000608 state = saved_state;
609 break;
610 }
611 } else {
612 tok->err = json_tokener_error_parse_string;
613 goto out;
Brent Miller126ad952009-08-20 06:50:22 +0000614 }
William Dignaziobb492d42013-03-06 12:29:33 -0500615 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Brent Miller126ad952009-08-20 06:50:22 +0000616 if (got_hi_surrogate) /* Clean up any pending chars */
617 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
Michael Clark95f55a72009-04-27 08:16:58 +0000618 goto out;
Brent Miller126ad952009-08-20 06:50:22 +0000619 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000620 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000621 }
622 break;
623
624 case json_tokener_state_boolean:
Andrea Fauldsbda05402013-11-14 21:13:32 +0000625 {
626 int size1, size2;
627 printbuf_memappend_fast(tok->pb, &c, 1);
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400628 size1 = json_min(tok->st_pos+1, json_true_str_len);
629 size2 = json_min(tok->st_pos+1, json_false_str_len);
Andrea Fauldsbda05402013-11-14 21:13:32 +0000630 if((!(tok->flags & JSON_TOKENER_STRICT) &&
631 strncasecmp(json_true_str, tok->pb->buf, size1) == 0)
632 || (strncmp(json_true_str, tok->pb->buf, size1) == 0)
633 ) {
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400634 if(tok->st_pos == json_true_str_len) {
Andrea Fauldsbda05402013-11-14 21:13:32 +0000635 current = json_object_new_boolean(1);
636 saved_state = json_tokener_state_finish;
637 state = json_tokener_state_eatws;
638 goto redo_char;
639 }
640 } else if((!(tok->flags & JSON_TOKENER_STRICT) &&
641 strncasecmp(json_false_str, tok->pb->buf, size2) == 0)
642 || (strncmp(json_false_str, tok->pb->buf, size2) == 0)) {
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400643 if(tok->st_pos == json_false_str_len) {
Andrea Fauldsbda05402013-11-14 21:13:32 +0000644 current = json_object_new_boolean(0);
645 saved_state = json_tokener_state_finish;
646 state = json_tokener_state_eatws;
647 goto redo_char;
648 }
649 } else {
650 tok->err = json_tokener_error_parse_boolean;
651 goto out;
Michael Clarkf0d08882007-03-13 08:26:18 +0000652 }
Andrea Fauldsbda05402013-11-14 21:13:32 +0000653 tok->st_pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000654 }
655 break;
656
657 case json_tokener_state_number:
Michael Clark95f55a72009-04-27 08:16:58 +0000658 {
659 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000660 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000661 int case_len=0;
662 while(c && strchr(json_number_chars, c)) {
663 ++case_len;
Eric Haszlakiewiczf931f612012-04-24 22:17:13 -0500664 if(c == '.' || c == 'e' || c == 'E')
665 tok->is_double = 1;
William Dignaziobb492d42013-03-06 12:29:33 -0500666 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000667 printbuf_memappend_fast(tok->pb, case_start, case_len);
668 goto out;
669 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000670 }
Michael Clark95f55a72009-04-27 08:16:58 +0000671 if (case_len>0)
672 printbuf_memappend_fast(tok->pb, case_start, case_len);
Eric Haszlakiewicz05da3162014-03-22 17:28:40 -0400673
674 // Check for -Infinity
675 if (tok->pb->buf[0] == '-' && case_len == 1 &&
676 (c == 'i' || c == 'I'))
677 {
678 state = json_tokener_state_inf;
679 goto redo_char;
680 }
Michael Clark95f55a72009-04-27 08:16:58 +0000681 }
682 {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000683 int64_t num64;
684 double numd;
685 if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) {
Remi Collete9ee4ae2013-06-13 13:40:01 +0200686 if (num64 && tok->pb->buf[0]=='0' && (tok->flags & JSON_TOKENER_STRICT)) {
Eric Haszlakiewiczd032aad2013-06-19 09:14:19 -0500687 /* in strict mode, number must not start with 0 */
Remi Collete9ee4ae2013-06-13 13:40:01 +0200688 tok->err = json_tokener_error_parse_number;
689 goto out;
690 }
ehaszla252669c2010-12-07 18:15:35 +0000691 current = json_object_new_int64(num64);
Eric Haszlakiewicz51993c22013-09-11 20:27:39 -0500692 }
693 else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0)
694 {
695 current = json_object_new_double_s(numd, tok->pb->buf);
Michael Clark95f55a72009-04-27 08:16:58 +0000696 } else {
697 tok->err = json_tokener_error_parse_number;
698 goto out;
699 }
700 saved_state = json_tokener_state_finish;
701 state = json_tokener_state_eatws;
702 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000703 }
704 break;
705
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500706 case json_tokener_state_array_after_sep:
Michael Clarkf0d08882007-03-13 08:26:18 +0000707 case json_tokener_state_array:
708 if(c == ']') {
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500709 if (state == json_tokener_state_array_after_sep &&
710 (tok->flags & JSON_TOKENER_STRICT))
711 {
712 tok->err = json_tokener_error_parse_unexpected;
713 goto out;
714 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000715 saved_state = json_tokener_state_finish;
716 state = json_tokener_state_eatws;
717 } else {
Remi Collet197cb1d2012-11-27 09:01:45 +0100718 if(tok->depth >= tok->max_depth-1) {
Michael Clarka850f8e2007-03-13 08:26:26 +0000719 tok->err = json_tokener_error_depth;
Michael Clarkf0d08882007-03-13 08:26:18 +0000720 goto out;
721 }
Michael Clarka850f8e2007-03-13 08:26:26 +0000722 state = json_tokener_state_array_add;
723 tok->depth++;
724 json_tokener_reset_level(tok, tok->depth);
725 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000726 }
727 break;
728
Michael Clarka850f8e2007-03-13 08:26:26 +0000729 case json_tokener_state_array_add:
730 json_object_array_add(current, obj);
731 saved_state = json_tokener_state_array_sep;
732 state = json_tokener_state_eatws;
733 goto redo_char;
734
Michael Clarkf0d08882007-03-13 08:26:18 +0000735 case json_tokener_state_array_sep:
736 if(c == ']') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000737 saved_state = json_tokener_state_finish;
738 state = json_tokener_state_eatws;
739 } else if(c == ',') {
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500740 saved_state = json_tokener_state_array_after_sep;
Michael Clarkf0d08882007-03-13 08:26:18 +0000741 state = json_tokener_state_eatws;
742 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000743 tok->err = json_tokener_error_parse_array;
744 goto out;
Michael Clarkf0d08882007-03-13 08:26:18 +0000745 }
746 break;
747
Michael Clarkf0d08882007-03-13 08:26:18 +0000748 case json_tokener_state_object_field_start:
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500749 case json_tokener_state_object_field_start_after_sep:
Michael Clarkf0d08882007-03-13 08:26:18 +0000750 if(c == '}') {
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500751 if (state == json_tokener_state_object_field_start_after_sep &&
752 (tok->flags & JSON_TOKENER_STRICT))
753 {
754 tok->err = json_tokener_error_parse_unexpected;
755 goto out;
756 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000757 saved_state = json_tokener_state_finish;
758 state = json_tokener_state_eatws;
759 } else if (c == '"' || c == '\'') {
Michael Clarka850f8e2007-03-13 08:26:26 +0000760 tok->quote_char = c;
761 printbuf_reset(tok->pb);
Michael Clarkf0d08882007-03-13 08:26:18 +0000762 state = json_tokener_state_object_field;
Michael Clark0370baa2007-03-13 08:26:22 +0000763 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000764 tok->err = json_tokener_error_parse_object_key_name;
Michael Clark0370baa2007-03-13 08:26:22 +0000765 goto out;
Michael Clarkf0d08882007-03-13 08:26:18 +0000766 }
767 break;
768
769 case json_tokener_state_object_field:
Michael Clark95f55a72009-04-27 08:16:58 +0000770 {
771 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000772 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000773 while(1) {
774 if(c == tok->quote_char) {
775 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
776 obj_field_name = strdup(tok->pb->buf);
777 saved_state = json_tokener_state_object_field_end;
778 state = json_tokener_state_eatws;
779 break;
780 } else if(c == '\\') {
781 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
782 saved_state = json_tokener_state_object_field;
783 state = json_tokener_state_string_escape;
784 break;
785 }
William Dignaziobb492d42013-03-06 12:29:33 -0500786 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000787 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
788 goto out;
789 }
790 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000791 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000792 break;
793
794 case json_tokener_state_object_field_end:
795 if(c == ':') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000796 saved_state = json_tokener_state_object_value;
797 state = json_tokener_state_eatws;
798 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000799 tok->err = json_tokener_error_parse_object_key_sep;
800 goto out;
Michael Clarkf0d08882007-03-13 08:26:18 +0000801 }
802 break;
803
804 case json_tokener_state_object_value:
Remi Collet197cb1d2012-11-27 09:01:45 +0100805 if(tok->depth >= tok->max_depth-1) {
Michael Clarka850f8e2007-03-13 08:26:26 +0000806 tok->err = json_tokener_error_depth;
Michael Clarkf0d08882007-03-13 08:26:18 +0000807 goto out;
808 }
Michael Clarka850f8e2007-03-13 08:26:26 +0000809 state = json_tokener_state_object_value_add;
810 tok->depth++;
811 json_tokener_reset_level(tok, tok->depth);
812 goto redo_char;
813
814 case json_tokener_state_object_value_add:
Michael Clarkf0d08882007-03-13 08:26:18 +0000815 json_object_object_add(current, obj_field_name, obj);
816 free(obj_field_name);
817 obj_field_name = NULL;
818 saved_state = json_tokener_state_object_sep;
819 state = json_tokener_state_eatws;
Michael Clarka850f8e2007-03-13 08:26:26 +0000820 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000821
822 case json_tokener_state_object_sep:
823 if(c == '}') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000824 saved_state = json_tokener_state_finish;
825 state = json_tokener_state_eatws;
826 } else if(c == ',') {
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500827 saved_state = json_tokener_state_object_field_start_after_sep;
Michael Clarkf0d08882007-03-13 08:26:18 +0000828 state = json_tokener_state_eatws;
829 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000830 tok->err = json_tokener_error_parse_object_value_sep;
Michael Clarkf0d08882007-03-13 08:26:18 +0000831 goto out;
832 }
833 break;
834
835 }
Michael Clark95f55a72009-04-27 08:16:58 +0000836 if (!ADVANCE_CHAR(str, tok))
837 goto out;
838 } /* while(POP_CHAR) */
Michael Clarkf0d08882007-03-13 08:26:18 +0000839
840 out:
Remi Collet4039f912013-08-23 13:40:01 +0200841 if (c &&
842 (state == json_tokener_state_finish) &&
843 (tok->depth == 0) &&
844 (tok->flags & JSON_TOKENER_STRICT)) {
845 /* unexpected char after JSON data */
846 tok->err = json_tokener_error_parse_unexpected;
847 }
Michael Clark95f55a72009-04-27 08:16:58 +0000848 if (!c) { /* We hit an eof char (0) */
849 if(state != json_tokener_state_finish &&
850 saved_state != json_tokener_state_finish)
851 tok->err = json_tokener_error_parse_eof;
852 }
853
Remi Colleta01b6592012-12-13 09:47:33 +0100854#ifdef HAVE_SETLOCALE
855 setlocale(LC_NUMERIC, oldlocale);
856 if (oldlocale) free(oldlocale);
857#endif
858
William Dignaziobb492d42013-03-06 12:29:33 -0500859 if (tok->err == json_tokener_success)
Eric Haszlakiewiczd809fa62012-03-31 22:53:43 -0500860 {
861 json_object *ret = json_object_get(current);
862 int ii;
863
864 /* Partially reset, so we parse additional objects on subsequent calls. */
865 for(ii = tok->depth; ii >= 0; ii--)
866 json_tokener_reset_level(tok, ii);
867 return ret;
868 }
869
Michael Clarkdfaf6702007-10-25 02:26:00 +0000870 MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n",
Michael Clarka850f8e2007-03-13 08:26:26 +0000871 json_tokener_errors[tok->err], tok->char_offset);
872 return NULL;
Michael Clarkf0d08882007-03-13 08:26:18 +0000873}
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500874
875void json_tokener_set_flags(struct json_tokener *tok, int flags)
876{
877 tok->flags = flags;
878}