GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/json.c Lines: 286 491 58.2 %
Date: 2020-12-10 21:44:00 Branches: 166 368 45.1 %

Line Branch Exec Source
1
/* vim: set et ts=3 sw=3 sts=3 ft=c: *
2
 * Copyright (C) 2012, 2013, 2014 James McLaughlin et al.  All rights reserved.
3
 * https://github.com/udp/json-parser
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 *
9
 * 1. Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
11
 *
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *   notice, this list of conditions and the following disclaimer in the
14
 *   documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 * SUCH DAMAGE.
27
 */
28
29
#include "json.h"
30
31
#ifdef _MSC_VER
32
   #ifndef _CRT_SECURE_NO_WARNINGS
33
      #define _CRT_SECURE_NO_WARNINGS
34
   #endif
35
#endif
36
37
const struct _json_value json_value_none;
38
39
#include <stdio.h>
40
#include <string.h>
41
#include <ctype.h>
42
#include <math.h>
43
44
typedef unsigned int json_uchar;
45
46
static unsigned char hex_value (json_char c)
47
{
48
   if (isdigit(c))
49
      return c - '0';
50
51
   switch (c) {
52
      case 'a': case 'A': return 0x0A;
53
      case 'b': case 'B': return 0x0B;
54
      case 'c': case 'C': return 0x0C;
55
      case 'd': case 'D': return 0x0D;
56
      case 'e': case 'E': return 0x0E;
57
      case 'f': case 'F': return 0x0F;
58
      default: return 0xFF;
59
   }
60
}
61
62
typedef struct
63
{
64
   unsigned long used_memory;
65
66
   unsigned int uint_max;
67
   unsigned long ulong_max;
68
69
   json_settings settings;
70
   int first_pass;
71
72
   const json_char * ptr;
73
   unsigned int cur_line, cur_col;
74
75
} json_state;
76
77
static void * default_alloc (size_t size, int zero, void * user_data)
78
{
79
   (void) user_data;
80
   return zero ? calloc (1, size) : malloc (size);
81
}
82
83
static void default_free (void * ptr, void * user_data)
84
{
85
   (void) user_data;
86
   free (ptr);
87
}
88
89
7175
static void * json_alloc (json_state * state, unsigned long size, int zero)
90
{
91
7175
   if ((state->ulong_max - state->used_memory) < size)
92
      return 0;
93
94
7175
   if (state->settings.max_memory
95
         && (state->used_memory += size) > state->settings.max_memory)
96
   {
97
      return 0;
98
   }
99
100
7175
   return state->settings.mem_alloc (size, zero, state->settings.user_data);
101
}
102
103
8673
static int new_value (json_state * state,
104
                      json_value ** top, json_value ** root, json_value ** alloc,
105
                      json_type type)
106
{
107
8673
   json_value * value;
108
8673
   int values_size;
109
110
8673
   if (!state->first_pass)
111
   {
112
4322
      value = *top = *alloc;
113
4322
      *alloc = (*alloc)->_reserved.next_alloc;
114
115
4322
      if (!*root)
116
84
         *root = value;
117
118

4322
      switch (value->type)
119
      {
120
455
         case json_array:
121
122
455
            if (value->u.array.length == 0)
123
               break;
124
125
449
            if (! (value->u.array.values = (json_value **) json_alloc
126
449
               (state, value->u.array.length * sizeof (json_value *), 0)) )
127
            {
128
               return 0;
129
            }
130
131
449
            value->u.array.length = 0;
132
449
            break;
133
134
756
         case json_object:
135
136
756
            if (value->u.object.length == 0)
137
               break;
138
139
756
            values_size = sizeof (*value->u.object.values) * value->u.object.length;
140
141
756
            if (! (value->u.object.values = (json_object_entry *) json_alloc
142
756
                  (state, values_size + ((unsigned long) value->u.object.values), 0)) )
143
            {
144
               return 0;
145
            }
146
147
756
            value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;
148
149
756
            value->u.object.length = 0;
150
756
            break;
151
152
1619
         case json_string:
153
154
1619
            if (! (value->u.string.ptr = (json_char *) json_alloc
155
1619
               (state, (value->u.string.length + 1) * sizeof (json_char), 0)) )
156
            {
157
               return 0;
158
            }
159
160
1619
            value->u.string.length = 0;
161
1619
            break;
162
163
         default:
164
            break;
165
6
      };
166
167
4322
      return 1;
168
   }
169
170
4351
   if (! (value = (json_value *) json_alloc
171
4351
         (state, sizeof (json_value) + state->settings.value_extra, 1)))
172
   {
173
      return 0;
174
   }
175
176
4351
   if (!*root)
177
85
      *root = value;
178
179
4351
   value->type = type;
180
4351
   value->parent = *top;
181
182
   #ifdef JSON_TRACK_SOURCE
183
      value->line = state->cur_line;
184
      value->col = state->cur_col;
185
   #endif
186
187
4351
   if (*alloc)
188
4266
      (*alloc)->_reserved.next_alloc = value;
189
190
4351
   *alloc = *top = value;
191
192
4351
   return 1;
193
}
194
195
#define whitespace \
196
   case '\n': ++ state.cur_line;  state.cur_col = 0; \
197
   case ' ': case '\t': case '\r'
198
199
#define string_add(b)  \
200
   do { if (!state.first_pass) string [string_length] = b;  ++ string_length; } while (0);
201
202
#define line_and_col \
203
   state.cur_line, state.cur_col
204
205
static const long
206
   flag_next             = 1 << 0,
207
   flag_reproc           = 1 << 1,
208
   flag_need_comma       = 1 << 2,
209
   flag_seek_value       = 1 << 3,
210
   flag_escaped          = 1 << 4,
211
   flag_string           = 1 << 5,
212
   flag_need_colon       = 1 << 6,
213
   flag_done             = 1 << 7,
214
   flag_num_negative     = 1 << 8,
215
   flag_num_zero         = 1 << 9,
216
   flag_num_e            = 1 << 10,
217
   flag_num_e_got_sign   = 1 << 11,
218
   flag_num_e_negative   = 1 << 12,
219
   flag_line_comment     = 1 << 13,
220
   flag_block_comment    = 1 << 14;
221
222
85
json_value * json_parse_ex (json_settings * settings,
223
                            const json_char * json,
224
                            size_t length,
225
                            char * error_buf)
226
{
227
85
   json_char error [json_error_max];
228
85
   const json_char * end;
229
85
   json_value * top, * root, * alloc = 0;
230
85
   json_state state = { 0 };
231
85
   long flags;
232
85
   long num_digits = 0, num_e = 0;
233
85
   json_int_t num_fraction = 0;
234
235
   /* Skip UTF-8 BOM
236
    */
237

85
   if (length >= 3 && ((unsigned char) json [0]) == 0xEF
238
                   && ((unsigned char) json [1]) == 0xBB
239
                   && ((unsigned char) json [2]) == 0xBF)
240
   {
241
      json += 3;
242
      length -= 3;
243
   }
244
245
85
   error[0] = '\0';
246
85
   end = (json + length);
247
248
85
   memcpy (&state.settings, settings, sizeof (json_settings));
249
250
85
   if (!state.settings.mem_alloc)
251
      state.settings.mem_alloc = default_alloc;
252
253
85
   if (!state.settings.mem_free)
254
      state.settings.mem_free = default_free;
255
256
85
   memset (&state.uint_max, 0xFF, sizeof (state.uint_max));
257
85
   memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max));
258
259
85
   state.uint_max -= 8; /* limit of how much can be added before next check */
260
85
   state.ulong_max -= 8;
261
262
253
   for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass)
263
   {
264
169
      json_uchar uchar;
265
169
      unsigned char uc_b1, uc_b2, uc_b3, uc_b4;
266
169
      json_char * string = 0;
267
169
      unsigned int string_length = 0;
268
269
169
      top = root = 0;
270
169
      flags = flag_seek_value;
271
272
169
      state.cur_line = 1;
273
274
169
      for (state.ptr = json ;; ++ state.ptr)
275
330439
      {
276
330608
         json_char b = (state.ptr == end ? 0 : *state.ptr);
277
278
330608
         if (flags & flag_string)
279
         {
280
186044
            if (!b)
281
            {  sprintf (error, "Unexpected EOF in string (at %u:%u)", line_and_col);
282
               goto e_failed;
283
            }
284
285
186044
            if (string_length > state.uint_max)
286
               goto e_overflow;
287
288
186044
            if (flags & flag_escaped)
289
            {
290
               flags &= ~ flag_escaped;
291
292
               switch (b)
293
               {
294
                  case 'b':  string_add ('\b');  break;
295
                  case 'f':  string_add ('\f');  break;
296
                  case 'n':  string_add ('\n');  break;
297
                  case 'r':  string_add ('\r');  break;
298
                  case 't':  string_add ('\t');  break;
299
                  case 'u':
300
301
                    if (end - state.ptr <= 4 ||
302
                        (uc_b1 = hex_value (*++ state.ptr)) == 0xFF ||
303
                        (uc_b2 = hex_value (*++ state.ptr)) == 0xFF ||
304
                        (uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
305
                        (uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
306
                    {
307
                        sprintf (error, "Invalid character value `%c` (at %u:%u)", b, line_and_col);
308
                        goto e_failed;
309
                    }
310
311
                    uc_b1 = (uc_b1 << 4) | uc_b2;
312
                    uc_b2 = (uc_b3 << 4) | uc_b4;
313
                    uchar = (uc_b1 << 8) | uc_b2;
314
if ((uchar & 0xF800) == 0xD800) {
315
                        json_uchar uchar2;
316
317
                        if (end - state.ptr <= 6 || (*++ state.ptr) != '\\' || (*++ state.ptr) != 'u' ||
318
                            (uc_b1 = hex_value (*++ state.ptr)) == 0xFF ||
319
                            (uc_b2 = hex_value (*++ state.ptr)) == 0xFF ||
320
                            (uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
321
                            (uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
322
                        {
323
                            sprintf (error, "Invalid character value `%c` (at %u:%u)", b, line_and_col);
324
                            goto e_failed;
325
                        }
326
327
                        uc_b1 = (uc_b1 << 4) | uc_b2;
328
                        uc_b2 = (uc_b3 << 4) | uc_b4;
329
                        uchar2 = (uc_b1 << 8) | uc_b2;
330
331
                        uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF);
332
                    }
333
334
                    if (sizeof (json_char) >= sizeof (json_uchar) || (uchar <= 0x7F))
335
                    {
336
                       string_add ((json_char) uchar);
337
                       break;
338
                    }
339
340
                    if (uchar <= 0x7FF)
341
                    {
342
                        if (state.first_pass)
343
                           string_length += 2;
344
                        else
345
                        {  string [string_length ++] = 0xC0 | (uchar >> 6);
346
                           string [string_length ++] = 0x80 | (uchar & 0x3F);
347
                        }
348
349
                        break;
350
                    }
351
352
                    if (uchar <= 0xFFFF) {
353
                        if (state.first_pass)
354
                           string_length += 3;
355
                        else
356
                        {  string [string_length ++] = 0xE0 | (uchar >> 12);
357
                           string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
358
                           string [string_length ++] = 0x80 | (uchar & 0x3F);
359
                        }
360
361
                        break;
362
                    }
363
364
                    if (state.first_pass)
365
                       string_length += 4;
366
                    else
367
                    {  string [string_length ++] = 0xF0 | (uchar >> 18);
368
                       string [string_length ++] = 0x80 | ((uchar >> 12) & 0x3F);
369
                       string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
370
                       string [string_length ++] = 0x80 | (uchar & 0x3F);
371
                    }
372
373
                    break;
374
375
                  default:
376
                     string_add (b);
377
               };
378
379
               continue;
380
            }
381
382
186044
            if (b == '\\')
383
            {
384
               flags |= flag_escaped;
385
               continue;
386
            }
387
388
186044
            if (b == '"')
389
            {
390
10112
               if (!state.first_pass)
391
5040
                  string [string_length] = 0;
392
393
10112
               flags &= ~ flag_string;
394
10112
               string = 0;
395
396
10112
               switch (top->type)
397
               {
398
3246
                  case json_string:
399
400
3246
                     top->u.string.length = string_length;
401
3246
                     flags |= flag_next;
402
403
3246
                     break;
404
405
6866
                  case json_object:
406
407
6866
                     if (state.first_pass)
408
3445
                        (*(json_char **) &top->u.object.values) += string_length + 1;
409
                     else
410
                     {
411
3421
                        top->u.object.values [top->u.object.length].name
412
3421
                           = (json_char *) top->_reserved.object_mem;
413
414
3421
                        top->u.object.values [top->u.object.length].name_length
415
3421
                           = string_length;
416
417
3421
                        (*(json_char **) &top->_reserved.object_mem) += string_length + 1;
418
                     }
419
420
6866
                     flags |= flag_seek_value | flag_need_colon;
421
6866
                     continue;
422
423
                  default:
424
                     break;
425
               };
426
            }
427
            else
428
            {
429
175932
               string_add (b);
430
175932
               continue;
431
            }
432
         }
433
434
147810
         if (state.settings.settings & json_enable_comments)
435
         {
436
147810
            if (flags & (flag_line_comment | flag_block_comment))
437
            {
438
               if (flags & flag_line_comment)
439
               {
440
                  if (b == '\r' || b == '\n' || !b)
441
                  {
442
                     flags &= ~ flag_line_comment;
443
                     -- state.ptr;  /* so null can be reproc'd */
444
                  }
445
446
                  continue;
447
               }
448
449
               if (flags & flag_block_comment)
450
               {
451
                  if (!b)
452
                  {  sprintf (error, "%u:%u: Unexpected EOF in block comment", line_and_col);
453
                     goto e_failed;
454
                  }
455
456
                  if (b == '*' && state.ptr < (end - 1) && state.ptr [1] == '/')
457
                  {
458
                     flags &= ~ flag_block_comment;
459
                     ++ state.ptr;  /* skip closing sequence */
460
                  }
461
462
                  continue;
463
               }
464
            }
465
147810
            else if (b == '/')
466
            {
467
               if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)
468
               {  sprintf (error, "%u:%u: Comment not allowed here", line_and_col);
469
                  goto e_failed;
470
               }
471
472
               if (++ state.ptr == end)
473
               {  sprintf (error, "%u:%u: EOF unexpected", line_and_col);
474
                  goto e_failed;
475
               }
476
477
               switch (b = *state.ptr)
478
               {
479
                  case '/':
480
                     flags |= flag_line_comment;
481
                     continue;
482
483
                  case '*':
484
                     flags |= flag_block_comment;
485
                     continue;
486
487
                  default:
488
                     sprintf (error, "%u:%u: Unexpected `%c` in comment opening sequence", line_and_col, b);
489
                     goto e_failed;
490
147810
               };
491
            }
492
         }
493
494
147810
         if (flags & flag_done)
495
         {
496
348
            if (!b)
497
               break;
498
499
180
            switch (b)
500
            {
501
#pragma GCC diagnostic push
502
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
503
180
               whitespace:
504
#pragma GCC diagnostic pop
505
180
                  continue;
506
507
               default:
508
509
                  sprintf (error, "%u:%u: Trailing garbage: `%c`",
510
                           state.cur_line, state.cur_col, b);
511
512
                  goto e_failed;
513
147462
            };
514
         }
515
516
147462
         if (flags & flag_seek_value)
517
         {
518

49363
            switch (b)
519
            {
520
#pragma GCC diagnostic push
521
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
522
2542
               whitespace:
523
#pragma GCC diagnostic pop
524
32174
                  continue;
525
526
912
               case ']':
527
528

912
                  if (top && top->type == json_array)
529
912
                     flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
530
                  else
531
                  {  sprintf (error, "%u:%u: Unexpected ]", line_and_col);
532
                     goto e_failed;
533
                  }
534
535
912
                  break;
536
537
16277
               default:
538
539
16277
                  if (flags & flag_need_comma)
540
                  {
541
738
                     if (b == ',')
542
738
                     {  flags &= ~ flag_need_comma;
543
738
                        continue;
544
                     }
545
                     else
546
                     {
547
                        sprintf (error, "%u:%u: Expected , before %c",
548
                                 state.cur_line, state.cur_col, b);
549
550
                        goto e_failed;
551
                     }
552
                  }
553
554
15539
                  if (flags & flag_need_colon)
555
                  {
556
6866
                     if (b == ':')
557
6866
                     {  flags &= ~ flag_need_colon;
558
6866
                        continue;
559
                     }
560
                     else
561
                     {
562
                        sprintf (error, "%u:%u: Expected : before %c",
563
                                 state.cur_line, state.cur_col, b);
564
565
                        goto e_failed;
566
                     }
567
                  }
568
569
8673
                  flags &= ~ flag_seek_value;
570
571

8673
                  switch (b)
572
                  {
573
1518
                     case '{':
574
575
1518
                        if (!new_value (&state, &top, &root, &alloc, json_object))
576
                           goto e_alloc_failure;
577
578
1518
                        continue;
579
580
912
                     case '[':
581
582
912
                        if (!new_value (&state, &top, &root, &alloc, json_array))
583
                           goto e_alloc_failure;
584
585
912
                        flags |= flag_seek_value;
586
912
                        continue;
587
588
3246
                     case '"':
589
590
3246
                        if (!new_value (&state, &top, &root, &alloc, json_string))
591
                           goto e_alloc_failure;
592
593
3246
                        flags |= flag_string;
594
595
3246
                        string = top->u.string.ptr;
596
3246
                        string_length = 0;
597
598
3246
                        continue;
599
600
                     case 't':
601
602
                        if ((end - state.ptr) < 3 || *(++ state.ptr) != 'r' ||
603
                            *(++ state.ptr) != 'u' || *(++ state.ptr) != 'e')
604
                        {
605
                           goto e_unknown_value;
606
                        }
607
608
                        if (!new_value (&state, &top, &root, &alloc, json_boolean))
609
                           goto e_alloc_failure;
610
611
                        top->u.boolean = 1;
612
613
                        flags |= flag_next;
614
                        break;
615
616
296
                     case 'f':
617
618

296
                        if ((end - state.ptr) < 4 || *(++ state.ptr) != 'a' ||
619

296
                            *(++ state.ptr) != 'l' || *(++ state.ptr) != 's' ||
620
296
                            *(++ state.ptr) != 'e')
621
                        {
622
                           goto e_unknown_value;
623
                        }
624
625
296
                        if (!new_value (&state, &top, &root, &alloc, json_boolean))
626
                           goto e_alloc_failure;
627
628
296
                        flags |= flag_next;
629
296
                        break;
630
631
                     case 'n':
632
633
                        if ((end - state.ptr) < 3 || *(++ state.ptr) != 'u' ||
634
                            *(++ state.ptr) != 'l' || *(++ state.ptr) != 'l')
635
                        {
636
                           goto e_unknown_value;
637
                        }
638
639
                        if (!new_value (&state, &top, &root, &alloc, json_null))
640
                           goto e_alloc_failure;
641
642
                        flags |= flag_next;
643
                        break;
644
645
2701
                     default:
646
647

2701
                        if (isdigit (b) || b == '-')
648
                        {
649
2701
                           if (!new_value (&state, &top, &root, &alloc, json_integer))
650
                              goto e_alloc_failure;
651
652
2701
                           if (!state.first_pass)
653
                           {
654

5509
                              while (isdigit (b) || b == '+' || b == '-'
655

1344
                                        || b == 'e' || b == 'E' || b == '.')
656
                              {
657
4165
                                 if ( (++ state.ptr) == end)
658
                                 {
659
1344
                                    b = 0;
660
                                    break;
661
                                 }
662
663
4165
                                 b = *state.ptr;
664
                              }
665
666
1344
                              flags |= flag_next | flag_reproc;
667
1344
                              break;
668
                           }
669
670
1357
                           flags &= ~ (flag_num_negative | flag_num_e |
671
                                        flag_num_e_got_sign | flag_num_e_negative |
672
                                           flag_num_zero);
673
674
1357
                           num_digits = 0;
675
1357
                           num_fraction = 0;
676
1357
                           num_e = 0;
677
678
1357
                           if (b != '-')
679
                           {
680
1353
                              flags |= flag_reproc;
681
1353
                              break;
682
                           }
683
684
4
                           flags |= flag_num_negative;
685
4
                           continue;
686
                        }
687
                        else
688
                        {  sprintf (error, "%u:%u: Unexpected %c when seeking value", line_and_col, b);
689
                           goto e_failed;
690
                        }
691
                  };
692
            };
693
         }
694
         else
695
         {
696
98099
            switch (top->type)
697
            {
698
89282
            case json_object:
699
700

89282
               switch (b)
701
               {
702
#pragma GCC diagnostic push
703
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
704
8385
                  whitespace:
705
75550
                     continue;
706
#pragma GCC diagnostic pop
707
708
6866
                  case '"':
709
710
6866
                     if (flags & flag_need_comma)
711
                     {  sprintf (error, "%u:%u: Expected , before \"", line_and_col);
712
                        goto e_failed;
713
                     }
714
715
6866
                     flags |= flag_string;
716
717
6866
                     string = (json_char *) top->_reserved.object_mem;
718
6866
                     string_length = 0;
719
720
6866
                     break;
721
722
1517
                  case '}':
723
724
1517
                     flags = (flags & ~ flag_need_comma) | flag_next;
725
1517
                     break;
726
727
5348
                  case ',':
728
729
5348
                     if (flags & flag_need_comma)
730
                     {
731
5348
                        flags &= ~ flag_need_comma;
732
5348
                        break;
733
                     }
734
735
                     sprintf (error, "%u:%u: Unexpected `%c` in object", line_and_col, b);
736
                     goto e_failed;
737
1
                  default:
738
1
                     sprintf (error, "%u:%u: Unexpected `%c` in object", line_and_col, b);
739
1
                     goto e_failed;
740
               };
741
742
               break;
743
744
5571
            case json_integer:
745
            case json_double:
746
747
5571
               if (isdigit (b))
748
               {
749
4214
                  ++ num_digits;
750
751

4214
                  if (top->type == json_integer || flags & flag_num_e)
752
                  {
753
4214
                     if (! (flags & flag_num_e))
754
                     {
755
4214
                        if (flags & flag_num_zero)
756
                        {  sprintf (error, "%u:%u: Unexpected `0` before `%c`", line_and_col, b);
757
                           goto e_failed;
758
                        }
759
760
4214
                        if (num_digits == 1 && b == '0')
761
1
                           flags |= flag_num_zero;
762
                     }
763
                     else
764
                     {
765
                        flags |= flag_num_e_got_sign;
766
                        num_e = (num_e * 10) + (b - '0');
767
                        continue;
768
                     }
769
770
4214
                     top->u.integer = (top->u.integer * 10) + (b - '0');
771
4214
                     continue;
772
                  }
773
774
                  num_fraction = (num_fraction * 10) + (b - '0');
775
                  continue;
776
               }
777
778
1357
               if (b == '+' || b == '-')
779
               {
780
                  if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign))
781
                  {
782
                     flags |= flag_num_e_got_sign;
783
784
                     if (b == '-')
785
                        flags |= flag_num_e_negative;
786
787
                     continue;
788
                  }
789
               }
790

1357
               else if (b == '.' && top->type == json_integer)
791
               {
792
                  if (!num_digits)
793
                  {  sprintf (error, "%u:%u: Expected digit before `.`", line_and_col);
794
                     goto e_failed;
795
                  }
796
797
                  top->type = json_double;
798
                  top->u.dbl = (double) top->u.integer;
799
800
                  num_digits = 0;
801
                  continue;
802
               }
803
804
1357
               if (! (flags & flag_num_e))
805
               {
806
1357
                  if (top->type == json_double)
807
                  {
808
                     if (!num_digits)
809
                     {  sprintf (error, "%u:%u: Expected digit after `.`", line_and_col);
810
                        goto e_failed;
811
                     }
812
813
                     top->u.dbl += ((double) num_fraction) / (pow (10.0, (double) num_digits));
814
                  }
815
816
1357
                  if (b == 'e' || b == 'E')
817
                  {
818
                     flags |= flag_num_e;
819
820
                     if (top->type == json_integer)
821
                     {
822
                        top->type = json_double;
823
                        top->u.dbl = (double) top->u.integer;
824
                     }
825
826
                     num_digits = 0;
827
                     flags &= ~ flag_num_zero;
828
829
                     continue;
830
                  }
831
               }
832
               else
833
               {
834
                  if (!num_digits)
835
                  {  sprintf (error, "%u:%u: Expected digit after `e`", line_and_col);
836
                     goto e_failed;
837
                  }
838
839
                  top->u.dbl *= pow (10.0, (double)
840
                      (flags & flag_num_e_negative ? - num_e : num_e));
841
               }
842
843
1357
               if (flags & flag_num_negative)
844
               {
845
4
                  if (top->type == json_integer)
846
4
                     top->u.integer = - top->u.integer;
847
                  else
848
                     top->u.dbl = - top->u.dbl;
849
               }
850
851
1357
               flags |= flag_next | flag_reproc;
852
1357
               break;
853
854
            default:
855
               break;
856
22239
            };
857
         }
858
859
22239
         if (flags & flag_reproc)
860
         {
861
4054
            flags &= ~ flag_reproc;
862
4054
            -- state.ptr;
863
         }
864
865
22239
         if (flags & flag_next)
866
         {
867
8672
            flags = (flags & ~ flag_next) | flag_need_comma;
868
869
8672
            if (!top->parent)
870
            {
871
               /* root value done */
872
873
168
               flags |= flag_done;
874
168
               continue;
875
            }
876
877
8504
            if (top->parent->type == json_array)
878
1638
               flags |= flag_seek_value;
879
880
8504
            if (!state.first_pass)
881
            {
882
4238
               json_value * parent = top->parent;
883
884
4238
               switch (parent->type)
885
               {
886
3421
                  case json_object:
887
888
3421
                     parent->u.object.values
889
3421
                        [parent->u.object.length].value = top;
890
891
3421
                     break;
892
893
817
                  case json_array:
894
895
817
                     parent->u.array.values
896
817
                           [parent->u.array.length] = top;
897
898
817
                     break;
899
900
                  default:
901
                     break;
902
4266
               };
903
            }
904
905
8504
            if ( (++ top->parent->u.array.length) > state.uint_max)
906
               goto e_overflow;
907
908
8504
            top = top->parent;
909
910
8504
            continue;
911
         }
912
      }
913
914
168
      alloc = root;
915
   }
916
917
84
   return root;
918
919
e_unknown_value:
920
921
   sprintf (error, "%u:%u: Unknown value", line_and_col);
922
   goto e_failed;
923
924
e_alloc_failure:
925
926
   strcpy (error, "Memory allocation failure");
927
   goto e_failed;
928
929
e_overflow:
930
931
   sprintf (error, "%u:%u: Too long (caught overflow)", line_and_col);
932
   goto e_failed;
933
934
1
e_failed:
935
936
1
   if (error_buf)
937
   {
938
1
      if (*error)
939
1
         strcpy (error_buf, error);
940
      else
941
         strcpy (error_buf, "Unknown error");
942
   }
943
944
1
   if (state.first_pass)
945
1
      alloc = root;
946
947
30
   while (alloc)
948
   {
949
29
      top = alloc->_reserved.next_alloc;
950
29
      state.settings.mem_free (alloc, state.settings.user_data);
951
29
      alloc = top;
952
   }
953
954
1
   if (!state.first_pass)
955
      json_value_free_ex (&state.settings, root);
956
957
   return 0;
958
}
959
960
json_value * json_parse (const json_char * json, size_t length)
961
{
962
   json_settings settings = { 0 };
963
   return json_parse_ex (&settings, json, length, 0);
964
}
965
966
83
void json_value_free_ex (json_settings * settings, json_value * value)
967
{
968
83
   json_value * cur_value;
969
970
83
   if (!value)
971
      return;
972
973
83
   value->parent = 0;
974
975
8612
   while (value)
976
   {
977

8529
      switch (value->type)
978
      {
979
1267
         case json_array:
980
981
1267
            if (!value->u.array.length)
982
            {
983
453
               settings->mem_free (value->u.array.values, settings->user_data);
984
453
               break;
985
            }
986
987
814
            value = value->u.array.values [-- value->u.array.length];
988
814
            continue;
989
990
4159
         case json_object:
991
992
4159
            if (!value->u.object.length)
993
            {
994
750
               settings->mem_free (value->u.object.values, settings->user_data);
995
750
               break;
996
            }
997
998
3409
            value = value->u.object.values [-- value->u.object.length].value;
999
3409
            continue;
1000
1001
1615
         case json_string:
1002
1003
1615
            settings->mem_free (value->u.string.ptr, settings->user_data);
1004
1615
            break;
1005
1006
         default:
1007
            break;
1008
4306
      };
1009
1010
4306
      cur_value = value;
1011
4306
      value = value->parent;
1012
4306
      settings->mem_free (cur_value, settings->user_data);
1013
   }
1014
}
1015
1016
void json_value_free (json_value * value)
1017
{
1018
   json_settings settings = { 0 };
1019
   settings.mem_free = default_free;
1020
   json_value_free_ex (&settings, value);
1021
}
1022
1023
19972
json_value * json_value_find (json_value * parent, char * name)
1024
{
1025
19972
    unsigned int i;
1026
19972
    json_value * t;
1027
1028
19972
    if (parent == NULL)
1029
        return NULL;
1030
1031
19972
    if (parent->type == json_object)
1032
20717
        for (i = 0; i < parent->u.object.length; i++)
1033
        {
1034
18258
            if (!strcmp (parent->u.object.values[i].name, name))
1035
3041
                return parent->u.object.values[i].value;
1036
15217
            if ((t = json_value_find(parent->u.object.values[i].value, name)) != NULL)
1037
                return t;
1038
        }
1039
1040
16931
    if (parent->type == json_array)
1041
2831
        for (i = 0; i < parent->u.array.length; i++)
1042
        {
1043
1704
            if ((t = json_value_find(parent->u.array.values[i], name)) != NULL)
1044
                return t;
1045
        }
1046
1047
    return NULL;
1048
}