json_tokener.c
Go to the documentation of this file.
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 
12 #include "config.h"
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <ctype.h>
17 #include <string.h>
18 #include <strings.h>
19 
20 #include "bits.h"
21 #include "debug.h"
22 #include "printbuf.h"
23 #include "arraylist.h"
24 #include "json_object.h"
25 #include "json_tokener.h"
26 
27 
28 #if !HAVE_STRNCASECMP && defined(_MSC_VER)
29  /* MSC has the version as _strnicmp */
30 # define strncasecmp _strnicmp
31 #elif !HAVE_STRNCASECMP
32 /*# error You do not have strncasecmp on your system.*/
33 #endif /* HAVE_STRNCASECMP */
34 
35 
36 static const char* json_null_str = "null";
37 static const char* json_true_str = "true";
38 static const char* json_false_str = "false";
39 
40 const char* json_tokener_errors[] = {
41  "success",
42  "continue",
43  "nesting to deep",
44  "unexpected end of data",
45  "unexpected character",
46  "null expected",
47  "boolean expected",
48  "number expected",
49  "array value separator ',' expected",
50  "quoted object property name expected",
51  "object property name separator ':' expected",
52  "object value separator ',' expected",
53  "invalid string sequence",
54  "expected comment",
55 };
56 
57 
59 {
60  struct json_tokener *tok = calloc(1, sizeof(struct json_tokener));
61  tok->pb = printbuf_new();
62  json_tokener_reset(tok);
63  return tok;
64 }
65 
67 {
68  json_tokener_reset(tok);
69  if(tok) printbuf_free(tok->pb);
70  free(tok);
71 }
72 
73 static void json_tokener_reset_level(struct json_tokener *tok, int depth)
74 {
75  tok->stack[depth].state = json_tokener_state_eatws;
78  tok->stack[depth].current = NULL;
79  free(tok->stack[depth].obj_field_name);
80  tok->stack[depth].obj_field_name = NULL;
81 }
82 
84 {
85  int i;
86  for(i = tok->depth; i >= 0; i--)
88  tok->depth = 0;
90 }
91 
92 struct json_object* json_tokener_parse(const char *str)
93 {
94  struct json_tokener* tok;
95  struct json_object* obj;
96 
97  tok = json_tokener_new();
98  obj = json_tokener_parse_ex(tok, str, -1);
99  if(tok->err != json_tokener_success)
100  obj = error_ptr(-tok->err);
101  json_tokener_free(tok);
102  return obj;
103 }
104 
105 
106 /*#if !HAVE_STRNDUP*/
107 /* CAW: compliant version of strndup() */
108 char* json_c_strndup(const char* str, size_t n)
109 {
110  if(str) {
111  size_t len = strlen(str);
112  size_t nn = min(len,n);
113  char* s = (char*)malloc(sizeof(char) * (nn + 1));
114 
115  if(s) {
116  memcpy(s, str, nn);
117  s[nn] = '\0';
118  }
119 
120  return s;
121  }
122 
123  return NULL;
124 }
125 /*#endif*/
126 
127 
128 #define state tok->stack[tok->depth].state
129 #define saved_state tok->stack[tok->depth].saved_state
130 #define current tok->stack[tok->depth].current
131 #define obj_field_name tok->stack[tok->depth].obj_field_name
132 
134  const char *str, int len)
135 {
136  struct json_object *obj = NULL;
137  char c;
138 
139  tok->char_offset = 0;
140  tok->err = json_tokener_success;
141 
142  do {
143  if(tok->char_offset == len) {
144  if(tok->depth == 0 && state == json_tokener_state_eatws &&
146  tok->err = json_tokener_success;
147  else
148  tok->err = json_tokener_continue;
149  goto out;
150  }
151 
152  c = *str;
153  redo_char:
154  switch(state) {
155 
157  if(isspace(c)) {
158  /* okay */
159  } else if(c == '/') {
160  printbuf_reset(tok->pb);
161  printbuf_memappend(tok->pb, &c, 1);
163  } else {
164  state = saved_state;
165  goto redo_char;
166  }
167  break;
168 
170  switch(c) {
171  case '{':
175  break;
176  case '[':
180  break;
181  case 'N':
182  case 'n':
184  printbuf_reset(tok->pb);
185  tok->st_pos = 0;
186  goto redo_char;
187  case '"':
188  case '\'':
190  printbuf_reset(tok->pb);
191  tok->quote_char = c;
192  break;
193  case 'T':
194  case 't':
195  case 'F':
196  case 'f':
198  printbuf_reset(tok->pb);
199  tok->st_pos = 0;
200  goto redo_char;
201 #if 0 /*defined(__GNUC__)*/
202  case '0' ... '9':
203 #else
204  case '0':
205  case '1':
206  case '2':
207  case '3':
208  case '4':
209  case '5':
210  case '6':
211  case '7':
212  case '8':
213  case '9':
214 #endif
215  case '-':
217  printbuf_reset(tok->pb);
218  tok->is_double = 0;
219  goto redo_char;
220  default:
222  goto out;
223  }
224  break;
225 
227  if(tok->depth == 0) goto out;
228  obj = json_object_get(current);
229  json_tokener_reset_level(tok, tok->depth);
230  tok->depth--;
231  goto redo_char;
232 
234  printbuf_memappend(tok->pb, &c, 1);
235  if(strncasecmp(json_null_str, tok->pb->buf,
236  min( (size_t) (tok->st_pos+1), strlen(json_null_str))) == 0) {
237  if( ((size_t) tok->st_pos) == strlen(json_null_str)) {
238  current = NULL;
241  goto redo_char;
242  }
243  } else {
245  goto out;
246  }
247  tok->st_pos++;
248  break;
249 
251  if(c == '*') {
253  } else if(c == '/') {
255  } else {
257  goto out;
258  }
259  printbuf_memappend(tok->pb, &c, 1);
260  break;
261 
263  if(c == '*') state = json_tokener_state_comment_end;
264  printbuf_memappend(tok->pb, &c, 1);
265  break;
266 
268  if(c == '\n') {
269  mc_debug("json_tokener_comment: %s\n", tok->pb->buf);
271  } else {
272  printbuf_memappend(tok->pb, &c, 1);
273  }
274  break;
275 
277  printbuf_memappend(tok->pb, &c, 1);
278  if(c == '/') {
279  mc_debug("json_tokener_comment: %s\n", tok->pb->buf);
281  } else {
283  }
284  break;
285 
287  if(c == tok->quote_char) {
291  } else if(c == '\\') {
294  } else {
295  printbuf_memappend(tok->pb, &c, 1);
296  }
297  break;
298 
300  switch(c) {
301  case '"':
302  case '\\':
303  case '/':
304  printbuf_memappend(tok->pb, &c, 1);
305  state = saved_state;
306  break;
307  case 'b':
308  case 'n':
309  case 'r':
310  case 't':
311  if(c == 'b') printbuf_memappend(tok->pb, "\b", 1);
312  else if(c == 'n') printbuf_memappend(tok->pb, "\n", 1);
313  else if(c == 'r') printbuf_memappend(tok->pb, "\r", 1);
314  else if(c == 't') printbuf_memappend(tok->pb, "\t", 1);
315  state = saved_state;
316  break;
317  case 'u':
318  tok->ucs_char = 0;
319  tok->st_pos = 0;
321  break;
322  default:
324  goto out;
325  }
326  break;
327 
329  if(strchr(json_hex_chars, c)) {
330  tok->ucs_char += ((unsigned int)hexdigit(c) << ((3-tok->st_pos++)*4));
331  if(tok->st_pos == 4) {
332  unsigned char utf_out[3];
333  if (tok->ucs_char < 0x80) {
334  utf_out[0] = tok->ucs_char;
335  printbuf_memappend(tok->pb, (char*)utf_out, 1);
336  } else if (tok->ucs_char < 0x800) {
337  utf_out[0] = 0xc0 | (tok->ucs_char >> 6);
338  utf_out[1] = 0x80 | (tok->ucs_char & 0x3f);
339  printbuf_memappend(tok->pb, (char*)utf_out, 2);
340  } else {
341  utf_out[0] = 0xe0 | (tok->ucs_char >> 12);
342  utf_out[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
343  utf_out[2] = 0x80 | (tok->ucs_char & 0x3f);
344  printbuf_memappend(tok->pb, (char*)utf_out, 3);
345  }
346  state = saved_state;
347  }
348  } else {
350  goto out;
351  }
352  break;
353 
355  printbuf_memappend(tok->pb, &c, 1);
356  if(strncasecmp(json_true_str, tok->pb->buf,
357  min( (size_t)(tok->st_pos+1), strlen(json_true_str))) == 0) {
358  if(((size_t) tok->st_pos) == strlen(json_true_str)) {
362  goto redo_char;
363  }
364  } else if(strncasecmp(json_false_str, tok->pb->buf,
365  min((size_t)(tok->st_pos+1), strlen(json_false_str))) == 0) {
366  if(( (size_t) tok->st_pos) == strlen(json_false_str)) {
370  goto redo_char;
371  }
372  } else {
374  goto out;
375  }
376  tok->st_pos++;
377  break;
378 
380  if(c && strchr(json_number_chars, c)) {
381  printbuf_memappend(tok->pb, &c, 1);
382  if(c == '.' || c == 'e') tok->is_double = 1;
383  } else {
384  int numi;
385  double numd;
386  if(!tok->is_double && sscanf(tok->pb->buf, "%d", &numi) == 1) {
388  } else if(tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) {
390  } else {
392  goto out;
393  }
396  goto redo_char;
397  }
398  break;
399 
401  if(c == ']') {
404  } else {
405  if(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) {
407  goto out;
408  }
410  tok->depth++;
411  json_tokener_reset_level(tok, tok->depth);
412  goto redo_char;
413  }
414  break;
415 
420  goto redo_char;
421 
423  if(c == ']') {
426  } else if(c == ',') {
429  } else {
431  goto out;
432  }
433  break;
434 
436  if(c == '}') {
439  } else if (c == '"' || c == '\'') {
440  tok->quote_char = c;
441  printbuf_reset(tok->pb);
443  } else {
445  goto out;
446  }
447  break;
448 
450  if(c == tok->quote_char) {
451  obj_field_name = strdup(tok->pb->buf);
454  } else if(c == '\\') {
457  } else {
458  printbuf_memappend(tok->pb, &c, 1);
459  }
460  break;
461 
463  if(c == ':') {
466  } else {
468  goto out;
469  }
470  break;
471 
473  if(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) {
475  goto out;
476  }
478  tok->depth++;
479  json_tokener_reset_level(tok, tok->depth);
480  goto redo_char;
481 
484  free(obj_field_name);
485  obj_field_name = NULL;
488  goto redo_char;
489 
491  if(c == '}') {
494  } else if(c == ',') {
497  } else {
499  goto out;
500  }
501  break;
502 
503  }
504  str++;
505  tok->char_offset++;
506  } while(c);
507 
511 
512  out:
513  if(tok->err == json_tokener_success) return json_object_get(current);
514  mc_debug("json_tokener_parse_ex: error %s at offset %d\n",
515  json_tokener_errors[tok->err], tok->char_offset);
516  return NULL;
517 }
json_tokener_success
@ json_tokener_success
Definition: json_tokener.h:18
json_false_str
static const char * json_false_str
Definition: json_tokener.c:38
json_tokener_state_comment_start
@ json_tokener_state_comment_start
Definition: json_tokener.h:39
json_object_new_array
struct json_object * json_object_new_array()
Definition: json_object.c:495
json_tokener_state_eatws
@ json_tokener_state_eatws
Definition: json_tokener.h:35
json_tokener_state_object_field
@ json_tokener_state_object_field
Definition: json_tokener.h:52
json_tokener_state_string_escape
@ json_tokener_state_string_escape
Definition: json_tokener.h:44
json_object_new_int
struct json_object * json_object_new_int(int i)
Definition: json_object.c:332
json_tokener::char_offset
int char_offset
Definition: json_tokener.h:73
json_object_get
struct json_object * json_object_get(struct json_object *this)
Definition: json_object.c:136
json_null_str
static const char * json_null_str
Definition: json_tokener.c:36
json_tokener_continue
@ json_tokener_continue
Definition: json_tokener.h:19
json_object_object_add
void json_object_object_add(struct json_object *this, const char *key, struct json_object *val)
Definition: json_object.c:270
json_hex_chars
const char * json_hex_chars
Definition: json_object.c:41
json_tokener_free
void json_tokener_free(struct json_tokener *tok)
Definition: json_tokener.c:66
json_tokener_error_parse_object_key_sep
@ json_tokener_error_parse_object_key_sep
Definition: json_tokener.h:28
json_tokener_state_array_add
@ json_tokener_state_array_add
Definition: json_tokener.h:49
json_object_new_object
struct json_object * json_object_new_object()
Definition: json_object.c:248
json_tokener_state_comment
@ json_tokener_state_comment
Definition: json_tokener.h:40
json_number_chars
const char * json_number_chars
Definition: json_object.c:40
json_tokener
Definition: json_tokener.h:69
json_tokener_error_parse_array
@ json_tokener_error_parse_array
Definition: json_tokener.h:26
json_tokener::pb
struct printbuf * pb
Definition: json_tokener.h:72
json_tokener_reset
void json_tokener_reset(struct json_tokener *tok)
Definition: json_tokener.c:83
mc_debug
void mc_debug(const char *msg,...)
Definition: debug.c:58
json_tokener::depth
int depth
Definition: json_tokener.h:73
printbuf.h
json_tokener_state_object_value
@ json_tokener_state_object_value
Definition: json_tokener.h:54
json_c_strndup
char * json_c_strndup(const char *str, size_t n)
Definition: json_tokener.c:108
printbuf_memappend
int printbuf_memappend(struct printbuf *p, const char *buf, int size)
Definition: printbuf.c:43
saved_state
#define saved_state
Definition: json_tokener.c:129
bits.h
JSON_TOKENER_MAX_DEPTH
#define JSON_TOKENER_MAX_DEPTH
Definition: json_tokener.h:67
json_tokener::is_double
int is_double
Definition: json_tokener.h:73
json_tokener_state_comment_end
@ json_tokener_state_comment_end
Definition: json_tokener.h:42
json_tokener_state_object_sep
@ json_tokener_state_object_sep
Definition: json_tokener.h:56
json_tokener_error_parse_unexpected
@ json_tokener_error_parse_unexpected
Definition: json_tokener.h:22
json_tokener_error_parse_number
@ json_tokener_error_parse_number
Definition: json_tokener.h:25
json_tokener_state_object_field_end
@ json_tokener_state_object_field_end
Definition: json_tokener.h:53
printbuf_reset
void printbuf_reset(struct printbuf *p)
Definition: printbuf.c:132
json_tokener::ucs_char
unsigned int ucs_char
Definition: json_tokener.h:75
json_tokener_error_parse_string
@ json_tokener_error_parse_string
Definition: json_tokener.h:30
printbuf_free
void printbuf_free(struct printbuf *p)
Definition: printbuf.c:138
json_tokener_state_string
@ json_tokener_state_string
Definition: json_tokener.h:43
error_ptr
#define error_ptr(error)
Definition: bits.h:24
json_tokener_srec::saved_state
enum json_tokener_state state saved_state
Definition: json_tokener.h:61
json_object_put
void json_object_put(struct json_object *this)
Definition: json_object.c:144
json_tokener_state_escape_unicode
@ json_tokener_state_escape_unicode
Definition: json_tokener.h:45
printbuf_new
struct printbuf * printbuf_new()
Definition: printbuf.c:28
json_object.h
json_tokener_state_object_field_start
@ json_tokener_state_object_field_start
Definition: json_tokener.h:51
json_object_new_boolean
struct json_object * json_object_new_boolean(boolean b)
Definition: json_object.c:297
json_tokener_error_parse_object_key_name
@ json_tokener_error_parse_object_key_name
Definition: json_tokener.h:27
json_object_new_double
struct json_object * json_object_new_double(double d)
Definition: json_object.c:386
state
#define state
Definition: json_tokener.c:128
json_tokener_state_boolean
@ json_tokener_state_boolean
Definition: json_tokener.h:46
json_tokener_state_finish
@ json_tokener_state_finish
Definition: json_tokener.h:37
json_tokener_state_array
@ json_tokener_state_array
Definition: json_tokener.h:48
json_true_str
static const char * json_true_str
Definition: json_tokener.c:37
json_tokener_errors
const char * json_tokener_errors[]
Definition: json_tokener.c:40
json_tokener_srec::obj_field_name
char * obj_field_name
Definition: json_tokener.h:64
json_tokener::quote_char
char quote_char
Definition: json_tokener.h:76
hexdigit
#define hexdigit(x)
Definition: bits.h:23
json_tokener::err
enum json_tokener_error err
Definition: json_tokener.h:74
obj_field_name
#define obj_field_name
Definition: json_tokener.c:131
json_tokener_state_number
@ json_tokener_state_number
Definition: json_tokener.h:47
json_tokener_error_parse_eof
@ json_tokener_error_parse_eof
Definition: json_tokener.h:21
json_tokener_state_start
@ json_tokener_state_start
Definition: json_tokener.h:36
json_tokener.h
json_object_new_string
struct json_object * json_object_new_string(const char *s)
Definition: json_object.c:432
json_tokener_error_parse_null
@ json_tokener_error_parse_null
Definition: json_tokener.h:23
json_tokener_state_array_sep
@ json_tokener_state_array_sep
Definition: json_tokener.h:50
printbuf::buf
char * buf
Definition: printbuf.h:18
json_tokener_parse
struct json_object * json_tokener_parse(const char *str)
Definition: json_tokener.c:92
json_tokener_error_depth
@ json_tokener_error_depth
Definition: json_tokener.h:20
json_tokener_state_comment_eol
@ json_tokener_state_comment_eol
Definition: json_tokener.h:41
json_tokener_srec::current
struct json_object * current
Definition: json_tokener.h:63
json_tokener_error_parse_comment
@ json_tokener_error_parse_comment
Definition: json_tokener.h:31
json_tokener::stack
struct json_tokener_srec stack[JSON_TOKENER_MAX_DEPTH]
Definition: json_tokener.h:77
json_tokener_state_object_value_add
@ json_tokener_state_object_value_add
Definition: json_tokener.h:55
json_tokener_parse_ex
struct json_object * json_tokener_parse_ex(struct json_tokener *tok, const char *str, int len)
Definition: json_tokener.c:133
json_object
Definition: json_object_private.h:21
arraylist.h
json_object_array_add
int json_object_array_add(struct json_object *this, struct json_object *val)
Definition: json_object.c:522
json_tokener_new
struct json_tokener * json_tokener_new()
Definition: json_tokener.c:58
min
#define min(a, b)
Definition: bits.h:16
json_tokener_error_parse_boolean
@ json_tokener_error_parse_boolean
Definition: json_tokener.h:24
current
#define current
Definition: json_tokener.c:130
json_tokener::st_pos
int st_pos
Definition: json_tokener.h:73
debug.h
json_tokener_state_null
@ json_tokener_state_null
Definition: json_tokener.h:38
json_tokener_reset_level
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
Definition: json_tokener.c:73
json_tokener_error_parse_object_value_sep
@ json_tokener_error_parse_object_value_sep
Definition: json_tokener.h:29


csm
Author(s): Andrea Censi
autogenerated on Wed Aug 17 2022 02:50:33