You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

json_tokener.c 24 kB

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