1 /* vim: set et ts=3 sw=3 sts=3 ft=c:
2  *
3  * Copyright (C) 2012, 2013, 2014 James McLaughlin et al.  All rights reserved.
4  * https://github.com/udp/json-parser
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *   notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in the
15  *   documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #include "gravity_json.h"
31 #include "gravity_utils.h"
32 #include "gravity_memory.h"
33 #include "gravity_array.h"
34 #include "gravity_config.h"
35 
36 #include <inttypes.h>
37 #include <math.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <fcntl.h>
41 #include <ctype.h>
42 #include <assert.h>
43 
44 #ifdef _MSC_VER
45    #ifndef _CRT_SECURE_NO_WARNINGS
46       #define _CRT_SECURE_NO_WARNINGS
47    #endif
48 #endif
49 
50 // MARK: - JSON Serializer -
51 // Written by Marco Bambini
52 
53 #define JSON_MINSIZE            4096
54 #define JSON_NEWLINE            "\n"
55 #define JSON_NEWLINE_CHAR       '\n'
56 #define JSON_PRETTYLINE         "    "
57 #define JSON_PRETTYSIZE         4
58 #define JSON_WRITE_COLUMN       json_write_raw(json, ":", 1, false, false)
59 #define JSON_WRITE_COMMA        json_write_raw(json, ",", 1, false, false);
60 
61 #define JSON_POP_CTX(j)         marray_pop(j->context)
62 #define JSON_PUSH_CTX(j,x)      marray_push(JSON_CONTEXT, j->context, x);
63 #define JSON_CURR_CTX(j)        marray_last(j->context)
64 
65 #define JSON_ESCAPE(c)          do {        \
66                                     new_buffer[j] = '\\';     \
67                                     new_buffer[j+1] = (c);    \
68                                     j+=2;                     \
69                                 } while(0);                   \
70 
71 typedef enum {
72     JSON_CONTEXT_ROOT = 0,
73     JSON_CONTEXT_OBJECT = 1,
74     JSON_CONTEXT_ARRAY = 2
75 } JSON_CONTEXT;
76 typedef marray_t(JSON_CONTEXT)    JSON_CONTEXT_R;
77 
78 // MARK: -
79 
80 struct json_t {
81     char            *buffer;
82     size_t          blen;
83     size_t          bused;
84 
85     const char      *label;
86     uint32_t        options;
87     JSON_CONTEXT_R  context;
88 };
89 
json_new(void)90 json_t *json_new (void) {
91     json_t *json = mem_alloc(NULL, sizeof(json_t));
92     assert(json);
93 
94     json->buffer = mem_alloc(NULL, JSON_MINSIZE);
95     assert(json->buffer);
96 
97     json->blen = JSON_MINSIZE;
98     json->bused = 0;
99     json->options = json_opt_none;
100     marray_init(json->context);
101     marray_push(JSON_CONTEXT, json->context, JSON_CONTEXT_ROOT);
102 
103     return json;
104 }
105 
json_free(json_t * json)106 void json_free (json_t *json) {
107     JSON_CONTEXT context = marray_pop(json->context);
108     if (context != JSON_CONTEXT_ROOT) assert(0);
109 
110     marray_destroy(json->context);
111     mem_free(json->buffer);
112     mem_free(json);
113 }
114 
115 // MARK: - Private
116 
json_write_raw(json_t * json,const char * buffer,size_t len,bool escape,bool is_pretty)117 static void json_write_raw (json_t *json, const char *buffer, size_t len, bool escape, bool is_pretty) {
118     // pretty output disabled in this version
119     is_pretty = false;
120 
121     bool      pretty_mask = json_option_isset(json, json_opt_prettify);
122     uint32_t  ident_count = ((uint32_t) marray_size(json->context)) - 1;
123     size_t    prettylen = (is_pretty && pretty_mask) ? (ident_count * JSON_PRETTYSIZE) : 0;
124     size_t    escapelen = (escape) ? 2 : 0;
125 
126     // check buffer reallocation
127     size_t reqlen = json->bused + len + prettylen + escapelen + JSON_MINSIZE;
128     if (reqlen >= json->blen) {
129         json->buffer = mem_realloc(NULL, json->buffer, json->blen + reqlen);
130         assert(json->buffer);
131         json->blen += reqlen;
132     }
133 
134     if (is_pretty && pretty_mask) {
135         for (uint32_t i=0; i<ident_count; ++i) {
136             memcpy(json->buffer+json->bused, JSON_PRETTYLINE, JSON_PRETTYSIZE);
137             json->bused += JSON_PRETTYSIZE;
138         }
139     }
140 
141     if (escape) {
142         memcpy(json->buffer+json->bused, "\"", 1);
143         json->bused += 1;
144     }
145 
146     memcpy(json->buffer+json->bused, buffer, len);
147     json->bused += len;
148 
149     if (escape) {
150         memcpy(json->buffer+json->bused, "\"", 1);
151         json->bused += 1;
152     }
153 }
154 
json_write_escaped(json_t * json,const char * buffer,size_t len,bool escape,bool is_pretty)155 static void json_write_escaped (json_t *json, const char *buffer, size_t len, bool escape, bool is_pretty) {
156     if (!len) {
157         json_write_raw(json, "", 0, escape, is_pretty);
158         return;
159     }
160 
161     char *new_buffer = mem_alloc(NULL, len*2);
162     size_t j = 0;
163     assert(new_buffer);
164 
165     for (size_t i=0; i<len; ++i) {
166         char c = buffer[i];
167         switch (c) {
168             case '"' : JSON_ESCAPE ('\"');  continue;
169             case '\\': JSON_ESCAPE ('\\');  continue;
170             case '\b': JSON_ESCAPE ('b');   continue;
171             case '\f': JSON_ESCAPE ('f');   continue;
172             case '\n': JSON_ESCAPE ('n');   continue;
173             case '\r': JSON_ESCAPE ('r');   continue;
174             case '\t': JSON_ESCAPE ('t');   continue;
175 
176             default: new_buffer[j] = c; ++j;break;
177         };
178     }
179 
180     json_write_raw(json, new_buffer, j, escape, is_pretty);
181     mem_free(new_buffer);
182 }
183 
json_check_comma(json_t * json)184 static void json_check_comma (json_t *json) {
185     if (json_option_isset(json, json_opt_need_comma)) {
186         JSON_WRITE_COMMA;
187     } else {
188         json_set_option(json, json_opt_need_comma);
189     }
190 }
191 
192 // MARK: - Public
193 
json_begin_object(json_t * json,const char * key)194 void json_begin_object (json_t *json, const char *key) {
195     json_check_comma(json);
196 
197     // ignore given key if not inside an object
198     if (JSON_CURR_CTX(json) != JSON_CONTEXT_OBJECT) {
199         key = NULL;
200     }
201 
202     if (key) {
203         json_write_raw (json, key, strlen(key), true, true);
204         JSON_WRITE_COLUMN;
205     }
206 
207     JSON_PUSH_CTX(json, JSON_CONTEXT_OBJECT);
208     json_write_raw(json, "{", 1, false, (key == NULL));
209 
210     json_clear_option(json, json_opt_need_comma);
211 }
212 
json_end_object(json_t * json)213 void json_end_object (json_t *json) {
214     JSON_POP_CTX(json);
215 
216     json_set_option(json, json_opt_need_comma);
217     json_write_raw(json, "}", 1, false, true);
218 }
219 
json_begin_array(json_t * json,const char * key)220 void json_begin_array (json_t *json, const char *key) {
221     json_check_comma(json);
222 
223     // ignore given key if not inside an object
224     if (JSON_CURR_CTX(json) != JSON_CONTEXT_OBJECT) {
225         key = NULL;
226     }
227 
228     if (key) {
229         json_write_raw (json, key, strlen(key), true, true);
230         JSON_WRITE_COLUMN;
231     }
232 
233     JSON_PUSH_CTX(json, JSON_CONTEXT_ARRAY);
234     json_write_raw(json, "[", 1, false, (key == NULL));
235 
236     json_clear_option(json, json_opt_need_comma);
237 }
238 
json_end_array(json_t * json)239 void json_end_array (json_t *json) {
240     JSON_POP_CTX(json);
241 
242     json_set_option(json, json_opt_need_comma);
243     json_write_raw(json, "]", 1, false, true);
244 }
245 
json_add_string(json_t * json,const char * key,const char * value,size_t len)246 void json_add_string (json_t *json, const char *key, const char *value, size_t len) {
247     json_check_comma(json);
248 
249     if (!value) {
250         json_add_null(json, key);
251         return;
252     }
253 
254     if (key) {
255         json_write_raw (json, key, strlen(key), true, true);
256         JSON_WRITE_COLUMN;
257     }
258 
259     // check if string value needs to be escaped
260     bool write_escaped = false;
261     for (size_t i=0; i<len; ++i) {
262         if (value[i] == '"') {write_escaped = true; break;}
263     }
264     if (len == 0) write_escaped = true;
265 
266     if (write_escaped)
267         json_write_escaped(json, value, len, true, (key == NULL));
268     else
269         json_write_raw(json, value, len, true, (key == NULL));
270 }
271 
json_add_cstring(json_t * json,const char * key,const char * value)272 void json_add_cstring (json_t *json, const char *key, const char *value) {
273     json_add_string(json, key, value, (value) ? strlen(value) : 0);
274 }
275 
json_add_int(json_t * json,const char * key,int64_t value)276 void json_add_int (json_t *json, const char *key, int64_t value) {
277     json_check_comma(json);
278 
279     char buffer[512];
280     size_t len = snprintf(buffer, sizeof(buffer), "%" PRId64, value);
281 
282     if (key) {
283         json_write_raw (json, key, strlen(key), true, true);
284         JSON_WRITE_COLUMN;
285     }
286 
287     json_write_raw(json, buffer, len, false, (key == NULL));
288 }
289 
json_add_double(json_t * json,const char * key,double value)290 void json_add_double (json_t *json, const char *key, double value) {
291     json_check_comma(json);
292 
293     char buffer[512];
294     // was %g but we don't like scientific notation nor the missing .0 in case of float number with no decimals
295     size_t len = snprintf(buffer, sizeof(buffer), "%f", value);
296 
297     if (key) {
298         json_write_raw (json, key, strlen(key), true, true);
299         JSON_WRITE_COLUMN;
300     }
301 
302     json_write_raw(json, buffer, len, false, (key == NULL));
303 }
304 
json_add_bool(json_t * json,const char * key,bool bvalue)305 void json_add_bool (json_t *json, const char *key, bool bvalue) {
306     json_check_comma(json);
307 
308     const char *value = (bvalue) ? "true" : "false";
309 
310     if (key) {
311         json_write_raw (json, key, strlen(key), true, true);
312         JSON_WRITE_COLUMN;
313     }
314 
315     json_write_raw(json, value, strlen(value), false, (key == NULL));
316 }
317 
json_add_null(json_t * json,const char * key)318 void json_add_null (json_t *json, const char *key) {
319     json_check_comma (json);
320 
321     if (key) {
322         json_write_raw (json, key, strlen(key), true, true);
323         JSON_WRITE_COLUMN;
324     }
325 
326     json_write_raw(json, "null", 4, false, (key == NULL));
327 }
328 
json_set_label(json_t * json,const char * key)329 void json_set_label (json_t *json, const char *key) {
330     if (JSON_CURR_CTX(json) != JSON_CONTEXT_OBJECT) return;
331     json->label = key;
332 }
333 
json_get_label(json_t * json,const char * key)334 const char *json_get_label (json_t *json, const char *key) {
335     if (JSON_CURR_CTX(json) != JSON_CONTEXT_OBJECT) return NULL;
336 
337     if (json->label) {
338         const char *result = json->label;
339         json->label = NULL;
340         return result;
341     }
342 
343     if (key) return key;
344     assert(0);
345 	return NULL;
346 }
347 
348 // MARK: - Buffer
349 
json_buffer(json_t * json,size_t * len)350 char *json_buffer (json_t *json, size_t *len) {
351     assert(json->buffer);
352     if (len) *len = json->bused;
353     return json->buffer;
354 }
355 
json_write_file(json_t * json,const char * path)356 bool json_write_file (json_t *json, const char *path) {
357     return file_write(path, json->buffer, json->bused);
358 }
359 
360 // MARK: - Options
361 
json_get_options(json_t * json)362 uint32_t json_get_options (json_t *json) {
363     return json->options;
364 }
365 
json_set_option(json_t * json,json_opt_mask option_value)366 void json_set_option (json_t *json, json_opt_mask option_value) {
367     json->options |= option_value;
368 }
369 
json_option_isset(json_t * json,json_opt_mask option_value)370 bool json_option_isset (json_t *json, json_opt_mask option_value) {
371     return (json->options & option_value);
372 }
373 
json_clear_option(json_t * json,json_opt_mask option_value)374 void json_clear_option (json_t *json, json_opt_mask option_value) {
375     json->options &= ~option_value;
376 }
377 
378 #undef JSON_MINSIZE
379 #undef JSON_NEWLINE
380 #undef JSON_NEWLINE_CHAR
381 #undef JSON_PRETTYLINE
382 #undef JSON_PRETTYSIZE
383 #undef JSON_WRITE_SEP
384 #undef JSON_TERM_FIELD
385 
386 // MARK: - JSON Parser -
387 // Written by https://github.com/udp/json-parser
388 
389 const struct _json_value json_value_none;
390 typedef unsigned int json_uchar;
391 
hex_value(json_char c)392 static unsigned char hex_value (json_char c)
393 {
394    if (isdigit(c))
395       return c - '0';
396 
397    switch (c) {
398       case 'a': case 'A': return 0x0A;
399       case 'b': case 'B': return 0x0B;
400       case 'c': case 'C': return 0x0C;
401       case 'd': case 'D': return 0x0D;
402       case 'e': case 'E': return 0x0E;
403       case 'f': case 'F': return 0x0F;
404       default: return 0xFF;
405    }
406 }
407 
408 typedef struct
409 {
410    unsigned long used_memory;
411 
412    unsigned int uint_max;
413    unsigned long ulong_max;
414 
415    json_settings settings;
416    int first_pass;
417 
418    const json_char * ptr;
419    unsigned int cur_line, cur_col;
420 
421 } json_state;
422 
default_alloc(size_t size,int zero,void * user_data)423 static void * default_alloc (size_t size, int zero, void * user_data)
424 {
425     #pragma unused(zero, user_data)
426     return mem_alloc(NULL, size);
427     //return zero ? calloc (1, size) : malloc (size);
428 }
429 
default_free(void * ptr,void * user_data)430 static void default_free (void * ptr, void * user_data)
431 {
432     #pragma unused(user_data)
433     mem_free(ptr);
434     //free (ptr);
435 }
436 
json_alloc(json_state * state,unsigned long size,int zero)437 static void * json_alloc (json_state * state, unsigned long size, int zero)
438 {
439    if ((state->ulong_max - state->used_memory) < size)
440       return 0;
441 
442    if (state->settings.max_memory
443          && (state->used_memory += size) > state->settings.max_memory)
444    {
445       return 0;
446    }
447 
448    return state->settings.memory_alloc (size, zero, state->settings.user_data);
449 }
450 
new_value(json_state * state,json_value ** top,json_value ** root,json_value ** alloc,json_type type)451 static int new_value (json_state * state,
452                       json_value ** top, json_value ** root, json_value ** alloc,
453                       json_type type)
454 {
455    json_value * value;
456    int values_size;
457 
458    if (!state->first_pass)
459    {
460       value = *top = *alloc;
461       *alloc = (*alloc)->_reserved.next_alloc;
462 
463       if (!*root)
464          *root = value;
465 
466       switch (value->type)
467       {
468          case json_array:
469 
470             if (value->u.array.length == 0)
471                break;
472 
473             if (! (value->u.array.values = (json_value **) json_alloc
474                (state, value->u.array.length * sizeof (json_value *), 0)) )
475             {
476                return 0;
477             }
478 
479             value->u.array.length = 0;
480             break;
481 
482          case json_object:
483 
484             if (value->u.object.length == 0)
485                break;
486 
487             values_size = sizeof (*value->u.object.values) * value->u.object.length;
488 
489             if (! (value->u.object.values = (json_object_entry *) json_alloc
490                   (state, values_size + ((unsigned long) value->u.object.values), 0)) )
491             {
492                return 0;
493             }
494 
495             value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;
496 
497             value->u.object.length = 0;
498             break;
499 
500          case json_string:
501 
502             if (! (value->u.string.ptr = (json_char *) json_alloc
503                (state, (value->u.string.length + 1) * sizeof (json_char), 0)) )
504             {
505                return 0;
506             }
507 
508             value->u.string.length = 0;
509             break;
510 
511          default:
512             break;
513       };
514 
515       return 1;
516    }
517 
518    if (! (value = (json_value *) json_alloc
519          (state, (unsigned long)(sizeof (json_value) + state->settings.value_extra), 1)))
520    {
521       return 0;
522    }
523 
524    if (!*root)
525       *root = value;
526 
527    value->type = type;
528    value->parent = *top;
529 
530    #ifdef JSON_TRACK_SOURCE
531       value->line = state->cur_line;
532       value->col = state->cur_col;
533    #endif
534 
535    if (*alloc)
536       (*alloc)->_reserved.next_alloc = value;
537 
538    *alloc = *top = value;
539 
540    return 1;
541 }
542 
543 #define whitespace \
544    case '\n': ++ state.cur_line;  state.cur_col = 0; \
545    case ' ': case '\t': case '\r'
546 
547 #define string_add(b)  \
548    do { if (!state.first_pass) string [string_length] = b;  ++ string_length; } while (0);
549 
550 #define line_and_col \
551    state.cur_line, state.cur_col
552 
553 static const long
554    flag_next             = 1 << 0,
555    flag_reproc           = 1 << 1,
556    flag_need_comma       = 1 << 2,
557    flag_seek_value       = 1 << 3,
558    flag_escaped          = 1 << 4,
559    flag_string           = 1 << 5,
560    flag_need_colon       = 1 << 6,
561    flag_done             = 1 << 7,
562    flag_num_negative     = 1 << 8,
563    flag_num_zero         = 1 << 9,
564    flag_num_e            = 1 << 10,
565    flag_num_e_got_sign   = 1 << 11,
566    flag_num_e_negative   = 1 << 12,
567    flag_line_comment     = 1 << 13,
568    flag_block_comment    = 1 << 14;
569 
json_parse_ex(json_settings * settings,const json_char * json,size_t length,char * error_buf)570 json_value * json_parse_ex (json_settings * settings,
571                             const json_char * json,
572                             size_t length,
573                             char * error_buf)
574 {
575    json_char error [json_error_max];
576    const json_char * end;
577    json_value *top, *root = NULL, * alloc = 0;
578    json_state state = EMPTY_STATE_STRUCT;
579    long flags;
580    long num_digits = 0, num_e = 0;
581    json_int_t num_fraction = 0;
582 
583    /* Skip UTF-8 BOM
584     */
585    if (length >= 3 && ((unsigned char) json [0]) == 0xEF
586                    && ((unsigned char) json [1]) == 0xBB
587                    && ((unsigned char) json [2]) == 0xBF)
588    {
589       json += 3;
590       length -= 3;
591    }
592 
593    error[0] = '\0';
594    end = (json + length);
595 
596    memcpy (&state.settings, settings, sizeof (json_settings));
597 
598    if (!state.settings.memory_alloc)
599       state.settings.memory_alloc = default_alloc;
600 
601    if (!state.settings.memory_free)
602       state.settings.memory_free = default_free;
603 
604    memset (&state.uint_max, 0xFF, sizeof (state.uint_max));
605    memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max));
606 
607    state.uint_max -= 8; /* limit of how much can be added before next check */
608    state.ulong_max -= 8;
609 
610    for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass)
611    {
612       json_uchar uchar;
613       unsigned char uc_b1, uc_b2, uc_b3, uc_b4;
614       json_char * string = 0;
615       unsigned int string_length = 0;
616 
617       top = root = 0;
618       flags = flag_seek_value;
619 
620       state.cur_line = 1;
621 
622       for (state.ptr = json ;; ++ state.ptr)
623       {
624          json_char b = (state.ptr == end ? 0 : *state.ptr);
625 
626          if (flags & flag_string)
627          {
628             if (!b)
629             {  sprintf (error, "Unexpected EOF in string (at %d:%d)", line_and_col);
630                goto e_failed;
631             }
632 
633             if (string_length > state.uint_max)
634                goto e_overflow;
635 
636             if (flags & flag_escaped)
637             {
638                flags &= ~ flag_escaped;
639 
640                switch (b)
641                {
642                   case 'b':  string_add ('\b');  break;
643                   case 'f':  string_add ('\f');  break;
644                   case 'n':  string_add ('\n');  break;
645                   case 'r':  string_add ('\r');  break;
646                   case 't':  string_add ('\t');  break;
647                   case 'u':
648 
649                     if (end - state.ptr < 4 ||
650                         (uc_b1 = hex_value (*++ state.ptr)) == 0xFF ||
651                         (uc_b2 = hex_value (*++ state.ptr)) == 0xFF ||
652                         (uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
653                         (uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
654                     {
655                         sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col);
656                         goto e_failed;
657                     }
658 
659                     uc_b1 = (uc_b1 << 4) | uc_b2;
660                     uc_b2 = (uc_b3 << 4) | uc_b4;
661                     uchar = (uc_b1 << 8) | uc_b2;
662 
663                     if ((uchar & 0xF800) == 0xD800) {
664                         json_uchar uchar2;
665 
666                         if (end - state.ptr < 6 || (*++ state.ptr) != '\\' || (*++ state.ptr) != 'u' ||
667                             (uc_b1 = hex_value (*++ state.ptr)) == 0xFF ||
668                             (uc_b2 = hex_value (*++ state.ptr)) == 0xFF ||
669                             (uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
670                             (uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
671                         {
672                             sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col);
673                             goto e_failed;
674                         }
675 
676                         uc_b1 = (uc_b1 << 4) | uc_b2;
677                         uc_b2 = (uc_b3 << 4) | uc_b4;
678                         uchar2 = (uc_b1 << 8) | uc_b2;
679 
680                         uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF);
681                     }
682 
683                     if (sizeof (json_char) >= sizeof (json_uchar) || (uchar <= 0x7F))
684                     {
685                        string_add ((json_char) uchar);
686                        break;
687                     }
688 
689                     if (uchar <= 0x7FF)
690                     {
691                         if (state.first_pass)
692                            string_length += 2;
693                         else
694                         {  string [string_length ++] = 0xC0 | (uchar >> 6);
695                            string [string_length ++] = 0x80 | (uchar & 0x3F);
696                         }
697 
698                         break;
699                     }
700 
701                     if (uchar <= 0xFFFF) {
702                         if (state.first_pass)
703                            string_length += 3;
704                         else
705                         {  string [string_length ++] = 0xE0 | (uchar >> 12);
706                            string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
707                            string [string_length ++] = 0x80 | (uchar & 0x3F);
708                         }
709 
710                         break;
711                     }
712 
713                     if (state.first_pass)
714                        string_length += 4;
715                     else
716                     {  string [string_length ++] = 0xF0 | (uchar >> 18);
717                        string [string_length ++] = 0x80 | ((uchar >> 12) & 0x3F);
718                        string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
719                        string [string_length ++] = 0x80 | (uchar & 0x3F);
720                     }
721 
722                     break;
723 
724                   default:
725                      string_add (b);
726                };
727 
728                continue;
729             }
730 
731             if (b == '\\')
732             {
733                flags |= flag_escaped;
734                continue;
735             }
736 
737             if (b == '"')
738             {
739                if (!state.first_pass)
740                   string [string_length] = 0;
741 
742                flags &= ~ flag_string;
743                string = 0;
744 
745                switch (top->type)
746                {
747                   case json_string:
748 
749                      top->u.string.length = string_length;
750                      flags |= flag_next;
751 
752                      break;
753 
754                   case json_object:
755 
756                      if (state.first_pass)
757                         (*(json_char **) &top->u.object.values) += string_length + 1;
758                      else
759                      {
760                         top->u.object.values [top->u.object.length].name
761                            = (json_char *) top->_reserved.object_mem;
762 
763                         top->u.object.values [top->u.object.length].name_length
764                            = string_length;
765 
766                         (*(json_char **) &top->_reserved.object_mem) += string_length + 1;
767                      }
768 
769                      flags |= flag_seek_value | flag_need_colon;
770                      continue;
771 
772                   default:
773                      break;
774                };
775             }
776             else
777             {
778                string_add (b);
779                continue;
780             }
781          }
782 
783          if (state.settings.settings & json_enable_comments)
784          {
785             if (flags & (flag_line_comment | flag_block_comment))
786             {
787                if (flags & flag_line_comment)
788                {
789                   if (b == '\r' || b == '\n' || !b)
790                   {
791                      flags &= ~ flag_line_comment;
792                      -- state.ptr;  /* so null can be reproc'd */
793                   }
794 
795                   continue;
796                }
797 
798                if (flags & flag_block_comment)
799                {
800                   if (!b)
801                   {  sprintf (error, "%d:%d: Unexpected EOF in block comment", line_and_col);
802                      goto e_failed;
803                   }
804 
805                   if (b == '*' && state.ptr < (end - 1) && state.ptr [1] == '/')
806                   {
807                      flags &= ~ flag_block_comment;
808                      ++ state.ptr;  /* skip closing sequence */
809                   }
810 
811                   continue;
812                }
813             }
814             else if (b == '/')
815             {
816                if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)
817                {  sprintf (error, "%d:%d: Comment not allowed here", line_and_col);
818                   goto e_failed;
819                }
820 
821                if (++ state.ptr == end)
822                {  sprintf (error, "%d:%d: EOF unexpected", line_and_col);
823                   goto e_failed;
824                }
825 
826                switch (b = *state.ptr)
827                {
828                   case '/':
829                      flags |= flag_line_comment;
830                      continue;
831 
832                   case '*':
833                      flags |= flag_block_comment;
834                      continue;
835 
836                   default:
837                      sprintf (error, "%d:%d: Unexpected `%c` in comment opening sequence", line_and_col, b);
838                      goto e_failed;
839                };
840             }
841          }
842 
843          if (flags & flag_done)
844          {
845             if (!b)
846                break;
847 
848             switch (b)
849             {
850                whitespace:
851                   continue;
852 
853                default:
854 
855                   sprintf (error, "%d:%d: Trailing garbage: `%c`",
856                            state.cur_line, state.cur_col, b);
857 
858                   goto e_failed;
859             };
860          }
861 
862          if (flags & flag_seek_value)
863          {
864             switch (b)
865             {
866                whitespace:
867                   continue;
868 
869                case ']':
870 
871                   if (top && top->type == json_array)
872                      flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
873                   else
874                   {  sprintf (error, "%d:%d: Unexpected ]", line_and_col);
875                      goto e_failed;
876                   }
877 
878                   break;
879 
880                default:
881 
882                   if (flags & flag_need_comma)
883                   {
884                      if (b == ',')
885                      {  flags &= ~ flag_need_comma;
886                         continue;
887                      }
888                      else
889                      {
890                         sprintf (error, "%d:%d: Expected , before %c",
891                                  state.cur_line, state.cur_col, b);
892 
893                         goto e_failed;
894                      }
895                   }
896 
897                   if (flags & flag_need_colon)
898                   {
899                      if (b == ':')
900                      {  flags &= ~ flag_need_colon;
901                         continue;
902                      }
903                      else
904                      {
905                         sprintf (error, "%d:%d: Expected : before %c",
906                                  state.cur_line, state.cur_col, b);
907 
908                         goto e_failed;
909                      }
910                   }
911 
912                   flags &= ~ flag_seek_value;
913 
914                   switch (b)
915                   {
916                      case '{':
917 
918                         if (!new_value (&state, &top, &root, &alloc, json_object))
919                            goto e_alloc_failure;
920 
921                         continue;
922 
923                      case '[':
924 
925                         if (!new_value (&state, &top, &root, &alloc, json_array))
926                            goto e_alloc_failure;
927 
928                         flags |= flag_seek_value;
929                         continue;
930 
931                      case '"':
932 
933                         if (!new_value (&state, &top, &root, &alloc, json_string))
934                            goto e_alloc_failure;
935 
936                         flags |= flag_string;
937 
938                         string = top->u.string.ptr;
939                         string_length = 0;
940 
941                         continue;
942 
943                      case 't':
944 
945                         if ((end - state.ptr) < 3 || *(++ state.ptr) != 'r' ||
946                             *(++ state.ptr) != 'u' || *(++ state.ptr) != 'e')
947                         {
948                            goto e_unknown_value;
949                         }
950 
951                         if (!new_value (&state, &top, &root, &alloc, json_boolean))
952                            goto e_alloc_failure;
953 
954                         top->u.boolean = 1;
955 
956                         flags |= flag_next;
957                         break;
958 
959                      case 'f':
960 
961                         if ((end - state.ptr) < 4 || *(++ state.ptr) != 'a' ||
962                             *(++ state.ptr) != 'l' || *(++ state.ptr) != 's' ||
963                             *(++ state.ptr) != 'e')
964                         {
965                            goto e_unknown_value;
966                         }
967 
968                         if (!new_value (&state, &top, &root, &alloc, json_boolean))
969                            goto e_alloc_failure;
970 
971                         flags |= flag_next;
972                         break;
973 
974                      case 'n':
975 
976                         if ((end - state.ptr) < 3 || *(++ state.ptr) != 'u' ||
977                             *(++ state.ptr) != 'l' || *(++ state.ptr) != 'l')
978                         {
979                            goto e_unknown_value;
980                         }
981 
982                         if (!new_value (&state, &top, &root, &alloc, json_null))
983                            goto e_alloc_failure;
984 
985                         flags |= flag_next;
986                         break;
987 
988                      default:
989 
990                         if (isdigit (b) || b == '-')
991                         {
992                            if (!new_value (&state, &top, &root, &alloc, json_integer))
993                               goto e_alloc_failure;
994 
995                            if (!state.first_pass)
996                            {
997                               while (isdigit (b) || b == '+' || b == '-'
998                                         || b == 'e' || b == 'E' || b == '.')
999                               {
1000                                  if ( (++ state.ptr) == end)
1001                                  {
1002                                     b = 0;
1003                                     break;
1004                                  }
1005 
1006                                  b = *state.ptr;
1007                               }
1008 
1009                               flags |= flag_next | flag_reproc;
1010                               break;
1011                            }
1012 
1013                            flags &= ~ (flag_num_negative | flag_num_e |
1014                                         flag_num_e_got_sign | flag_num_e_negative |
1015                                            flag_num_zero);
1016 
1017                            num_digits = 0;
1018                            num_fraction = 0;
1019                            num_e = 0;
1020 
1021                            if (b != '-')
1022                            {
1023                               flags |= flag_reproc;
1024                               break;
1025                            }
1026 
1027                            flags |= flag_num_negative;
1028                            continue;
1029                         }
1030                         else
1031                         {  sprintf (error, "%d:%d: Unexpected %c when seeking value", line_and_col, b);
1032                            goto e_failed;
1033                         }
1034                   };
1035             };
1036          }
1037          else
1038          {
1039             switch (top->type)
1040             {
1041             case json_object:
1042 
1043                switch (b)
1044                {
1045                   whitespace:
1046                      continue;
1047 
1048                   case '"':
1049 
1050                      if (flags & flag_need_comma)
1051                      {  sprintf (error, "%d:%d: Expected , before \"", line_and_col);
1052                         goto e_failed;
1053                      }
1054 
1055                      flags |= flag_string;
1056 
1057                      string = (json_char *) top->_reserved.object_mem;
1058                      string_length = 0;
1059 
1060                      break;
1061 
1062                   case '}':
1063 
1064                      flags = (flags & ~ flag_need_comma) | flag_next;
1065                      break;
1066 
1067                   case ',':
1068 
1069                      if (flags & flag_need_comma)
1070                      {
1071                         flags &= ~ flag_need_comma;
1072                         break;
1073                      }
1074 
1075                   default:
1076                      sprintf (error, "%d:%d: Unexpected `%c` in object", line_and_col, b);
1077                      goto e_failed;
1078                };
1079 
1080                break;
1081 
1082             case json_integer:
1083             case json_double:
1084 
1085                if (isdigit (b))
1086                {
1087                   ++ num_digits;
1088 
1089                   if (top->type == json_integer || flags & flag_num_e)
1090                   {
1091                      if (! (flags & flag_num_e))
1092                      {
1093                         if (flags & flag_num_zero)
1094                         {  sprintf (error, "%d:%d: Unexpected `0` before `%c`", line_and_col, b);
1095                            goto e_failed;
1096                         }
1097 
1098                         if (num_digits == 1 && b == '0')
1099                            flags |= flag_num_zero;
1100                      }
1101                      else
1102                      {
1103                         flags |= flag_num_e_got_sign;
1104                         num_e = (num_e * 10) + (b - '0');
1105                         continue;
1106                      }
1107 
1108                      top->u.integer = (top->u.integer * 10) + (b - '0');
1109                      continue;
1110                   }
1111 
1112                   num_fraction = (num_fraction * 10) + (b - '0');
1113                   continue;
1114                }
1115 
1116                if (b == '+' || b == '-')
1117                {
1118                   if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign))
1119                   {
1120                      flags |= flag_num_e_got_sign;
1121 
1122                      if (b == '-')
1123                         flags |= flag_num_e_negative;
1124 
1125                      continue;
1126                   }
1127                }
1128                else if (b == '.' && top->type == json_integer)
1129                {
1130                   if (!num_digits)
1131                   {  sprintf (error, "%d:%d: Expected digit before `.`", line_and_col);
1132                      goto e_failed;
1133                   }
1134 
1135                   top->type = json_double;
1136                   top->u.dbl = (double) top->u.integer;
1137 
1138                   num_digits = 0;
1139                   continue;
1140                }
1141 
1142                if (! (flags & flag_num_e))
1143                {
1144                   if (top->type == json_double)
1145                   {
1146                      if (!num_digits)
1147                      {  sprintf (error, "%d:%d: Expected digit after `.`", line_and_col);
1148                         goto e_failed;
1149                      }
1150 
1151                      top->u.dbl += ((double) num_fraction) / (pow (10.0, (double) num_digits));
1152                   }
1153 
1154                   if (b == 'e' || b == 'E')
1155                   {
1156                      flags |= flag_num_e;
1157 
1158                      if (top->type == json_integer)
1159                      {
1160                         top->type = json_double;
1161                         top->u.dbl = (double) top->u.integer;
1162                      }
1163 
1164                      num_digits = 0;
1165                      flags &= ~ flag_num_zero;
1166 
1167                      continue;
1168                   }
1169                }
1170                else
1171                {
1172                   if (!num_digits)
1173                   {  sprintf (error, "%d:%d: Expected digit after `e`", line_and_col);
1174                      goto e_failed;
1175                   }
1176 
1177                   top->u.dbl *= pow (10.0, (double)
1178                       (flags & flag_num_e_negative ? - num_e : num_e));
1179                }
1180 
1181                if (flags & flag_num_negative)
1182                {
1183                   if (top->type == json_integer)
1184                      top->u.integer = - top->u.integer;
1185                   else
1186                      top->u.dbl = - top->u.dbl;
1187                }
1188 
1189                flags |= flag_next | flag_reproc;
1190                break;
1191 
1192             default:
1193                break;
1194             };
1195          }
1196 
1197          if (flags & flag_reproc)
1198          {
1199             flags &= ~ flag_reproc;
1200             -- state.ptr;
1201          }
1202 
1203          if (flags & flag_next)
1204          {
1205             flags = (flags & ~ flag_next) | flag_need_comma;
1206 
1207             if (!top->parent)
1208             {
1209                /* root value done */
1210 
1211                flags |= flag_done;
1212                continue;
1213             }
1214 
1215             if (top->parent->type == json_array)
1216                flags |= flag_seek_value;
1217 
1218             if (!state.first_pass)
1219             {
1220                json_value * parent = top->parent;
1221 
1222                switch (parent->type)
1223                {
1224                   case json_object:
1225 
1226                      parent->u.object.values
1227                         [parent->u.object.length].value = top;
1228 
1229                      break;
1230 
1231                   case json_array:
1232 
1233                      parent->u.array.values
1234                            [parent->u.array.length] = top;
1235 
1236                      break;
1237 
1238                   default:
1239                      break;
1240                };
1241             }
1242 
1243             if ( (++ top->parent->u.array.length) > state.uint_max)
1244                goto e_overflow;
1245 
1246             top = top->parent;
1247 
1248             continue;
1249          }
1250       }
1251 
1252       alloc = root;
1253    }
1254 
1255    return root;
1256 
1257 e_unknown_value:
1258 
1259    sprintf (error, "%d:%d: Unknown value", line_and_col);
1260    goto e_failed;
1261 
1262 e_alloc_failure:
1263 
1264    strcpy (error, "Memory allocation failure");
1265    goto e_failed;
1266 
1267 e_overflow:
1268 
1269    sprintf (error, "%d:%d: Too long (caught overflow)", line_and_col);
1270    goto e_failed;
1271 
1272 e_failed:
1273 
1274    if (error_buf)
1275    {
1276       if (*error)
1277          strcpy (error_buf, error);
1278       else
1279          strcpy (error_buf, "Unknown error");
1280    }
1281 
1282    if (state.first_pass)
1283       alloc = root;
1284 
1285    while (alloc)
1286    {
1287       top = alloc->_reserved.next_alloc;
1288       state.settings.memory_free (alloc, state.settings.user_data);
1289       alloc = top;
1290    }
1291 
1292    if (!state.first_pass)
1293       json_value_free_ex (&state.settings, root);
1294 
1295    return 0;
1296 }
1297 
json_parse(const json_char * json,size_t length)1298 json_value * json_parse (const json_char * json, size_t length)
1299 {
1300    json_settings settings = EMPTY_SETTINGS_STRUCT;
1301    return json_parse_ex (&settings, json, length, 0);
1302 }
1303 
json_value_free_ex(json_settings * settings,json_value * value)1304 void json_value_free_ex (json_settings * settings, json_value * value)
1305 {
1306    json_value * cur_value;
1307 
1308    if (!value)
1309       return;
1310 
1311    value->parent = 0;
1312 
1313    while (value)
1314    {
1315       switch (value->type)
1316       {
1317          case json_array:
1318 
1319             if (!value->u.array.length)
1320             {
1321                if (value->u.array.values) settings->memory_free (value->u.array.values, settings->user_data);
1322                break;
1323             }
1324 
1325             value = value->u.array.values [-- value->u.array.length];
1326             continue;
1327 
1328          case json_object:
1329 
1330             if (!value->u.object.length)
1331             {
1332                settings->memory_free (value->u.object.values, settings->user_data);
1333                break;
1334             }
1335 
1336             value = value->u.object.values [-- value->u.object.length].value;
1337             continue;
1338 
1339          case json_string:
1340 
1341             settings->memory_free (value->u.string.ptr, settings->user_data);
1342             break;
1343 
1344          default:
1345             break;
1346       };
1347 
1348       cur_value = value;
1349       value = value->parent;
1350       settings->memory_free (cur_value, settings->user_data);
1351    }
1352 }
1353 
json_value_free(json_value * value)1354 void json_value_free (json_value * value)
1355 {
1356    json_settings settings = EMPTY_SETTINGS_STRUCT;
1357    settings.memory_free = default_free;
1358    json_value_free_ex (&settings, value);
1359 }
1360