blob: a1019c0a759ed5902d82fd4ec02476338a1f441e [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",
84};
85
Eric Haszlakiewicz2f9091f2012-02-22 08:24:40 -060086const char *json_tokener_error_desc(enum json_tokener_error jerr)
87{
Eric Haszlakiewiczca8b27d2013-02-09 16:35:24 -060088 int jerr_int = (int)jerr;
Eric Haszlakiewicz56df93d2014-02-11 23:16:53 -050089 if (jerr_int < 0 || jerr_int >= (int)(sizeof(json_tokener_errors) / sizeof(json_tokener_errors[0])))
Eric Haszlakiewicz2f9091f2012-02-22 08:24:40 -060090 return "Unknown error, invalid json_tokener_error value passed to json_tokener_error_desc()";
91 return json_tokener_errors[jerr];
92}
93
94enum json_tokener_error json_tokener_get_error(json_tokener *tok)
95{
96 return tok->err;
97}
98
Brent Miller126ad952009-08-20 06:50:22 +000099/* Stuff for decoding unicode sequences */
100#define IS_HIGH_SURROGATE(uc) (((uc) & 0xFC00) == 0xD800)
101#define IS_LOW_SURROGATE(uc) (((uc) & 0xFC00) == 0xDC00)
102#define DECODE_SURROGATE_PAIR(hi,lo) ((((hi) & 0x3FF) << 10) + ((lo) & 0x3FF) + 0x10000)
103static unsigned char utf8_replacement_char[3] = { 0xEF, 0xBF, 0xBD };
104
Remi Collet197cb1d2012-11-27 09:01:45 +0100105struct json_tokener* json_tokener_new_ex(int depth)
Michael Clarkf0d08882007-03-13 08:26:18 +0000106{
Michael Clarkaaec1ef2009-02-25 02:31:32 +0000107 struct json_tokener *tok;
108
109 tok = (struct json_tokener*)calloc(1, sizeof(struct json_tokener));
Christopher Watford543bb142009-07-08 03:46:10 +0000110 if (!tok) return NULL;
Eric Haszlakiewiczca8b27d2013-02-09 16:35:24 -0600111 tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
Remi Collet197cb1d2012-11-27 09:01:45 +0100112 if (!tok->stack) {
113 free(tok);
114 return NULL;
115 }
Michael Clarka850f8e2007-03-13 08:26:26 +0000116 tok->pb = printbuf_new();
Remi Collet197cb1d2012-11-27 09:01:45 +0100117 tok->max_depth = depth;
Michael Clarka850f8e2007-03-13 08:26:26 +0000118 json_tokener_reset(tok);
119 return tok;
120}
121
Remi Collet197cb1d2012-11-27 09:01:45 +0100122struct json_tokener* json_tokener_new(void)
123{
124 return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
125}
126
Michael Clarka850f8e2007-03-13 08:26:26 +0000127void json_tokener_free(struct json_tokener *tok)
128{
129 json_tokener_reset(tok);
Remi Collet197cb1d2012-11-27 09:01:45 +0100130 if (tok->pb) printbuf_free(tok->pb);
131 if (tok->stack) free(tok->stack);
Michael Clarka850f8e2007-03-13 08:26:26 +0000132 free(tok);
133}
134
135static void json_tokener_reset_level(struct json_tokener *tok, int depth)
136{
137 tok->stack[depth].state = json_tokener_state_eatws;
138 tok->stack[depth].saved_state = json_tokener_state_start;
139 json_object_put(tok->stack[depth].current);
140 tok->stack[depth].current = NULL;
141 free(tok->stack[depth].obj_field_name);
142 tok->stack[depth].obj_field_name = NULL;
143}
144
145void json_tokener_reset(struct json_tokener *tok)
146{
147 int i;
Michael Clark22dee7c2009-02-25 01:51:40 +0000148 if (!tok)
149 return;
150
Michael Clarka850f8e2007-03-13 08:26:26 +0000151 for(i = tok->depth; i >= 0; i--)
152 json_tokener_reset_level(tok, i);
153 tok->depth = 0;
154 tok->err = json_tokener_success;
155}
156
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000157struct json_object* json_tokener_parse(const char *str)
Michael Clarka850f8e2007-03-13 08:26:26 +0000158{
Eric Haszlakiewicz3620cba2012-03-31 12:52:59 -0500159 enum json_tokener_error jerr_ignored;
160 struct json_object* obj;
161 obj = json_tokener_parse_verbose(str, &jerr_ignored);
162 return obj;
Michael Clarkf0d08882007-03-13 08:26:18 +0000163}
164
Jehiah Czebotara503ee82010-12-08 03:52:07 +0000165struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
166{
167 struct json_tokener* tok;
168 struct json_object* obj;
169
170 tok = json_tokener_new();
Eric Haszlakiewicz3620cba2012-03-31 12:52:59 -0500171 if (!tok)
172 return NULL;
Jehiah Czebotara503ee82010-12-08 03:52:07 +0000173 obj = json_tokener_parse_ex(tok, str, -1);
174 *error = tok->err;
175 if(tok->err != json_tokener_success) {
Eric Haszlakiewicz3620cba2012-03-31 12:52:59 -0500176 if (obj != NULL)
177 json_object_put(obj);
Jehiah Czebotara503ee82010-12-08 03:52:07 +0000178 obj = NULL;
179 }
180
181 json_tokener_free(tok);
182 return obj;
183}
184
Michael Clarka850f8e2007-03-13 08:26:26 +0000185#define state tok->stack[tok->depth].state
186#define saved_state tok->stack[tok->depth].saved_state
187#define current tok->stack[tok->depth].current
188#define obj_field_name tok->stack[tok->depth].obj_field_name
189
Michael Clark95f55a72009-04-27 08:16:58 +0000190/* Optimization:
191 * json_tokener_parse_ex() consumed a lot of CPU in its main loop,
192 * iterating character-by character. A large performance boost is
193 * achieved by using tighter loops to locally handle units such as
William Dignaziobb492d42013-03-06 12:29:33 -0500194 * comments and strings. Loops that handle an entire token within
195 * their scope also gather entire strings and pass them to
Michael Clark95f55a72009-04-27 08:16:58 +0000196 * printbuf_memappend() in a single call, rather than calling
197 * printbuf_memappend() one char at a time.
198 *
William Dignaziobb492d42013-03-06 12:29:33 -0500199 * PEEK_CHAR() and ADVANCE_CHAR() macros are used for code that is
Michael Clark95f55a72009-04-27 08:16:58 +0000200 * common to both the main loop and the tighter loops.
201 */
202
William Dignaziobb492d42013-03-06 12:29:33 -0500203/* PEEK_CHAR(dest, tok) macro:
204 * Peeks at the current char and stores it in dest.
Michael Clark95f55a72009-04-27 08:16:58 +0000205 * Returns 1 on success, sets tok->err and returns 0 if no more chars.
206 * Implicit inputs: str, len vars
207 */
William Dignaziobb492d42013-03-06 12:29:33 -0500208#define PEEK_CHAR(dest, tok) \
Michael Clark95f55a72009-04-27 08:16:58 +0000209 (((tok)->char_offset == len) ? \
210 (((tok)->depth == 0 && state == json_tokener_state_eatws && saved_state == json_tokener_state_finish) ? \
211 (((tok)->err = json_tokener_success), 0) \
212 : \
213 (((tok)->err = json_tokener_continue), 0) \
214 ) : \
215 (((dest) = *str), 1) \
216 )
William Dignaziobb492d42013-03-06 12:29:33 -0500217
Michael Clark95f55a72009-04-27 08:16:58 +0000218/* ADVANCE_CHAR() macro:
219 * Incrementes str & tok->char_offset.
220 * For convenience of existing conditionals, returns the old value of c (0 on eof)
221 * Implicit inputs: c var
222 */
223#define ADVANCE_CHAR(str, tok) \
224 ( ++(str), ((tok)->char_offset)++, c)
225
Brent Miller126ad952009-08-20 06:50:22 +0000226
Michael Clark95f55a72009-04-27 08:16:58 +0000227/* End optimization macro defs */
228
229
Michael Clarka850f8e2007-03-13 08:26:26 +0000230struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000231 const char *str, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000232{
Michael Clarka850f8e2007-03-13 08:26:26 +0000233 struct json_object *obj = NULL;
Michael Clark95f55a72009-04-27 08:16:58 +0000234 char c = '\1';
Remi Colleta01b6592012-12-13 09:47:33 +0100235#ifdef HAVE_SETLOCALE
236 char *oldlocale=NULL, *tmplocale;
237
238 tmplocale = setlocale(LC_NUMERIC, NULL);
239 if (tmplocale) oldlocale = strdup(tmplocale);
240 setlocale(LC_NUMERIC, "C");
241#endif
Michael Clarkf0d08882007-03-13 08:26:18 +0000242
Michael Clarka850f8e2007-03-13 08:26:26 +0000243 tok->char_offset = 0;
244 tok->err = json_tokener_success;
Michael Clarkf0d08882007-03-13 08:26:18 +0000245
William Dignaziobb492d42013-03-06 12:29:33 -0500246 while (PEEK_CHAR(c, tok)) {
Michael Clarka850f8e2007-03-13 08:26:26 +0000247
Michael Clarka850f8e2007-03-13 08:26:26 +0000248 redo_char:
Michael Clarkf0d08882007-03-13 08:26:18 +0000249 switch(state) {
250
251 case json_tokener_state_eatws:
Michael Clark95f55a72009-04-27 08:16:58 +0000252 /* Advance until we change state */
ehaszla252669c2010-12-07 18:15:35 +0000253 while (isspace((int)c)) {
William Dignaziobb492d42013-03-06 12:29:33 -0500254 if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
Michael Clark95f55a72009-04-27 08:16:58 +0000255 goto out;
256 }
Remi Collet87fa32d2013-08-21 15:41:40 +0200257 if(c == '/' && !(tok->flags & JSON_TOKENER_STRICT)) {
Michael Clarka850f8e2007-03-13 08:26:26 +0000258 printbuf_reset(tok->pb);
Michael Clark95f55a72009-04-27 08:16:58 +0000259 printbuf_memappend_fast(tok->pb, &c, 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000260 state = json_tokener_state_comment_start;
Michael Clarkf0d08882007-03-13 08:26:18 +0000261 } else {
262 state = saved_state;
Michael Clarka850f8e2007-03-13 08:26:26 +0000263 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000264 }
265 break;
266
267 case json_tokener_state_start:
268 switch(c) {
269 case '{':
270 state = json_tokener_state_eatws;
Michael Clarka850f8e2007-03-13 08:26:26 +0000271 saved_state = json_tokener_state_object_field_start;
Michael Clarkf0d08882007-03-13 08:26:18 +0000272 current = json_object_new_object();
Michael Clarkf0d08882007-03-13 08:26:18 +0000273 break;
274 case '[':
275 state = json_tokener_state_eatws;
276 saved_state = json_tokener_state_array;
277 current = json_object_new_array();
Michael Clarkf0d08882007-03-13 08:26:18 +0000278 break;
Eric Haszlakiewicz05da3162014-03-22 17:28:40 -0400279 case 'I':
280 case 'i':
281 state = json_tokener_state_inf;
282 printbuf_reset(tok->pb);
283 tok->st_pos = 0;
284 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000285 case 'N':
286 case 'n':
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400287 state = json_tokener_state_null; // or NaN
Michael Clarka850f8e2007-03-13 08:26:26 +0000288 printbuf_reset(tok->pb);
289 tok->st_pos = 0;
290 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000291 case '\'':
Remi Colleta07ef3d2013-08-06 10:41:14 +0200292 if (tok->flags & JSON_TOKENER_STRICT) {
293 /* in STRICT mode only double-quote are allowed */
294 tok->err = json_tokener_error_parse_unexpected;
295 goto out;
296 }
297 case '"':
Michael Clarkf0d08882007-03-13 08:26:18 +0000298 state = json_tokener_state_string;
Michael Clarka850f8e2007-03-13 08:26:26 +0000299 printbuf_reset(tok->pb);
300 tok->quote_char = c;
Michael Clarkf0d08882007-03-13 08:26:18 +0000301 break;
302 case 'T':
303 case 't':
304 case 'F':
305 case 'f':
306 state = json_tokener_state_boolean;
Michael Clarka850f8e2007-03-13 08:26:26 +0000307 printbuf_reset(tok->pb);
308 tok->st_pos = 0;
309 goto redo_char;
Michael Clark4504df72007-03-13 08:26:20 +0000310#if defined(__GNUC__)
311 case '0' ... '9':
312#else
313 case '0':
314 case '1':
315 case '2':
316 case '3':
317 case '4':
318 case '5':
319 case '6':
320 case '7':
321 case '8':
322 case '9':
323#endif
Michael Clarkf0d08882007-03-13 08:26:18 +0000324 case '-':
Michael Clarkf0d08882007-03-13 08:26:18 +0000325 state = json_tokener_state_number;
Michael Clarka850f8e2007-03-13 08:26:26 +0000326 printbuf_reset(tok->pb);
327 tok->is_double = 0;
328 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000329 default:
Michael Clarka850f8e2007-03-13 08:26:26 +0000330 tok->err = json_tokener_error_parse_unexpected;
Michael Clarkf0d08882007-03-13 08:26:18 +0000331 goto out;
332 }
333 break;
334
335 case json_tokener_state_finish:
Michael Clarka850f8e2007-03-13 08:26:26 +0000336 if(tok->depth == 0) goto out;
337 obj = json_object_get(current);
338 json_tokener_reset_level(tok, tok->depth);
339 tok->depth--;
340 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000341
Eric Haszlakiewicz05da3162014-03-22 17:28:40 -0400342 case json_tokener_state_inf: /* aka starts with 'i' */
343 {
344 int size;
345 int size_inf;
346 int is_negative = 0;
347
348 printbuf_memappend_fast(tok->pb, &c, 1);
349 size = json_min(tok->st_pos+1, json_null_str_len);
350 size_inf = json_min(tok->st_pos+1, json_inf_str_len);
351 char *infbuf = tok->pb->buf;
352 if (*infbuf == '-')
353 {
354 infbuf++;
355 is_negative = 1;
356 }
357 if ((!(tok->flags & JSON_TOKENER_STRICT) &&
358 strncasecmp(json_inf_str, infbuf, size_inf) == 0) ||
359 (strncmp(json_inf_str, infbuf, size_inf) == 0)
360 )
361 {
362 if (tok->st_pos == json_inf_str_len)
363 {
364 current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
365 saved_state = json_tokener_state_finish;
366 state = json_tokener_state_eatws;
367 goto redo_char;
368 }
369 } else {
370 tok->err = json_tokener_error_parse_unexpected;
371 goto out;
372 }
373 tok->st_pos++;
374 }
375 break;
376 case json_tokener_state_null: /* aka starts with 'n' */
Andrea Fauldsbda05402013-11-14 21:13:32 +0000377 {
378 int size;
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400379 int size_nan;
Andrea Fauldsbda05402013-11-14 21:13:32 +0000380 printbuf_memappend_fast(tok->pb, &c, 1);
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400381 size = json_min(tok->st_pos+1, json_null_str_len);
382 size_nan = json_min(tok->st_pos+1, json_nan_str_len);
Andrea Fauldsbda05402013-11-14 21:13:32 +0000383 if((!(tok->flags & JSON_TOKENER_STRICT) &&
384 strncasecmp(json_null_str, tok->pb->buf, size) == 0)
385 || (strncmp(json_null_str, tok->pb->buf, size) == 0)
386 ) {
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400387 if (tok->st_pos == json_null_str_len) {
Andrea Fauldsbda05402013-11-14 21:13:32 +0000388 current = NULL;
389 saved_state = json_tokener_state_finish;
390 state = json_tokener_state_eatws;
391 goto redo_char;
392 }
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400393 }
394 else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
395 strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
396 (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0)
397 )
398 {
399 if (tok->st_pos == json_nan_str_len)
400 {
Markus Stenberga1c89912014-03-18 16:29:49 +0200401 current = json_object_new_double(NAN);
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400402 saved_state = json_tokener_state_finish;
403 state = json_tokener_state_eatws;
404 goto redo_char;
405 }
Andrea Fauldsbda05402013-11-14 21:13:32 +0000406 } else {
407 tok->err = json_tokener_error_parse_null;
408 goto out;
Michael Clarka850f8e2007-03-13 08:26:26 +0000409 }
Andrea Fauldsbda05402013-11-14 21:13:32 +0000410 tok->st_pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000411 }
412 break;
413
414 case json_tokener_state_comment_start:
415 if(c == '*') {
416 state = json_tokener_state_comment;
417 } else if(c == '/') {
418 state = json_tokener_state_comment_eol;
419 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000420 tok->err = json_tokener_error_parse_comment;
Michael Clarkf0d08882007-03-13 08:26:18 +0000421 goto out;
422 }
Michael Clark95f55a72009-04-27 08:16:58 +0000423 printbuf_memappend_fast(tok->pb, &c, 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000424 break;
425
426 case json_tokener_state_comment:
Michael Clark95f55a72009-04-27 08:16:58 +0000427 {
428 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000429 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000430 while(c != '*') {
William Dignaziobb492d42013-03-06 12:29:33 -0500431 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000432 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
433 goto out;
William Dignaziobb492d42013-03-06 12:29:33 -0500434 }
Michael Clark95f55a72009-04-27 08:16:58 +0000435 }
436 printbuf_memappend_fast(tok->pb, case_start, 1+str-case_start);
437 state = json_tokener_state_comment_end;
438 }
439 break;
Michael Clarkf0d08882007-03-13 08:26:18 +0000440
441 case json_tokener_state_comment_eol:
Michael Clark95f55a72009-04-27 08:16:58 +0000442 {
443 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000444 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000445 while(c != '\n') {
William Dignaziobb492d42013-03-06 12:29:33 -0500446 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000447 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
448 goto out;
449 }
450 }
451 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
Michael Clarkdfaf6702007-10-25 02:26:00 +0000452 MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
Michael Clarkf0d08882007-03-13 08:26:18 +0000453 state = json_tokener_state_eatws;
454 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000455 break;
456
457 case json_tokener_state_comment_end:
Michael Clark95f55a72009-04-27 08:16:58 +0000458 printbuf_memappend_fast(tok->pb, &c, 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000459 if(c == '/') {
Michael Clarkdfaf6702007-10-25 02:26:00 +0000460 MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
Michael Clarkf0d08882007-03-13 08:26:18 +0000461 state = json_tokener_state_eatws;
462 } else {
463 state = json_tokener_state_comment;
464 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000465 break;
466
467 case json_tokener_state_string:
Michael Clark95f55a72009-04-27 08:16:58 +0000468 {
469 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000470 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000471 while(1) {
472 if(c == tok->quote_char) {
473 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
Eric Haszlakiewicz4e4af932012-12-09 16:32:11 -0600474 current = json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
Michael Clark95f55a72009-04-27 08:16:58 +0000475 saved_state = json_tokener_state_finish;
476 state = json_tokener_state_eatws;
477 break;
478 } else if(c == '\\') {
479 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
480 saved_state = json_tokener_state_string;
481 state = json_tokener_state_string_escape;
482 break;
483 }
William Dignaziobb492d42013-03-06 12:29:33 -0500484 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000485 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
486 goto out;
487 }
488 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000489 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000490 break;
491
492 case json_tokener_state_string_escape:
493 switch(c) {
494 case '"':
495 case '\\':
Michael Clarka850f8e2007-03-13 08:26:26 +0000496 case '/':
Michael Clark95f55a72009-04-27 08:16:58 +0000497 printbuf_memappend_fast(tok->pb, &c, 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000498 state = saved_state;
499 break;
500 case 'b':
501 case 'n':
502 case 'r':
503 case 't':
Eric Haszlakiewicz92f31bd2012-07-29 12:31:07 -0500504 case 'f':
Michael Clark95f55a72009-04-27 08:16:58 +0000505 if(c == 'b') printbuf_memappend_fast(tok->pb, "\b", 1);
506 else if(c == 'n') printbuf_memappend_fast(tok->pb, "\n", 1);
507 else if(c == 'r') printbuf_memappend_fast(tok->pb, "\r", 1);
508 else if(c == 't') printbuf_memappend_fast(tok->pb, "\t", 1);
Eric Haszlakiewicz92f31bd2012-07-29 12:31:07 -0500509 else if(c == 'f') printbuf_memappend_fast(tok->pb, "\f", 1);
Michael Clarkf0d08882007-03-13 08:26:18 +0000510 state = saved_state;
511 break;
512 case 'u':
Michael Clarka850f8e2007-03-13 08:26:26 +0000513 tok->ucs_char = 0;
514 tok->st_pos = 0;
Michael Clarkf0d08882007-03-13 08:26:18 +0000515 state = json_tokener_state_escape_unicode;
516 break;
517 default:
Michael Clarka850f8e2007-03-13 08:26:26 +0000518 tok->err = json_tokener_error_parse_string;
Michael Clarkf0d08882007-03-13 08:26:18 +0000519 goto out;
520 }
521 break;
522
523 case json_tokener_state_escape_unicode:
Michael Clark95f55a72009-04-27 08:16:58 +0000524 {
Brent Miller126ad952009-08-20 06:50:22 +0000525 unsigned int got_hi_surrogate = 0;
526
527 /* Handle a 4-byte sequence, or two sequences if a surrogate pair */
Michael Clark95f55a72009-04-27 08:16:58 +0000528 while(1) {
529 if(strchr(json_hex_chars, c)) {
530 tok->ucs_char += ((unsigned int)hexdigit(c) << ((3-tok->st_pos++)*4));
531 if(tok->st_pos == 4) {
Brent Miller126ad952009-08-20 06:50:22 +0000532 unsigned char unescaped_utf[4];
533
534 if (got_hi_surrogate) {
535 if (IS_LOW_SURROGATE(tok->ucs_char)) {
536 /* Recalculate the ucs_char, then fall thru to process normally */
537 tok->ucs_char = DECODE_SURROGATE_PAIR(got_hi_surrogate, tok->ucs_char);
538 } else {
539 /* Hi surrogate was not followed by a low surrogate */
540 /* Replace the hi and process the rest normally */
541 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
542 }
543 got_hi_surrogate = 0;
544 }
545
Michael Clark95f55a72009-04-27 08:16:58 +0000546 if (tok->ucs_char < 0x80) {
Brent Miller126ad952009-08-20 06:50:22 +0000547 unescaped_utf[0] = tok->ucs_char;
548 printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 1);
Michael Clark95f55a72009-04-27 08:16:58 +0000549 } else if (tok->ucs_char < 0x800) {
Brent Miller126ad952009-08-20 06:50:22 +0000550 unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
551 unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
552 printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 2);
553 } else if (IS_HIGH_SURROGATE(tok->ucs_char)) {
554 /* Got a high surrogate. Remember it and look for the
555 * the beginning of another sequence, which should be the
556 * low surrogate.
557 */
558 got_hi_surrogate = tok->ucs_char;
559 /* Not at end, and the next two chars should be "\u" */
560 if ((tok->char_offset+1 != len) &&
561 (tok->char_offset+2 != len) &&
562 (str[1] == '\\') &&
563 (str[2] == 'u'))
564 {
William Dignazio32eddd62013-03-06 20:18:14 -0500565 /* Advance through the 16 bit surrogate, and move on to the
566 * next sequence. The next step is to process the following
567 * characters.
568 */
569 if( !ADVANCE_CHAR(str, tok) || !ADVANCE_CHAR(str, tok) ) {
570 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
571 }
Brent Miller126ad952009-08-20 06:50:22 +0000572 /* Advance to the first char of the next sequence and
573 * continue processing with the next sequence.
574 */
William Dignaziobb492d42013-03-06 12:29:33 -0500575 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Brent Miller126ad952009-08-20 06:50:22 +0000576 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
577 goto out;
578 }
579 tok->ucs_char = 0;
580 tok->st_pos = 0;
581 continue; /* other json_tokener_state_escape_unicode */
582 } else {
583 /* Got a high surrogate without another sequence following
584 * it. Put a replacement char in for the hi surrogate
585 * and pretend we finished.
586 */
587 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
588 }
589 } else if (IS_LOW_SURROGATE(tok->ucs_char)) {
590 /* Got a low surrogate not preceded by a high */
591 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
592 } else if (tok->ucs_char < 0x10000) {
593 unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
594 unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
595 unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
596 printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 3);
597 } else if (tok->ucs_char < 0x110000) {
598 unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
599 unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
600 unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
601 unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
602 printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 4);
Michael Clark95f55a72009-04-27 08:16:58 +0000603 } else {
Brent Miller126ad952009-08-20 06:50:22 +0000604 /* Don't know what we got--insert the replacement char */
605 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
606 }
Michael Clark95f55a72009-04-27 08:16:58 +0000607 state = saved_state;
608 break;
609 }
610 } else {
611 tok->err = json_tokener_error_parse_string;
612 goto out;
Brent Miller126ad952009-08-20 06:50:22 +0000613 }
William Dignaziobb492d42013-03-06 12:29:33 -0500614 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Brent Miller126ad952009-08-20 06:50:22 +0000615 if (got_hi_surrogate) /* Clean up any pending chars */
616 printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
Michael Clark95f55a72009-04-27 08:16:58 +0000617 goto out;
Brent Miller126ad952009-08-20 06:50:22 +0000618 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000619 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000620 }
621 break;
622
623 case json_tokener_state_boolean:
Andrea Fauldsbda05402013-11-14 21:13:32 +0000624 {
625 int size1, size2;
626 printbuf_memappend_fast(tok->pb, &c, 1);
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400627 size1 = json_min(tok->st_pos+1, json_true_str_len);
628 size2 = json_min(tok->st_pos+1, json_false_str_len);
Andrea Fauldsbda05402013-11-14 21:13:32 +0000629 if((!(tok->flags & JSON_TOKENER_STRICT) &&
630 strncasecmp(json_true_str, tok->pb->buf, size1) == 0)
631 || (strncmp(json_true_str, tok->pb->buf, size1) == 0)
632 ) {
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400633 if(tok->st_pos == json_true_str_len) {
Andrea Fauldsbda05402013-11-14 21:13:32 +0000634 current = json_object_new_boolean(1);
635 saved_state = json_tokener_state_finish;
636 state = json_tokener_state_eatws;
637 goto redo_char;
638 }
639 } else if((!(tok->flags & JSON_TOKENER_STRICT) &&
640 strncasecmp(json_false_str, tok->pb->buf, size2) == 0)
641 || (strncmp(json_false_str, tok->pb->buf, size2) == 0)) {
Eric Haszlakiewicz0eedf382014-03-09 16:41:33 -0400642 if(tok->st_pos == json_false_str_len) {
Andrea Fauldsbda05402013-11-14 21:13:32 +0000643 current = json_object_new_boolean(0);
644 saved_state = json_tokener_state_finish;
645 state = json_tokener_state_eatws;
646 goto redo_char;
647 }
648 } else {
649 tok->err = json_tokener_error_parse_boolean;
650 goto out;
Michael Clarkf0d08882007-03-13 08:26:18 +0000651 }
Andrea Fauldsbda05402013-11-14 21:13:32 +0000652 tok->st_pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000653 }
654 break;
655
656 case json_tokener_state_number:
Michael Clark95f55a72009-04-27 08:16:58 +0000657 {
658 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000659 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000660 int case_len=0;
661 while(c && strchr(json_number_chars, c)) {
662 ++case_len;
Eric Haszlakiewiczf931f612012-04-24 22:17:13 -0500663 if(c == '.' || c == 'e' || c == 'E')
664 tok->is_double = 1;
William Dignaziobb492d42013-03-06 12:29:33 -0500665 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000666 printbuf_memappend_fast(tok->pb, case_start, case_len);
667 goto out;
668 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000669 }
Michael Clark95f55a72009-04-27 08:16:58 +0000670 if (case_len>0)
671 printbuf_memappend_fast(tok->pb, case_start, case_len);
Eric Haszlakiewicz05da3162014-03-22 17:28:40 -0400672
673 // Check for -Infinity
674 if (tok->pb->buf[0] == '-' && case_len == 1 &&
675 (c == 'i' || c == 'I'))
676 {
677 state = json_tokener_state_inf;
678 goto redo_char;
679 }
Michael Clark95f55a72009-04-27 08:16:58 +0000680 }
681 {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000682 int64_t num64;
683 double numd;
684 if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) {
Remi Collete9ee4ae2013-06-13 13:40:01 +0200685 if (num64 && tok->pb->buf[0]=='0' && (tok->flags & JSON_TOKENER_STRICT)) {
Eric Haszlakiewiczd032aad2013-06-19 09:14:19 -0500686 /* in strict mode, number must not start with 0 */
Remi Collete9ee4ae2013-06-13 13:40:01 +0200687 tok->err = json_tokener_error_parse_number;
688 goto out;
689 }
ehaszla252669c2010-12-07 18:15:35 +0000690 current = json_object_new_int64(num64);
Eric Haszlakiewicz51993c22013-09-11 20:27:39 -0500691 }
692 else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0)
693 {
694 current = json_object_new_double_s(numd, tok->pb->buf);
Michael Clark95f55a72009-04-27 08:16:58 +0000695 } else {
696 tok->err = json_tokener_error_parse_number;
697 goto out;
698 }
699 saved_state = json_tokener_state_finish;
700 state = json_tokener_state_eatws;
701 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000702 }
703 break;
704
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500705 case json_tokener_state_array_after_sep:
Michael Clarkf0d08882007-03-13 08:26:18 +0000706 case json_tokener_state_array:
707 if(c == ']') {
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500708 if (state == json_tokener_state_array_after_sep &&
709 (tok->flags & JSON_TOKENER_STRICT))
710 {
711 tok->err = json_tokener_error_parse_unexpected;
712 goto out;
713 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000714 saved_state = json_tokener_state_finish;
715 state = json_tokener_state_eatws;
716 } else {
Remi Collet197cb1d2012-11-27 09:01:45 +0100717 if(tok->depth >= tok->max_depth-1) {
Michael Clarka850f8e2007-03-13 08:26:26 +0000718 tok->err = json_tokener_error_depth;
Michael Clarkf0d08882007-03-13 08:26:18 +0000719 goto out;
720 }
Michael Clarka850f8e2007-03-13 08:26:26 +0000721 state = json_tokener_state_array_add;
722 tok->depth++;
723 json_tokener_reset_level(tok, tok->depth);
724 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000725 }
726 break;
727
Michael Clarka850f8e2007-03-13 08:26:26 +0000728 case json_tokener_state_array_add:
729 json_object_array_add(current, obj);
730 saved_state = json_tokener_state_array_sep;
731 state = json_tokener_state_eatws;
732 goto redo_char;
733
Michael Clarkf0d08882007-03-13 08:26:18 +0000734 case json_tokener_state_array_sep:
735 if(c == ']') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000736 saved_state = json_tokener_state_finish;
737 state = json_tokener_state_eatws;
738 } else if(c == ',') {
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500739 saved_state = json_tokener_state_array_after_sep;
Michael Clarkf0d08882007-03-13 08:26:18 +0000740 state = json_tokener_state_eatws;
741 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000742 tok->err = json_tokener_error_parse_array;
743 goto out;
Michael Clarkf0d08882007-03-13 08:26:18 +0000744 }
745 break;
746
Michael Clarkf0d08882007-03-13 08:26:18 +0000747 case json_tokener_state_object_field_start:
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500748 case json_tokener_state_object_field_start_after_sep:
Michael Clarkf0d08882007-03-13 08:26:18 +0000749 if(c == '}') {
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500750 if (state == json_tokener_state_object_field_start_after_sep &&
751 (tok->flags & JSON_TOKENER_STRICT))
752 {
753 tok->err = json_tokener_error_parse_unexpected;
754 goto out;
755 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000756 saved_state = json_tokener_state_finish;
757 state = json_tokener_state_eatws;
758 } else if (c == '"' || c == '\'') {
Michael Clarka850f8e2007-03-13 08:26:26 +0000759 tok->quote_char = c;
760 printbuf_reset(tok->pb);
Michael Clarkf0d08882007-03-13 08:26:18 +0000761 state = json_tokener_state_object_field;
Michael Clark0370baa2007-03-13 08:26:22 +0000762 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000763 tok->err = json_tokener_error_parse_object_key_name;
Michael Clark0370baa2007-03-13 08:26:22 +0000764 goto out;
Michael Clarkf0d08882007-03-13 08:26:18 +0000765 }
766 break;
767
768 case json_tokener_state_object_field:
Michael Clark95f55a72009-04-27 08:16:58 +0000769 {
770 /* Advance until we change state */
Christopher Watfordb1a22ac2009-07-08 04:02:05 +0000771 const char *case_start = str;
Michael Clark95f55a72009-04-27 08:16:58 +0000772 while(1) {
773 if(c == tok->quote_char) {
774 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
775 obj_field_name = strdup(tok->pb->buf);
776 saved_state = json_tokener_state_object_field_end;
777 state = json_tokener_state_eatws;
778 break;
779 } else if(c == '\\') {
780 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
781 saved_state = json_tokener_state_object_field;
782 state = json_tokener_state_string_escape;
783 break;
784 }
William Dignaziobb492d42013-03-06 12:29:33 -0500785 if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
Michael Clark95f55a72009-04-27 08:16:58 +0000786 printbuf_memappend_fast(tok->pb, case_start, str-case_start);
787 goto out;
788 }
789 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000790 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000791 break;
792
793 case json_tokener_state_object_field_end:
794 if(c == ':') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000795 saved_state = json_tokener_state_object_value;
796 state = json_tokener_state_eatws;
797 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000798 tok->err = json_tokener_error_parse_object_key_sep;
799 goto out;
Michael Clarkf0d08882007-03-13 08:26:18 +0000800 }
801 break;
802
803 case json_tokener_state_object_value:
Remi Collet197cb1d2012-11-27 09:01:45 +0100804 if(tok->depth >= tok->max_depth-1) {
Michael Clarka850f8e2007-03-13 08:26:26 +0000805 tok->err = json_tokener_error_depth;
Michael Clarkf0d08882007-03-13 08:26:18 +0000806 goto out;
807 }
Michael Clarka850f8e2007-03-13 08:26:26 +0000808 state = json_tokener_state_object_value_add;
809 tok->depth++;
810 json_tokener_reset_level(tok, tok->depth);
811 goto redo_char;
812
813 case json_tokener_state_object_value_add:
Michael Clarkf0d08882007-03-13 08:26:18 +0000814 json_object_object_add(current, obj_field_name, obj);
815 free(obj_field_name);
816 obj_field_name = NULL;
817 saved_state = json_tokener_state_object_sep;
818 state = json_tokener_state_eatws;
Michael Clarka850f8e2007-03-13 08:26:26 +0000819 goto redo_char;
Michael Clarkf0d08882007-03-13 08:26:18 +0000820
821 case json_tokener_state_object_sep:
822 if(c == '}') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000823 saved_state = json_tokener_state_finish;
824 state = json_tokener_state_eatws;
825 } else if(c == ',') {
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500826 saved_state = json_tokener_state_object_field_start_after_sep;
Michael Clarkf0d08882007-03-13 08:26:18 +0000827 state = json_tokener_state_eatws;
828 } else {
Michael Clarka850f8e2007-03-13 08:26:26 +0000829 tok->err = json_tokener_error_parse_object_value_sep;
Michael Clarkf0d08882007-03-13 08:26:18 +0000830 goto out;
831 }
832 break;
833
834 }
Michael Clark95f55a72009-04-27 08:16:58 +0000835 if (!ADVANCE_CHAR(str, tok))
836 goto out;
837 } /* while(POP_CHAR) */
Michael Clarkf0d08882007-03-13 08:26:18 +0000838
839 out:
Remi Collet4039f912013-08-23 13:40:01 +0200840 if (c &&
841 (state == json_tokener_state_finish) &&
842 (tok->depth == 0) &&
843 (tok->flags & JSON_TOKENER_STRICT)) {
844 /* unexpected char after JSON data */
845 tok->err = json_tokener_error_parse_unexpected;
846 }
Michael Clark95f55a72009-04-27 08:16:58 +0000847 if (!c) { /* We hit an eof char (0) */
848 if(state != json_tokener_state_finish &&
849 saved_state != json_tokener_state_finish)
850 tok->err = json_tokener_error_parse_eof;
851 }
852
Remi Colleta01b6592012-12-13 09:47:33 +0100853#ifdef HAVE_SETLOCALE
854 setlocale(LC_NUMERIC, oldlocale);
855 if (oldlocale) free(oldlocale);
856#endif
857
William Dignaziobb492d42013-03-06 12:29:33 -0500858 if (tok->err == json_tokener_success)
Eric Haszlakiewiczd809fa62012-03-31 22:53:43 -0500859 {
860 json_object *ret = json_object_get(current);
861 int ii;
862
863 /* Partially reset, so we parse additional objects on subsequent calls. */
864 for(ii = tok->depth; ii >= 0; ii--)
865 json_tokener_reset_level(tok, ii);
866 return ret;
867 }
868
Michael Clarkdfaf6702007-10-25 02:26:00 +0000869 MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n",
Michael Clarka850f8e2007-03-13 08:26:26 +0000870 json_tokener_errors[tok->err], tok->char_offset);
871 return NULL;
Michael Clarkf0d08882007-03-13 08:26:18 +0000872}
Eric Haszlakiewicze8161a12013-03-31 20:05:36 -0500873
874void json_tokener_set_flags(struct json_tokener *tok, int flags)
875{
876 tok->flags = flags;
877}