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 "json.h"
31
32#ifdef _MSC_VER
33 #ifndef _CRT_SECURE_NO_WARNINGS
34 #define _CRT_SECURE_NO_WARNINGS
35 #endif
36#endif
37
38const struct _json_value json_value_none;
39
40#include <stdio.h>
41#include <string.h>
42#include <ctype.h>
43#include <math.h>
44
45typedef unsigned int json_uchar;
46
47static unsigned char hex_value (json_char c)
48{
49 if (isdigit(c))
50 return c - '0';
51
52 switch (c) {
53 case 'a': case 'A': return 0x0A;
54 case 'b': case 'B': return 0x0B;
55 case 'c': case 'C': return 0x0C;
56 case 'd': case 'D': return 0x0D;
57 case 'e': case 'E': return 0x0E;
58 case 'f': case 'F': return 0x0F;
59 default: return 0xFF;
60 }
61}
62
63typedef struct
64{
65 unsigned long used_memory;
66
67 unsigned int uint_max;
68 unsigned long ulong_max;
69
70 json_settings settings;
71 int first_pass;
72
73 const json_char * ptr;
74 unsigned int cur_line, cur_col;
75
76} json_state;
77
78static void * default_alloc (size_t size, int zero, void * user_data)
79{
80 return zero ? calloc (nmemb: 1, size: size) : malloc (size: size);
81}
82
83static void default_free (void * ptr, void * user_data)
84{
85 free (ptr: ptr);
86}
87
88static void * json_alloc (json_state * state, unsigned long size, int zero)
89{
90 if ((state->ulong_max - state->used_memory) < size)
91 return 0;
92
93 if (state->settings.max_memory
94 && (state->used_memory += size) > state->settings.max_memory)
95 {
96 return 0;
97 }
98
99 return state->settings.mem_alloc (size, zero, state->settings.user_data);
100}
101
102static int new_value (json_state * state,
103 json_value ** top, json_value ** root, json_value ** alloc,
104 json_type type)
105{
106 json_value * value;
107 int values_size;
108
109 if (!state->first_pass)
110 {
111 value = *top = *alloc;
112 *alloc = (*alloc)->_reserved.next_alloc;
113
114 if (!*root)
115 *root = value;
116
117 switch (value->type)
118 {
119 case json_array:
120
121 if (! (value->u.array.values = (json_value **) json_alloc
122 (state, size: value->u.array.length * sizeof (json_value *), zero: 0)) )
123 {
124 return 0;
125 }
126
127 value->u.array.length = 0;
128 break;
129
130 case json_object:
131
132 values_size = sizeof (*value->u.object.values) * value->u.object.length;
133
134 if (! ((*(void **) &value->u.object.values) = json_alloc
135 (state, values_size + ((uintptr_t) value->u.object.values), 0)) )
136 {
137 return 0;
138 }
139
140 value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;
141
142 value->u.object.length = 0;
143 break;
144
145 case json_string:
146
147 if (! (value->u.string.ptr = (json_char *) json_alloc
148 (state, size: (value->u.string.length + 1) * sizeof (json_char), zero: 0)) )
149 {
150 return 0;
151 }
152
153 value->u.string.length = 0;
154 break;
155
156 default:
157 break;
158 };
159
160 return 1;
161 }
162
163 if (! (value = (json_value *) json_alloc
164 (state, size: sizeof (json_value) + state->settings.value_extra, zero: 1)))
165 {
166 return 0;
167 }
168
169 if (!*root)
170 *root = value;
171
172 value->type = type;
173 value->parent = *top;
174
175 #ifdef JSON_TRACK_SOURCE
176 value->line = state->cur_line;
177 value->col = state->cur_col;
178 #endif
179
180 if (*alloc)
181 (*alloc)->_reserved.next_alloc = value;
182
183 *alloc = *top = value;
184
185 return 1;
186}
187
188#define whitespace \
189 case '\n': ++ state.cur_line; state.cur_col = 0; \
190 case ' ': case '\t': case '\r'
191
192#define string_add(b) \
193 do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0);
194
195#define line_and_col \
196 state.cur_line, state.cur_col
197
198static const long
199 flag_next = 1 << 0,
200 flag_reproc = 1 << 1,
201 flag_need_comma = 1 << 2,
202 flag_seek_value = 1 << 3,
203 flag_escaped = 1 << 4,
204 flag_string = 1 << 5,
205 flag_need_colon = 1 << 6,
206 flag_done = 1 << 7,
207 flag_num_negative = 1 << 8,
208 flag_num_zero = 1 << 9,
209 flag_num_e = 1 << 10,
210 flag_num_e_got_sign = 1 << 11,
211 flag_num_e_negative = 1 << 12,
212 flag_line_comment = 1 << 13,
213 flag_block_comment = 1 << 14;
214
215json_value * json_parse_ex (json_settings * settings,
216 const json_char * json,
217 size_t length,
218 char * error_buf)
219{
220 json_char error [json_error_max];
221 const json_char * end;
222 json_value * top, * root, * alloc = 0;
223 json_state state = { 0 };
224 long flags;
225 long num_digits = 0, num_e = 0;
226 json_int_t num_fraction = 0;
227
228 /* Skip UTF-8 BOM
229 */
230 if (length >= 3 && ((unsigned char) json [0]) == 0xEF
231 && ((unsigned char) json [1]) == 0xBB
232 && ((unsigned char) json [2]) == 0xBF)
233 {
234 json += 3;
235 length -= 3;
236 }
237
238 error[0] = '\0';
239 end = (json + length);
240
241 memcpy (dest: &state.settings, src: settings, n: sizeof (json_settings));
242
243 if (!state.settings.mem_alloc)
244 state.settings.mem_alloc = default_alloc;
245
246 if (!state.settings.mem_free)
247 state.settings.mem_free = default_free;
248
249 memset (s: &state.uint_max, c: 0xFF, n: sizeof (state.uint_max));
250 memset (s: &state.ulong_max, c: 0xFF, n: sizeof (state.ulong_max));
251
252 state.uint_max -= 8; /* limit of how much can be added before next check */
253 state.ulong_max -= 8;
254
255 for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass)
256 {
257 json_uchar uchar;
258 unsigned char uc_b1, uc_b2, uc_b3, uc_b4;
259 json_char * string = 0;
260 unsigned int string_length = 0;
261
262 top = root = 0;
263 flags = flag_seek_value;
264
265 state.cur_line = 1;
266
267 for (state.ptr = json ;; ++ state.ptr)
268 {
269 json_char b = (state.ptr == end ? 0 : *state.ptr);
270
271 if (flags & flag_string)
272 {
273 if (!b)
274 { sprintf (s: error, format: "Unexpected EOF in string (at %d:%d)", line_and_col);
275 goto e_failed;
276 }
277
278 if (string_length > state.uint_max)
279 goto e_overflow;
280
281 if (flags & flag_escaped)
282 {
283 flags &= ~ flag_escaped;
284
285 switch (b)
286 {
287 case 'b': string_add ('\b'); break;
288 case 'f': string_add ('\f'); break;
289 case 'n': string_add ('\n'); break;
290 case 'r': string_add ('\r'); break;
291 case 't': string_add ('\t'); break;
292 case 'u':
293
294 if (end - state.ptr < 4 ||
295 (uc_b1 = hex_value (c: *++ state.ptr)) == 0xFF ||
296 (uc_b2 = hex_value (c: *++ state.ptr)) == 0xFF ||
297 (uc_b3 = hex_value (c: *++ state.ptr)) == 0xFF ||
298 (uc_b4 = hex_value (c: *++ state.ptr)) == 0xFF)
299 {
300 sprintf (s: error, format: "Invalid character value `%c` (at %d:%d)", b, line_and_col);
301 goto e_failed;
302 }
303
304 uc_b1 = (uc_b1 << 4) | uc_b2;
305 uc_b2 = (uc_b3 << 4) | uc_b4;
306 uchar = (uc_b1 << 8) | uc_b2;
307
308 if ((uchar & 0xF800) == 0xD800) {
309 json_uchar uchar2;
310
311 if (end - state.ptr < 6 || (*++ state.ptr) != '\\' || (*++ state.ptr) != 'u' ||
312 (uc_b1 = hex_value (c: *++ state.ptr)) == 0xFF ||
313 (uc_b2 = hex_value (c: *++ state.ptr)) == 0xFF ||
314 (uc_b3 = hex_value (c: *++ state.ptr)) == 0xFF ||
315 (uc_b4 = hex_value (c: *++ state.ptr)) == 0xFF)
316 {
317 sprintf (s: error, format: "Invalid character value `%c` (at %d:%d)", b, line_and_col);
318 goto e_failed;
319 }
320
321 uc_b1 = (uc_b1 << 4) | uc_b2;
322 uc_b2 = (uc_b3 << 4) | uc_b4;
323 uchar2 = (uc_b1 << 8) | uc_b2;
324
325 uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF);
326 }
327
328 if (sizeof (json_char) >= sizeof (json_uchar) || (uchar <= 0x7F))
329 {
330 string_add ((json_char) uchar);
331 break;
332 }
333
334 if (uchar <= 0x7FF)
335 {
336 if (state.first_pass)
337 string_length += 2;
338 else
339 { string [string_length ++] = 0xC0 | (uchar >> 6);
340 string [string_length ++] = 0x80 | (uchar & 0x3F);
341 }
342
343 break;
344 }
345
346 if (uchar <= 0xFFFF) {
347 if (state.first_pass)
348 string_length += 3;
349 else
350 { string [string_length ++] = 0xE0 | (uchar >> 12);
351 string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
352 string [string_length ++] = 0x80 | (uchar & 0x3F);
353 }
354
355 break;
356 }
357
358 if (state.first_pass)
359 string_length += 4;
360 else
361 { string [string_length ++] = 0xF0 | (uchar >> 18);
362 string [string_length ++] = 0x80 | ((uchar >> 12) & 0x3F);
363 string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
364 string [string_length ++] = 0x80 | (uchar & 0x3F);
365 }
366
367 break;
368
369 default:
370 string_add (b);
371 };
372
373 continue;
374 }
375
376 if (b == '\\')
377 {
378 flags |= flag_escaped;
379 continue;
380 }
381
382 if (b == '"')
383 {
384 if (!state.first_pass)
385 string [string_length] = 0;
386
387 flags &= ~ flag_string;
388 string = 0;
389
390 switch (top->type)
391 {
392 case json_string:
393
394 top->u.string.length = string_length;
395 flags |= flag_next;
396
397 break;
398
399 case json_object:
400
401 if (state.first_pass)
402 (*(json_char **) &top->u.object.values) += string_length + 1;
403 else
404 {
405 top->u.object.values [top->u.object.length].name
406 = (json_char *) top->_reserved.object_mem;
407
408 top->u.object.values [top->u.object.length].name_length
409 = string_length;
410
411 (*(json_char **) &top->_reserved.object_mem) += string_length + 1;
412 }
413
414 flags |= flag_seek_value | flag_need_colon;
415 continue;
416
417 default:
418 break;
419 };
420 }
421 else
422 {
423 string_add (b);
424 continue;
425 }
426 }
427
428 if (state.settings.settings & json_enable_comments)
429 {
430 if (flags & (flag_line_comment | flag_block_comment))
431 {
432 if (flags & flag_line_comment)
433 {
434 if (b == '\r' || b == '\n' || !b)
435 {
436 flags &= ~ flag_line_comment;
437 -- state.ptr; /* so null can be reproc'd */
438 }
439
440 continue;
441 }
442
443 if (flags & flag_block_comment)
444 {
445 if (!b)
446 { sprintf (s: error, format: "%d:%d: Unexpected EOF in block comment", line_and_col);
447 goto e_failed;
448 }
449
450 if (b == '*' && state.ptr < (end - 1) && state.ptr [1] == '/')
451 {
452 flags &= ~ flag_block_comment;
453 ++ state.ptr; /* skip closing sequence */
454 }
455
456 continue;
457 }
458 }
459 else if (b == '/')
460 {
461 if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)
462 { sprintf (s: error, format: "%d:%d: Comment not allowed here", line_and_col);
463 goto e_failed;
464 }
465
466 if (++ state.ptr == end)
467 { sprintf (s: error, format: "%d:%d: EOF unexpected", line_and_col);
468 goto e_failed;
469 }
470
471 switch (b = *state.ptr)
472 {
473 case '/':
474 flags |= flag_line_comment;
475 continue;
476
477 case '*':
478 flags |= flag_block_comment;
479 continue;
480
481 default:
482 sprintf (s: error, format: "%d:%d: Unexpected `%c` in comment opening sequence", line_and_col, b);
483 goto e_failed;
484 };
485 }
486 }
487
488 if (flags & flag_done)
489 {
490 if (!b)
491 break;
492
493 switch (b)
494 {
495 whitespace:
496 continue;
497
498 default:
499
500 sprintf (s: error, format: "%d:%d: Trailing garbage: `%c`",
501 state.cur_line, state.cur_col, b);
502
503 goto e_failed;
504 };
505 }
506
507 if (flags & flag_seek_value)
508 {
509 switch (b)
510 {
511 whitespace:
512 continue;
513
514 case ']':
515
516 if (top && top->type == json_array)
517 flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
518 else
519 { sprintf (s: error, format: "%d:%d: Unexpected ]", line_and_col);
520 goto e_failed;
521 }
522
523 break;
524
525 default:
526
527 if (flags & flag_need_comma)
528 {
529 if (b == ',')
530 { flags &= ~ flag_need_comma;
531 continue;
532 }
533 else
534 {
535 sprintf (s: error, format: "%d:%d: Expected , before %c",
536 state.cur_line, state.cur_col, b);
537
538 goto e_failed;
539 }
540 }
541
542 if (flags & flag_need_colon)
543 {
544 if (b == ':')
545 { flags &= ~ flag_need_colon;
546 continue;
547 }
548 else
549 {
550 sprintf (s: error, format: "%d:%d: Expected : before %c",
551 state.cur_line, state.cur_col, b);
552
553 goto e_failed;
554 }
555 }
556
557 flags &= ~ flag_seek_value;
558
559 switch (b)
560 {
561 case '{':
562
563 if (!new_value (state: &state, top: &top, root: &root, alloc: &alloc, type: json_object))
564 goto e_alloc_failure;
565
566 continue;
567
568 case '[':
569
570 if (!new_value (state: &state, top: &top, root: &root, alloc: &alloc, type: json_array))
571 goto e_alloc_failure;
572
573 flags |= flag_seek_value;
574 continue;
575
576 case '"':
577
578 if (!new_value (state: &state, top: &top, root: &root, alloc: &alloc, type: json_string))
579 goto e_alloc_failure;
580
581 flags |= flag_string;
582
583 string = top->u.string.ptr;
584 string_length = 0;
585
586 continue;
587
588 case 't':
589
590 if ((end - state.ptr) < 3 || *(++ state.ptr) != 'r' ||
591 *(++ state.ptr) != 'u' || *(++ state.ptr) != 'e')
592 {
593 goto e_unknown_value;
594 }
595
596 if (!new_value (state: &state, top: &top, root: &root, alloc: &alloc, type: json_boolean))
597 goto e_alloc_failure;
598
599 top->u.boolean = 1;
600
601 flags |= flag_next;
602 break;
603
604 case 'f':
605
606 if ((end - state.ptr) < 4 || *(++ state.ptr) != 'a' ||
607 *(++ state.ptr) != 'l' || *(++ state.ptr) != 's' ||
608 *(++ state.ptr) != 'e')
609 {
610 goto e_unknown_value;
611 }
612
613 if (!new_value (state: &state, top: &top, root: &root, alloc: &alloc, type: json_boolean))
614 goto e_alloc_failure;
615
616 flags |= flag_next;
617 break;
618
619 case 'n':
620
621 if ((end - state.ptr) < 3 || *(++ state.ptr) != 'u' ||
622 *(++ state.ptr) != 'l' || *(++ state.ptr) != 'l')
623 {
624 goto e_unknown_value;
625 }
626
627 if (!new_value (state: &state, top: &top, root: &root, alloc: &alloc, type: json_null))
628 goto e_alloc_failure;
629
630 flags |= flag_next;
631 break;
632
633 default:
634
635 if (isdigit (b) || b == '-')
636 {
637 if (!new_value (state: &state, top: &top, root: &root, alloc: &alloc, type: json_integer))
638 goto e_alloc_failure;
639
640 if (!state.first_pass)
641 {
642 while (isdigit (b) || b == '+' || b == '-'
643 || b == 'e' || b == 'E' || b == '.')
644 {
645 if ( (++ state.ptr) == end)
646 {
647 b = 0;
648 break;
649 }
650
651 b = *state.ptr;
652 }
653
654 flags |= flag_next | flag_reproc;
655 break;
656 }
657
658 flags &= ~ (flag_num_negative | flag_num_e |
659 flag_num_e_got_sign | flag_num_e_negative |
660 flag_num_zero);
661
662 num_digits = 0;
663 num_fraction = 0;
664 num_e = 0;
665
666 if (b != '-')
667 {
668 flags |= flag_reproc;
669 break;
670 }
671
672 flags |= flag_num_negative;
673 continue;
674 }
675 else
676 { sprintf (s: error, format: "%d:%d: Unexpected %c when seeking value", line_and_col, b);
677 goto e_failed;
678 }
679 };
680 };
681 }
682 else
683 {
684 switch (top->type)
685 {
686 case json_object:
687
688 switch (b)
689 {
690 whitespace:
691 continue;
692
693 case '"':
694
695 if (flags & flag_need_comma)
696 { sprintf (s: error, format: "%d:%d: Expected , before \"", line_and_col);
697 goto e_failed;
698 }
699
700 flags |= flag_string;
701
702 string = (json_char *) top->_reserved.object_mem;
703 string_length = 0;
704
705 break;
706
707 case '}':
708
709 flags = (flags & ~ flag_need_comma) | flag_next;
710 break;
711
712 case ',':
713
714 if (flags & flag_need_comma)
715 {
716 flags &= ~ flag_need_comma;
717 break;
718 }
719
720 default:
721 sprintf (s: error, format: "%d:%d: Unexpected `%c` in object", line_and_col, b);
722 goto e_failed;
723 };
724
725 break;
726
727 case json_integer:
728 case json_double:
729
730 if (isdigit (b))
731 {
732 ++ num_digits;
733
734 if (top->type == json_integer || flags & flag_num_e)
735 {
736 if (! (flags & flag_num_e))
737 {
738 if (flags & flag_num_zero)
739 { sprintf (s: error, format: "%d:%d: Unexpected `0` before `%c`", line_and_col, b);
740 goto e_failed;
741 }
742
743 if (num_digits == 1 && b == '0')
744 flags |= flag_num_zero;
745 }
746 else
747 {
748 flags |= flag_num_e_got_sign;
749 num_e = (num_e * 10) + (b - '0');
750 continue;
751 }
752
753 top->u.integer = (top->u.integer * 10) + (b - '0');
754 continue;
755 }
756
757 num_fraction = (num_fraction * 10) + (b - '0');
758 continue;
759 }
760
761 if (b == '+' || b == '-')
762 {
763 if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign))
764 {
765 flags |= flag_num_e_got_sign;
766
767 if (b == '-')
768 flags |= flag_num_e_negative;
769
770 continue;
771 }
772 }
773 else if (b == '.' && top->type == json_integer)
774 {
775 if (!num_digits)
776 { sprintf (s: error, format: "%d:%d: Expected digit before `.`", line_and_col);
777 goto e_failed;
778 }
779
780 top->type = json_double;
781 top->u.dbl = (double) top->u.integer;
782
783 num_digits = 0;
784 continue;
785 }
786
787 if (! (flags & flag_num_e))
788 {
789 if (top->type == json_double)
790 {
791 if (!num_digits)
792 { sprintf (s: error, format: "%d:%d: Expected digit after `.`", line_and_col);
793 goto e_failed;
794 }
795
796 top->u.dbl += ((double) num_fraction) / (pow (x: 10.0, y: (double) num_digits));
797 }
798
799 if (b == 'e' || b == 'E')
800 {
801 flags |= flag_num_e;
802
803 if (top->type == json_integer)
804 {
805 top->type = json_double;
806 top->u.dbl = (double) top->u.integer;
807 }
808
809 num_digits = 0;
810 flags &= ~ flag_num_zero;
811
812 continue;
813 }
814 }
815 else
816 {
817 if (!num_digits)
818 { sprintf (s: error, format: "%d:%d: Expected digit after `e`", line_and_col);
819 goto e_failed;
820 }
821
822 top->u.dbl *= pow (x: 10.0, y: (double)
823 (flags & flag_num_e_negative ? - num_e : num_e));
824 }
825
826 if (flags & flag_num_negative)
827 {
828 if (top->type == json_integer)
829 top->u.integer = - top->u.integer;
830 else
831 top->u.dbl = - top->u.dbl;
832 }
833
834 flags |= flag_next | flag_reproc;
835 break;
836
837 default:
838 break;
839 };
840 }
841
842 if (flags & flag_reproc)
843 {
844 flags &= ~ flag_reproc;
845 -- state.ptr;
846 }
847
848 if (flags & flag_next)
849 {
850 flags = (flags & ~ flag_next) | flag_need_comma;
851
852 if (!top->parent)
853 {
854 /* root value done */
855
856 flags |= flag_done;
857 continue;
858 }
859
860 if (top->parent->type == json_array)
861 flags |= flag_seek_value;
862
863 if (!state.first_pass)
864 {
865 json_value * parent = top->parent;
866
867 switch (parent->type)
868 {
869 case json_object:
870
871 parent->u.object.values
872 [parent->u.object.length].value = top;
873
874 break;
875
876 case json_array:
877
878 parent->u.array.values
879 [parent->u.array.length] = top;
880
881 break;
882
883 default:
884 break;
885 };
886 }
887
888 if ( (++ top->parent->u.array.length) > state.uint_max)
889 goto e_overflow;
890
891 top = top->parent;
892
893 continue;
894 }
895 }
896
897 alloc = root;
898 }
899
900 return root;
901
902e_unknown_value:
903
904 sprintf (s: error, format: "%d:%d: Unknown value", line_and_col);
905 goto e_failed;
906
907e_alloc_failure:
908
909 strcpy (dest: error, src: "Memory allocation failure");
910 goto e_failed;
911
912e_overflow:
913
914 sprintf (s: error, format: "%d:%d: Too long (caught overflow)", line_and_col);
915 goto e_failed;
916
917e_failed:
918
919 if (error_buf)
920 {
921 if (*error)
922 strcpy (dest: error_buf, src: error);
923 else
924 strcpy (dest: error_buf, src: "Unknown error");
925 }
926
927 if (state.first_pass)
928 alloc = root;
929
930 while (alloc)
931 {
932 top = alloc->_reserved.next_alloc;
933 state.settings.mem_free (alloc, state.settings.user_data);
934 alloc = top;
935 }
936
937 if (!state.first_pass)
938 json_value_free_ex (settings: &state.settings, root);
939
940 return 0;
941}
942
943json_value * json_parse (const json_char * json, size_t length)
944{
945 json_settings settings = { 0 };
946 return json_parse_ex (settings: &settings, json, length, error_buf: 0);
947}
948
949void json_value_free_ex (json_settings * settings, json_value * value)
950{
951 json_value * cur_value;
952
953 if (!value)
954 return;
955
956 value->parent = 0;
957
958 while (value)
959 {
960 switch (value->type)
961 {
962 case json_array:
963
964 if (!value->u.array.length)
965 {
966 settings->mem_free (value->u.array.values, settings->user_data);
967 break;
968 }
969
970 value = value->u.array.values [-- value->u.array.length];
971 continue;
972
973 case json_object:
974
975 if (!value->u.object.length)
976 {
977 settings->mem_free (value->u.object.values, settings->user_data);
978 break;
979 }
980
981 value = value->u.object.values [-- value->u.object.length].value;
982 continue;
983
984 case json_string:
985
986 settings->mem_free (value->u.string.ptr, settings->user_data);
987 break;
988
989 default:
990 break;
991 };
992
993 cur_value = value;
994 value = value->parent;
995 settings->mem_free (cur_value, settings->user_data);
996 }
997}
998
999void json_value_free (json_value * value)
1000{
1001 json_settings settings = { 0 };
1002 settings.mem_free = default_free;
1003 json_value_free_ex (settings: &settings, value);
1004}
1005