Coverage Report

Created: 2026-11-12 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/json-c/json_tokener.c
Line
Count
Source
1
/*
2
 * $Id: json_tokener.c,v 1.20 2006/07/25 03:24:50 mclark Exp $
3
 *
4
 * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
5
 * Michael Clark <michael@metaparadigm.com>
6
 *
7
 * This library is free software; you can redistribute it and/or modify
8
 * it under the terms of the MIT license. See COPYING for details.
9
 *
10
 *
11
 * Copyright (c) 2008-2009 Yahoo! Inc.  All rights reserved.
12
 * The copyrights to the contents of this file are licensed under the MIT License
13
 * (https://www.opensource.org/licenses/mit-license.php)
14
 */
15
16
#include "config.h"
17
18
#include "math_compat.h"
19
#include <assert.h>
20
#include <errno.h>
21
#include <limits.h>
22
#include <math.h>
23
#include <stddef.h>
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <string.h>
27
28
#include "debug.h"
29
#include "json_inttypes.h"
30
#include "json_object.h"
31
#include "json_object_private.h"
32
#include "json_tokener.h"
33
#include "json_util.h"
34
#include "printbuf.h"
35
#include "strdup_compat.h"
36
37
#ifdef HAVE_LOCALE_H
38
#include <locale.h>
39
#endif /* HAVE_LOCALE_H */
40
#ifdef HAVE_XLOCALE_H
41
#include <xlocale.h>
42
#endif
43
#ifdef HAVE_STRINGS_H
44
#include <strings.h>
45
#endif /* HAVE_STRINGS_H */
46
47
11.7k
#define jt_hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x)&7) + 9)
48
49
#if !HAVE_STRNCASECMP && defined(_MSC_VER)
50
/* MSC has the version as _strnicmp */
51
#define strncasecmp _strnicmp
52
#elif !HAVE_STRNCASECMP
53
#error You do not have strncasecmp on your system.
54
#endif /* HAVE_STRNCASECMP */
55
56
#if defined(_MSC_VER) && (_MSC_VER <= 1800)
57
/* VS2013 doesn't know about "inline" */
58
#define inline __inline
59
#elif defined(AIX_CC)
60
#define inline
61
#endif
62
63
/* The following helper functions are used to speed up parsing. They
64
 * are faster than their ctype counterparts because they assume that
65
 * the input is in ASCII and that the locale is set to "C". The
66
 * compiler will also inline these functions, providing an additional
67
 * speedup by saving on function calls.
68
 */
69
static inline int is_ws_char(char c)
70
200k
{
71
200k
  return c == ' '
72
199k
      || c == '\t'
73
198k
      || c == '\n'
74
198k
      || c == '\r';
75
200k
}
76
77
static inline int is_hex_char(char c)
78
11.8k
{
79
11.8k
  return (c >= '0' && c <= '9')
80
8.30k
      || (c >= 'A' && c <= 'F')
81
5.09k
      || (c >= 'a' && c <= 'f');
82
11.8k
}
83
84
/* Use C99 NAN by default; if not available, nan("") should work too. */
85
#ifndef NAN
86
#define NAN nan("")
87
#endif /* !NAN */
88
89
static const char json_null_str[] = "null";
90
static const int json_null_str_len = sizeof(json_null_str) - 1;
91
static const char json_inf_str[] = "Infinity";
92
/* Swapped case "Infinity" to avoid need to call tolower() on input chars: */
93
static const char json_inf_str_invert[] = "iNFINITY";
94
static const unsigned int json_inf_str_len = sizeof(json_inf_str) - 1;
95
static const char json_nan_str[] = "NaN";
96
static const int json_nan_str_len = sizeof(json_nan_str) - 1;
97
static const char json_true_str[] = "true";
98
static const int json_true_str_len = sizeof(json_true_str) - 1;
99
static const char json_false_str[] = "false";
100
static const int json_false_str_len = sizeof(json_false_str) - 1;
101
102
/* clang-format off */
103
static const char *json_tokener_errors[] = {
104
  "success",
105
  "continue",
106
  "nesting too deep",
107
  "unexpected end of data",
108
  "unexpected character",
109
  "null expected",
110
  "boolean expected",
111
  "number expected",
112
  "array value separator ',' expected",
113
  "quoted object property name expected",
114
  "object property name separator ':' expected",
115
  "object value separator ',' expected",
116
  "invalid string sequence",
117
  "expected comment",
118
  "invalid utf-8 string",
119
  "buffer size overflow",
120
  "out of memory"
121
};
122
/* clang-format on */
123
124
/**
125
 * validete the utf-8 string in strict model.
126
 * if not utf-8 format, return err.
127
 */
128
static json_bool json_tokener_validate_utf8(const char c, unsigned int *nBytes);
129
130
static int json_tokener_parse_double(const char *buf, int len, double *retval);
131
132
const char *json_tokener_error_desc(enum json_tokener_error jerr)
133
0
{
134
0
  int jerr_int = (int)jerr;
135
0
  if (jerr_int < 0 ||
136
0
      jerr_int >= (int)(sizeof(json_tokener_errors) / sizeof(json_tokener_errors[0])))
137
0
    return "Unknown error, "
138
0
           "invalid json_tokener_error value passed to json_tokener_error_desc()";
139
0
  return json_tokener_errors[jerr];
140
0
}
141
142
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok)
143
0
{
144
0
  return tok->err;
145
0
}
146
147
/* Stuff for decoding unicode sequences */
148
2.43k
#define IS_HIGH_SURROGATE(uc) (((uc)&0xFC00) == 0xD800)
149
1.91k
#define IS_LOW_SURROGATE(uc) (((uc)&0xFC00) == 0xDC00)
150
441
#define DECODE_SURROGATE_PAIR(hi, lo) ((((hi)&0x3FF) << 10) + ((lo)&0x3FF) + 0x10000)
151
static unsigned char utf8_replacement_char[3] = {0xEF, 0xBF, 0xBD};
152
153
struct json_tokener *json_tokener_new_ex(int depth)
154
2.50k
{
155
2.50k
  struct json_tokener *tok;
156
157
2.50k
  tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
158
2.50k
  if (!tok)
159
0
    return NULL;
160
2.50k
  tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
161
2.50k
  if (!tok->stack)
162
0
  {
163
0
    free(tok);
164
0
    return NULL;
165
0
  }
166
2.50k
  tok->pb = printbuf_new();
167
2.50k
  if (!tok->pb)
168
0
  {
169
0
    free(tok->stack);
170
0
    free(tok);
171
0
    return NULL;
172
0
  }
173
2.50k
  tok->max_depth = depth;
174
2.50k
  json_tokener_reset(tok);
175
2.50k
  return tok;
176
2.50k
}
177
178
struct json_tokener *json_tokener_new(void)
179
2.50k
{
180
2.50k
  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
181
2.50k
}
182
183
void json_tokener_free(struct json_tokener *tok)
184
2.50k
{
185
2.50k
  json_tokener_reset(tok);
186
2.50k
  if (tok->pb)
187
2.50k
    printbuf_free(tok->pb);
188
2.50k
  free(tok->stack);
189
2.50k
  free(tok);
190
2.50k
}
191
192
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
193
89.5k
{
194
89.5k
  tok->stack[depth].state = json_tokener_state_eatws;
195
89.5k
  tok->stack[depth].saved_state = json_tokener_state_start;
196
89.5k
  json_object_put(tok->stack[depth].current);
197
89.5k
  tok->stack[depth].current = NULL;
198
89.5k
  free(tok->stack[depth].obj_field_name);
199
89.5k
  tok->stack[depth].obj_field_name = NULL;
200
89.5k
}
201
202
void json_tokener_reset(struct json_tokener *tok)
203
5.01k
{
204
5.01k
  int i;
205
5.01k
  if (!tok)
206
0
    return;
207
208
11.7k
  for (i = tok->depth; i >= 0; i--)
209
6.75k
    json_tokener_reset_level(tok, i);
210
5.01k
  tok->depth = 0;
211
5.01k
  tok->err = json_tokener_success;
212
5.01k
}
213
214
struct json_object *json_tokener_parse(const char *str)
215
2.50k
{
216
2.50k
  enum json_tokener_error jerr_ignored;
217
2.50k
  struct json_object *obj;
218
2.50k
  obj = json_tokener_parse_verbose(str, &jerr_ignored);
219
2.50k
  return obj;
220
2.50k
}
221
222
struct json_object *json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
223
2.50k
{
224
2.50k
  struct json_tokener *tok;
225
2.50k
  struct json_object *obj;
226
227
2.50k
  tok = json_tokener_new();
228
2.50k
  if (!tok)
229
0
  {
230
0
    *error = json_tokener_error_memory;
231
0
    return NULL;
232
0
  }
233
2.50k
  obj = json_tokener_parse_ex(tok, str, -1);
234
2.50k
  *error = tok->err;
235
2.50k
  if (tok->err != json_tokener_success
236
#if 0
237
    /* This would be a more sensible default, and cause parsing
238
     * things like "null123" to fail when the caller can't know
239
     * where the parsing left off, but starting to fail would
240
     * be a notable behaviour change.  Save for a 1.0 release.
241
     */
242
      || json_tokener_get_parse_end(tok) != strlen(str)
243
#endif
244
2.50k
  )
245
246
2.04k
  {
247
2.04k
    if (obj != NULL)
248
0
      json_object_put(obj);
249
2.04k
    obj = NULL;
250
2.04k
  }
251
252
2.50k
  json_tokener_free(tok);
253
2.50k
  return obj;
254
2.50k
}
255
256
987k
#define state tok->stack[tok->depth].state
257
356k
#define saved_state tok->stack[tok->depth].saved_state
258
170k
#define current tok->stack[tok->depth].current
259
58.4k
#define obj_field_name tok->stack[tok->depth].obj_field_name
260
261
/* Optimization:
262
 * json_tokener_parse_ex() consumed a lot of CPU in its main loop,
263
 * iterating character-by character.  A large performance boost is
264
 * achieved by using tighter loops to locally handle units such as
265
 * comments and strings.  Loops that handle an entire token within
266
 * their scope also gather entire strings and pass them to
267
 * printbuf_memappend() in a single call, rather than calling
268
 * printbuf_memappend() one char at a time.
269
 *
270
 * PEEK_CHAR() and ADVANCE_CHAR() macros are used for code that is
271
 * common to both the main loop and the tighter loops.
272
 */
273
274
/* PEEK_CHAR(dest, tok) macro:
275
 *   Peeks at the current char and stores it in dest.
276
 *   Returns 1 on success, sets tok->err and returns 0 if no more chars.
277
 *   Implicit inputs:  str, len, nBytesp vars
278
 */
279
#define PEEK_CHAR(dest, tok)                                                 \
280
478k
  (((tok)->char_offset == len)                                         \
281
478k
       ? (((tok)->depth == 0 && state == json_tokener_state_eatws &&   \
282
0
           saved_state == json_tokener_state_finish)                   \
283
0
              ? (((tok)->err = json_tokener_success), 0)               \
284
0
              : (((tok)->err = json_tokener_continue), 0))             \
285
478k
       : (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) &&                \
286
478k
           (!json_tokener_validate_utf8(*str, nBytesp)))               \
287
478k
              ? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
288
478k
              : (((dest) = *str), 1)))
289
290
/* ADVANCE_CHAR() macro:
291
 *   Increments str & tok->char_offset.
292
 *   For convenience of existing conditionals, returns the old value of c (0 on eof).
293
 *   Implicit inputs:  c var
294
 */
295
803k
#define ADVANCE_CHAR(str, tok) (++(str), ((tok)->char_offset)++, c)
296
297
/* printbuf_memappend_checked(p, s, l) macro:
298
 *   Add string s of length l to printbuffer p.
299
 *   If operation fails abort parse operation with memory error.
300
 */
301
#define printbuf_memappend_checked(p, s, l)                   \
302
80.7k
  do {                                                  \
303
80.7k
    if (printbuf_memappend((p), (s), (l)) < 0)    \
304
80.7k
    {                                             \
305
0
      tok->err = json_tokener_error_memory; \
306
0
      goto out;                             \
307
0
    }                                             \
308
80.7k
  } while (0)
309
310
/* End optimization macro defs */
311
312
struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *str, int len)
313
2.50k
{
314
2.50k
  struct json_object *obj = NULL;
315
2.50k
  char c = '\1';
316
2.50k
  unsigned int nBytes = 0;
317
2.50k
  unsigned int *nBytesp = &nBytes;
318
319
2.50k
#ifdef HAVE_USELOCALE
320
2.50k
  locale_t oldlocale = uselocale(NULL);
321
2.50k
  locale_t newloc;
322
#elif defined(HAVE_SETLOCALE)
323
  char *oldlocale = NULL;
324
#endif
325
326
2.50k
  tok->char_offset = 0;
327
2.50k
  tok->err = json_tokener_success;
328
329
  /* this interface is presently not 64-bit clean due to the int len argument
330
   * and the internal printbuf interface that takes 32-bit int len arguments
331
   * so the function limits the maximum string size to INT32_MAX (2GB).
332
   * If the function is called with len == -1 then strlen is called to check
333
   * the string length is less than INT32_MAX (2GB)
334
   */
335
2.50k
  if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX))
336
0
  {
337
0
    tok->err = json_tokener_error_size;
338
0
    return NULL;
339
0
  }
340
341
2.50k
#ifdef HAVE_USELOCALE
342
2.50k
  {
343
2.50k
    locale_t duploc = duplocale(oldlocale);
344
2.50k
    if (duploc == NULL && errno == ENOMEM)
345
0
    {
346
0
      tok->err = json_tokener_error_memory;
347
0
      return NULL;
348
0
    }
349
2.50k
    newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
350
2.50k
    if (newloc == NULL)
351
0
    {
352
0
      tok->err = json_tokener_error_memory;
353
0
      freelocale(duploc);
354
0
      return NULL;
355
0
    }
356
#ifdef NEWLOCALE_NEEDS_FREELOCALE
357
    // Older versions of FreeBSD (<12.4) don't free the locale
358
    // passed to newlocale(), so do it here
359
    freelocale(duploc);
360
#endif
361
2.50k
    uselocale(newloc);
362
2.50k
  }
363
#elif defined(HAVE_SETLOCALE)
364
  {
365
    char *tmplocale;
366
    tmplocale = setlocale(LC_NUMERIC, NULL);
367
    if (tmplocale)
368
    {
369
      oldlocale = strdup(tmplocale);
370
      if (oldlocale == NULL)
371
      {
372
        tok->err = json_tokener_error_memory;
373
        return NULL;
374
      }
375
    }
376
    setlocale(LC_NUMERIC, "C");
377
  }
378
#endif
379
380
132k
  while (PEEK_CHAR(c, tok)) // Note: c might be '\0' !
381
132k
  {
382
383
518k
  redo_char:
384
518k
    switch (state)
385
518k
    {
386
387
196k
    case json_tokener_state_eatws:
388
      /* Advance until we change state */
389
198k
      while (is_ws_char(c))
390
2.14k
      {
391
2.14k
        if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
392
0
          goto out;
393
2.14k
      }
394
196k
      if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
395
1.54k
      {
396
1.54k
        printbuf_reset(tok->pb);
397
1.54k
        printbuf_memappend_checked(tok->pb, &c, 1);
398
1.54k
        state = json_tokener_state_comment_start;
399
1.54k
      }
400
195k
      else
401
195k
      {
402
195k
        state = saved_state;
403
195k
        goto redo_char;
404
195k
      }
405
1.54k
      break;
406
407
44.2k
    case json_tokener_state_start:
408
44.2k
      switch (c)
409
44.2k
      {
410
2.65k
      case '{':
411
2.65k
        state = json_tokener_state_eatws;
412
2.65k
        saved_state = json_tokener_state_object_field_start;
413
2.65k
        current = json_object_new_object();
414
2.65k
        if (current == NULL)
415
0
        {
416
0
          tok->err = json_tokener_error_memory;
417
0
          goto out;
418
0
        }
419
2.65k
        break;
420
5.72k
      case '[':
421
5.72k
        state = json_tokener_state_eatws;
422
5.72k
        saved_state = json_tokener_state_array;
423
5.72k
        current = json_object_new_array();
424
5.72k
        if (current == NULL)
425
0
        {
426
0
          tok->err = json_tokener_error_memory;
427
0
          goto out;
428
0
        }
429
5.72k
        break;
430
5.72k
      case 'I':
431
685
      case 'i':
432
685
        state = json_tokener_state_inf;
433
685
        printbuf_reset(tok->pb);
434
685
        tok->st_pos = 0;
435
685
        goto redo_char;
436
875
      case 'N':
437
1.74k
      case 'n':
438
1.74k
        state = json_tokener_state_null; // or NaN
439
1.74k
        printbuf_reset(tok->pb);
440
1.74k
        tok->st_pos = 0;
441
1.74k
        goto redo_char;
442
841
      case '\'':
443
841
        if (tok->flags & JSON_TOKENER_STRICT)
444
0
        {
445
          /* in STRICT mode only double-quote are allowed */
446
0
          tok->err = json_tokener_error_parse_unexpected;
447
0
          goto out;
448
0
        }
449
        /* FALLTHRU */
450
1.51k
      case '"':
451
1.51k
        state = json_tokener_state_string;
452
1.51k
        printbuf_reset(tok->pb);
453
1.51k
        tok->quote_char = c;
454
1.51k
        break;
455
279
      case 'T':
456
990
      case 't':
457
1.49k
      case 'F':
458
1.79k
      case 'f':
459
1.79k
        state = json_tokener_state_boolean;
460
1.79k
        printbuf_reset(tok->pb);
461
1.79k
        tok->st_pos = 0;
462
1.79k
        goto redo_char;
463
15.0k
      case '0':
464
17.3k
      case '1':
465
18.6k
      case '2':
466
19.3k
      case '3':
467
20.2k
      case '4':
468
21.1k
      case '5':
469
23.7k
      case '6':
470
24.7k
      case '7':
471
27.4k
      case '8':
472
28.1k
      case '9':
473
29.8k
      case '-':
474
29.8k
        state = json_tokener_state_number;
475
29.8k
        printbuf_reset(tok->pb);
476
29.8k
        tok->is_double = 0;
477
29.8k
        goto redo_char;
478
218
      default: tok->err = json_tokener_error_parse_unexpected; goto out;
479
44.2k
      }
480
9.90k
      break;
481
482
40.6k
    case json_tokener_state_finish:
483
40.6k
      if (tok->depth == 0)
484
423
        goto out;
485
40.1k
      obj = json_object_get(current);
486
40.1k
      json_tokener_reset_level(tok, tok->depth);
487
40.1k
      tok->depth--;
488
40.1k
      goto redo_char;
489
490
1.26k
    case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
491
1.26k
    {
492
      /* If we were guaranteed to have len set, then we could (usually) handle
493
       * the entire "Infinity" check in a single strncmp (strncasecmp), but
494
       * since len might be -1 (i.e. "read until \0"), we need to check it
495
       * a character at a time.
496
       * Trying to handle it both ways would make this code considerably more
497
       * complicated with likely little performance benefit.
498
       */
499
1.26k
      int is_negative = 0;
500
501
      /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
502
10.9k
      while (tok->st_pos < (int)json_inf_str_len)
503
9.76k
      {
504
9.76k
        char inf_char = *str;
505
9.76k
        if (inf_char != json_inf_str[tok->st_pos] &&
506
5.01k
            ((tok->flags & JSON_TOKENER_STRICT) ||
507
5.01k
              inf_char != json_inf_str_invert[tok->st_pos])
508
9.76k
           )
509
69
        {
510
69
          tok->err = json_tokener_error_parse_unexpected;
511
69
          goto out;
512
69
        }
513
9.69k
        tok->st_pos++;
514
9.69k
        (void)ADVANCE_CHAR(str, tok);
515
9.69k
        if (!PEEK_CHAR(c, tok))
516
0
        {
517
          /* out of input chars, for now at least */
518
0
          goto out;
519
0
        }
520
9.69k
      }
521
      /* We checked the full length of "Infinity", so create the object.
522
       * When handling -Infinity, the number parsing code will have dropped
523
       * the "-" into tok->pb for us, so check it now.
524
       */
525
1.19k
      if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
526
566
      {
527
566
        is_negative = 1;
528
566
      }
529
1.19k
      current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
530
1.19k
      if (current == NULL)
531
0
      {
532
0
        tok->err = json_tokener_error_memory;
533
0
        goto out;
534
0
      }
535
1.19k
      saved_state = json_tokener_state_finish;
536
1.19k
      state = json_tokener_state_eatws;
537
1.19k
      goto redo_char;
538
1.19k
    }
539
0
    break;
540
7.36k
    case json_tokener_state_null: /* aka starts with 'n' */
541
7.36k
    {
542
7.36k
      int size;
543
7.36k
      int size_nan;
544
7.36k
      printbuf_memappend_checked(tok->pb, &c, 1);
545
7.36k
      size = json_min(tok->st_pos + 1, json_null_str_len);
546
7.36k
      size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
547
7.36k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
548
7.36k
           strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
549
3.47k
          (strncmp(json_null_str, tok->pb->buf, size) == 0))
550
3.89k
      {
551
3.89k
        if (tok->st_pos == json_null_str_len)
552
531
        {
553
531
          current = NULL;
554
531
          saved_state = json_tokener_state_finish;
555
531
          state = json_tokener_state_eatws;
556
531
          goto redo_char;
557
531
        }
558
3.89k
      }
559
3.47k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
560
3.47k
                strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
561
91
               (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
562
3.38k
      {
563
3.38k
        if (tok->st_pos == json_nan_str_len)
564
1.12k
        {
565
1.12k
          current = json_object_new_double(NAN);
566
1.12k
          if (current == NULL)
567
0
          {
568
0
            tok->err = json_tokener_error_memory;
569
0
            goto out;
570
0
          }
571
1.12k
          saved_state = json_tokener_state_finish;
572
1.12k
          state = json_tokener_state_eatws;
573
1.12k
          goto redo_char;
574
1.12k
        }
575
3.38k
      }
576
91
      else
577
91
      {
578
91
        tok->err = json_tokener_error_parse_null;
579
91
        goto out;
580
91
      }
581
5.62k
      tok->st_pos++;
582
5.62k
    }
583
0
    break;
584
585
1.54k
    case json_tokener_state_comment_start:
586
1.54k
      if (c == '*')
587
528
      {
588
528
        state = json_tokener_state_comment;
589
528
      }
590
1.01k
      else if (c == '/')
591
974
      {
592
974
        state = json_tokener_state_comment_eol;
593
974
      }
594
41
      else
595
41
      {
596
41
        tok->err = json_tokener_error_parse_comment;
597
41
        goto out;
598
41
      }
599
1.50k
      printbuf_memappend_checked(tok->pb, &c, 1);
600
1.50k
      break;
601
602
3.83k
    case json_tokener_state_comment:
603
3.83k
    {
604
      /* Advance until we change state */
605
3.83k
      const char *case_start = str;
606
96.1k
      while (c != '*')
607
92.3k
      {
608
92.3k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
609
124
        {
610
124
          printbuf_memappend_checked(tok->pb, case_start,
611
124
                                     str - case_start);
612
124
          goto out;
613
124
        }
614
92.3k
      }
615
3.71k
      printbuf_memappend_checked(tok->pb, case_start, 1 + str - case_start);
616
3.71k
      state = json_tokener_state_comment_end;
617
3.71k
    }
618
0
    break;
619
620
974
    case json_tokener_state_comment_eol:
621
974
    {
622
      /* Advance until we change state */
623
974
      const char *case_start = str;
624
32.4k
      while (c != '\n')
625
31.5k
      {
626
31.5k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
627
77
        {
628
77
          printbuf_memappend_checked(tok->pb, case_start,
629
77
                                     str - case_start);
630
77
          goto out;
631
77
        }
632
31.5k
      }
633
897
      printbuf_memappend_checked(tok->pb, case_start, str - case_start);
634
897
      MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
635
897
      state = json_tokener_state_eatws;
636
897
    }
637
0
    break;
638
639
3.71k
    case json_tokener_state_comment_end:
640
3.71k
      printbuf_memappend_checked(tok->pb, &c, 1);
641
3.71k
      if (c == '/')
642
365
      {
643
365
        MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
644
365
        state = json_tokener_state_eatws;
645
365
      }
646
3.34k
      else
647
3.34k
      {
648
3.34k
        state = json_tokener_state_comment;
649
3.34k
      }
650
3.71k
      break;
651
652
5.17k
    case json_tokener_state_string:
653
5.17k
    {
654
      /* Advance until we change state */
655
5.17k
      const char *case_start = str;
656
48.0k
      while (1)
657
48.0k
      {
658
48.0k
        if (c == tok->quote_char)
659
1.11k
        {
660
1.11k
          printbuf_memappend_checked(tok->pb, case_start,
661
1.11k
                                     str - case_start);
662
1.11k
          current =
663
1.11k
              json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
664
1.11k
          if (current == NULL)
665
0
          {
666
0
            tok->err = json_tokener_error_memory;
667
0
            goto out;
668
0
          }
669
1.11k
          saved_state = json_tokener_state_finish;
670
1.11k
          state = json_tokener_state_eatws;
671
1.11k
          break;
672
1.11k
        }
673
46.9k
        else if (c == '\\')
674
3.77k
        {
675
3.77k
          printbuf_memappend_checked(tok->pb, case_start,
676
3.77k
                                     str - case_start);
677
3.77k
          saved_state = json_tokener_state_string;
678
3.77k
          state = json_tokener_state_string_escape;
679
3.77k
          break;
680
3.77k
        }
681
43.1k
        else if ((tok->flags & JSON_TOKENER_STRICT) && c <= 0x1f)
682
0
        {
683
          // Disallow control characters in strict mode
684
0
          tok->err = json_tokener_error_parse_string;
685
0
          goto out;
686
0
        }
687
43.1k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
688
290
        {
689
290
          printbuf_memappend_checked(tok->pb, case_start,
690
290
                                     str - case_start);
691
290
          goto out;
692
290
        }
693
43.1k
      }
694
5.17k
    }
695
4.88k
    break;
696
697
4.88k
    case json_tokener_state_string_escape:
698
4.39k
      switch (c)
699
4.39k
      {
700
229
      case '"':
701
880
      case '\\':
702
1.09k
      case '/':
703
1.09k
        printbuf_memappend_checked(tok->pb, &c, 1);
704
1.09k
        state = saved_state;
705
1.09k
        break;
706
225
      case 'b':
707
474
      case 'n':
708
682
      case 'r':
709
973
      case 't':
710
1.31k
      case 'f':
711
1.31k
        if (c == 'b')
712
225
          printbuf_memappend_checked(tok->pb, "\b", 1);
713
1.08k
        else if (c == 'n')
714
249
          printbuf_memappend_checked(tok->pb, "\n", 1);
715
840
        else if (c == 'r')
716
208
          printbuf_memappend_checked(tok->pb, "\r", 1);
717
632
        else if (c == 't')
718
291
          printbuf_memappend_checked(tok->pb, "\t", 1);
719
341
        else if (c == 'f')
720
341
          printbuf_memappend_checked(tok->pb, "\f", 1);
721
1.31k
        state = saved_state;
722
1.31k
        break;
723
1.92k
      case 'u':
724
1.92k
        tok->ucs_char = 0;
725
1.92k
        tok->st_pos = 0;
726
1.92k
        state = json_tokener_state_escape_unicode;
727
1.92k
        break;
728
58
      default: tok->err = json_tokener_error_parse_string; goto out;
729
4.39k
      }
730
4.33k
      break;
731
732
      // ===================================================
733
734
4.33k
    case json_tokener_state_escape_unicode:
735
3.00k
    {
736
      /* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */
737
11.8k
      while (1)
738
11.8k
      {
739
11.8k
        if (!c || !is_hex_char(c))
740
79
        {
741
79
          tok->err = json_tokener_error_parse_string;
742
79
          goto out;
743
79
        }
744
11.7k
        tok->ucs_char |=
745
11.7k
            ((unsigned int)jt_hexdigit(c) << ((3 - tok->st_pos) * 4));
746
11.7k
        tok->st_pos++;
747
11.7k
        if (tok->st_pos >= 4)
748
2.93k
          break;
749
750
8.86k
        (void)ADVANCE_CHAR(str, tok);
751
8.86k
        if (!PEEK_CHAR(c, tok))
752
0
        {
753
          /*
754
           * We're out of characters in the current call to
755
           * json_tokener_parse(), but a subsequent call might
756
           * provide us with more, so leave our current state
757
           * as-is (including tok->high_surrogate) and return.
758
           */
759
0
          goto out;
760
0
        }
761
8.86k
      }
762
2.93k
      tok->st_pos = 0;
763
764
      /* Now, we have a full \uNNNN sequence in tok->ucs_char */
765
766
      /* If the *previous* sequence was a high surrogate ... */
767
2.93k
      if (tok->high_surrogate)
768
1.06k
      {
769
1.06k
        if (IS_LOW_SURROGATE(tok->ucs_char))
770
441
        {
771
          /* Recalculate the ucs_char, then fall thru to process normally */
772
441
          tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate,
773
441
                                                tok->ucs_char);
774
441
        }
775
625
        else
776
625
        {
777
          /* High surrogate was not followed by a low surrogate
778
           * Replace the high and process the rest normally
779
           */
780
625
          printbuf_memappend_checked(tok->pb,
781
625
                                     (char *)utf8_replacement_char, 3);
782
625
        }
783
1.06k
        tok->high_surrogate = 0;
784
1.06k
      }
785
786
2.93k
      if (tok->ucs_char < 0x80)
787
279
      {
788
279
        unsigned char unescaped_utf[1];
789
279
        unescaped_utf[0] = tok->ucs_char;
790
279
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 1);
791
279
      }
792
2.65k
      else if (tok->ucs_char < 0x800)
793
219
      {
794
219
        unsigned char unescaped_utf[2];
795
219
        unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
796
219
        unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
797
219
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 2);
798
219
      }
799
2.43k
      else if (IS_HIGH_SURROGATE(tok->ucs_char))
800
1.58k
      {
801
        /*
802
         * The next two characters should be \u, HOWEVER,
803
         * we can't simply peek ahead here, because the
804
         * characters we need might not be passed to us
805
         * until a subsequent call to json_tokener_parse.
806
         * Instead, transition through a couple of states.
807
         * (now):
808
         *   _escape_unicode => _unicode_need_escape
809
         * (see a '\\' char):
810
         *   _unicode_need_escape => _unicode_need_u
811
         * (see a 'u' char):
812
         *   _unicode_need_u => _escape_unicode
813
         *      ...and we'll end up back around here.
814
         */
815
1.58k
        tok->high_surrogate = tok->ucs_char;
816
1.58k
        tok->ucs_char = 0;
817
1.58k
        state = json_tokener_state_escape_unicode_need_escape;
818
1.58k
        break;
819
1.58k
      }
820
848
      else if (IS_LOW_SURROGATE(tok->ucs_char))
821
211
      {
822
        /* Got a low surrogate not preceded by a high */
823
211
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
824
211
      }
825
637
      else if (tok->ucs_char < 0x10000)
826
396
      {
827
396
        unsigned char unescaped_utf[3];
828
396
        unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
829
396
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
830
396
        unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
831
396
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 3);
832
396
      }
833
241
      else if (tok->ucs_char < 0x110000)
834
241
      {
835
241
        unsigned char unescaped_utf[4];
836
241
        unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
837
241
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
838
241
        unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
839
241
        unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
840
241
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 4);
841
241
      }
842
0
      else
843
0
      {
844
        /* Don't know what we got--insert the replacement char */
845
0
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
846
0
      }
847
1.34k
      state = saved_state; // i.e. _state_string or _state_object_field
848
1.34k
    }
849
0
    break;
850
851
1.58k
    case json_tokener_state_escape_unicode_need_escape:
852
      // We get here after processing a high_surrogate
853
      // require a '\\' char
854
1.58k
      if (!c || c != '\\')
855
240
      {
856
        /* Got a high surrogate without another sequence following
857
         * it.  Put a replacement char in for the high surrogate
858
         * and pop back up to _state_string or _state_object_field.
859
         */
860
240
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
861
240
        tok->high_surrogate = 0;
862
240
        tok->ucs_char = 0;
863
240
        tok->st_pos = 0;
864
240
        state = saved_state;
865
240
        goto redo_char;
866
240
      }
867
1.34k
      state = json_tokener_state_escape_unicode_need_u;
868
1.34k
      break;
869
870
1.34k
    case json_tokener_state_escape_unicode_need_u:
871
      /* We already had a \ char, check that it's \u */
872
1.34k
      if (!c || c != 'u')
873
257
      {
874
        /* Got a high surrogate with some non-unicode escape
875
         * sequence following it.
876
         * Put a replacement char in for the high surrogate
877
         * and handle the escape sequence normally.
878
         */
879
257
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
880
257
        tok->high_surrogate = 0;
881
257
        tok->ucs_char = 0;
882
257
        tok->st_pos = 0;
883
257
        state = json_tokener_state_string_escape;
884
257
        goto redo_char;
885
257
      }
886
1.08k
      state = json_tokener_state_escape_unicode;
887
1.08k
      break;
888
889
      // ===================================================
890
891
9.44k
    case json_tokener_state_boolean:
892
9.44k
    {
893
9.44k
      int size1, size2;
894
9.44k
      printbuf_memappend_checked(tok->pb, &c, 1);
895
9.44k
      size1 = json_min(tok->st_pos + 1, json_true_str_len);
896
9.44k
      size2 = json_min(tok->st_pos + 1, json_false_str_len);
897
9.44k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
898
9.44k
           strncasecmp(json_true_str, tok->pb->buf, size1) == 0) ||
899
4.71k
          (strncmp(json_true_str, tok->pb->buf, size1) == 0))
900
4.73k
      {
901
4.73k
        if (tok->st_pos == json_true_str_len)
902
926
        {
903
926
          current = json_object_new_boolean(1);
904
926
          if (current == NULL)
905
0
          {
906
0
            tok->err = json_tokener_error_memory;
907
0
            goto out;
908
0
          }
909
926
          saved_state = json_tokener_state_finish;
910
926
          state = json_tokener_state_eatws;
911
926
          goto redo_char;
912
926
        }
913
4.73k
      }
914
4.71k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
915
4.71k
                strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
916
134
               (strncmp(json_false_str, tok->pb->buf, size2) == 0))
917
4.57k
      {
918
4.57k
        if (tok->st_pos == json_false_str_len)
919
739
        {
920
739
          current = json_object_new_boolean(0);
921
739
          if (current == NULL)
922
0
          {
923
0
            tok->err = json_tokener_error_memory;
924
0
            goto out;
925
0
          }
926
739
          saved_state = json_tokener_state_finish;
927
739
          state = json_tokener_state_eatws;
928
739
          goto redo_char;
929
739
        }
930
4.57k
      }
931
134
      else
932
134
      {
933
134
        tok->err = json_tokener_error_parse_boolean;
934
134
        goto out;
935
134
      }
936
7.65k
      tok->st_pos++;
937
7.65k
    }
938
0
    break;
939
940
29.8k
    case json_tokener_state_number:
941
29.8k
    {
942
      /* Advance until we change state */
943
29.8k
      const char *case_start = str;
944
29.8k
      int case_len = 0;
945
29.8k
      int is_exponent = 0;
946
29.8k
      int neg_sign_ok = 1;
947
29.8k
      int pos_sign_ok = 0;
948
29.8k
      if (printbuf_length(tok->pb) > 0)
949
0
      {
950
        /* We don't save all state from the previous incremental parse
951
           so we need to re-generate it based on the saved string so far.
952
         */
953
0
        char *e_loc = strchr(tok->pb->buf, 'e');
954
0
        if (!e_loc)
955
0
          e_loc = strchr(tok->pb->buf, 'E');
956
0
        if (e_loc)
957
0
        {
958
0
          char *last_saved_char =
959
0
              &tok->pb->buf[printbuf_length(tok->pb) - 1];
960
0
          is_exponent = 1;
961
0
          pos_sign_ok = neg_sign_ok = 1;
962
          /* If the "e" isn't at the end, we can't start with a '-' */
963
0
          if (e_loc != last_saved_char)
964
0
          {
965
0
            neg_sign_ok = 0;
966
0
            pos_sign_ok = 0;
967
0
          }
968
          // else leave it set to 1, i.e. start of the new input
969
0
        }
970
0
      }
971
972
95.8k
      while (c && ((c >= '0' && c <= '9') ||
973
33.7k
                   (!is_exponent && (c == 'e' || c == 'E')) ||
974
32.6k
                   (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') ||
975
30.2k
                   (!tok->is_double && c == '.')))
976
65.9k
      {
977
65.9k
        pos_sign_ok = neg_sign_ok = 0;
978
65.9k
        ++case_len;
979
980
        /* non-digit characters checks */
981
        /* note: since the main loop condition to get here was
982
         * an input starting with 0-9 or '-', we are
983
         * protected from input starting with '.' or
984
         * e/E.
985
         */
986
65.9k
        switch (c)
987
65.9k
        {
988
762
        case '.':
989
762
          tok->is_double = 1;
990
762
          pos_sign_ok = 1;
991
762
          neg_sign_ok = 1;
992
762
          break;
993
452
        case 'e': /* FALLTHRU */
994
1.09k
        case 'E':
995
1.09k
          is_exponent = 1;
996
1.09k
          tok->is_double = 1;
997
          /* the exponent part can begin with a negative sign */
998
1.09k
          pos_sign_ok = neg_sign_ok = 1;
999
1.09k
          break;
1000
64.0k
        default: break;
1001
65.9k
        }
1002
1003
65.9k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
1004
0
        {
1005
0
          printbuf_memappend_checked(tok->pb, case_start, case_len);
1006
0
          goto out;
1007
0
        }
1008
65.9k
      }
1009
      /*
1010
        Now we know c isn't a valid number char, but check whether
1011
        it might have been intended to be, and return a potentially
1012
        more understandable error right away.
1013
        However, if we're at the top-level, use the number as-is
1014
        because c can be part of a new object to parse on the
1015
        next call to json_tokener_parse().
1016
       */
1017
29.8k
      if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
1018
1.94k
          c != 'I' && c != 'i' && !is_ws_char(c))
1019
169
      {
1020
169
        tok->err = json_tokener_error_parse_number;
1021
169
        goto out;
1022
169
      }
1023
29.6k
      if (case_len > 0)
1024
29.6k
        printbuf_memappend_checked(tok->pb, case_start, case_len);
1025
1026
      // Check for -Infinity
1027
29.6k
      if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
1028
583
      {
1029
583
        state = json_tokener_state_inf;
1030
583
        tok->st_pos = 0;
1031
583
        goto redo_char;
1032
583
      }
1033
29.1k
      if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
1034
1.54k
      {
1035
        /* Trim some chars off the end, to allow things
1036
           like "123e+" to parse ok. */
1037
3.32k
        while (printbuf_length(tok->pb) > 1)
1038
2.61k
        {
1039
2.61k
          char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1];
1040
2.61k
          if (last_char != 'e' && last_char != 'E' &&
1041
1.54k
              last_char != '-' && last_char != '+')
1042
836
          {
1043
836
            break;
1044
836
          }
1045
1.78k
          tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0';
1046
1.78k
          printbuf_length(tok->pb)--;
1047
1.78k
        }
1048
1.54k
      }
1049
29.1k
    }
1050
0
      {
1051
29.1k
        int64_t num64;
1052
29.1k
        uint64_t numuint64;
1053
29.1k
        double numd;
1054
29.1k
        if (!tok->is_double && tok->pb->buf[0] == '-' &&
1055
832
            json_parse_int64(tok->pb->buf, &num64) == 0)
1056
793
        {
1057
793
          if (errno == ERANGE && (tok->flags & JSON_TOKENER_STRICT))
1058
0
          {
1059
0
            tok->err = json_tokener_error_parse_number;
1060
0
            goto out;
1061
0
          }
1062
793
          current = json_object_new_int64(num64);
1063
793
          if (current == NULL)
1064
0
          {
1065
0
            tok->err = json_tokener_error_memory;
1066
0
            goto out;
1067
0
          }
1068
793
        }
1069
28.3k
        else if (!tok->is_double && tok->pb->buf[0] != '-' &&
1070
26.7k
                 json_parse_uint64(tok->pb->buf, &numuint64) == 0)
1071
26.7k
        {
1072
26.7k
          if (errno == ERANGE && (tok->flags & JSON_TOKENER_STRICT))
1073
0
          {
1074
0
            tok->err = json_tokener_error_parse_number;
1075
0
            goto out;
1076
0
          }
1077
26.7k
          if (numuint64 && tok->pb->buf[0] == '0' &&
1078
220
              (tok->flags & JSON_TOKENER_STRICT))
1079
0
          {
1080
0
            tok->err = json_tokener_error_parse_number;
1081
0
            goto out;
1082
0
          }
1083
26.7k
          if (numuint64 <= INT64_MAX)
1084
26.2k
          {
1085
26.2k
            num64 = (uint64_t)numuint64;
1086
26.2k
            current = json_object_new_int64(num64);
1087
26.2k
            if (current == NULL)
1088
0
            {
1089
0
              tok->err = json_tokener_error_memory;
1090
0
              goto out;
1091
0
            }
1092
26.2k
          }
1093
467
          else
1094
467
          {
1095
467
            current = json_object_new_uint64(numuint64);
1096
467
            if (current == NULL)
1097
0
            {
1098
0
              tok->err = json_tokener_error_memory;
1099
0
              goto out;
1100
0
            }
1101
467
          }
1102
26.7k
        }
1103
1.57k
        else if (tok->is_double &&
1104
1.54k
                 json_tokener_parse_double(
1105
1.54k
                     tok->pb->buf, printbuf_length(tok->pb), &numd) == 0)
1106
1.53k
        {
1107
1.53k
          current = json_object_new_double_s(numd, tok->pb->buf);
1108
1.53k
          if (current == NULL)
1109
0
          {
1110
0
            tok->err = json_tokener_error_memory;
1111
0
            goto out;
1112
0
          }
1113
1.53k
        }
1114
49
        else
1115
49
        {
1116
49
          tok->err = json_tokener_error_parse_number;
1117
49
          goto out;
1118
49
        }
1119
29.0k
        saved_state = json_tokener_state_finish;
1120
29.0k
        state = json_tokener_state_eatws;
1121
29.0k
        goto redo_char;
1122
29.1k
      }
1123
0
      break;
1124
1125
27.0k
    case json_tokener_state_array_after_sep:
1126
32.7k
    case json_tokener_state_array:
1127
32.7k
      if (c == ']')
1128
2.87k
      {
1129
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1130
2.87k
        json_object_array_shrink(current, 0);
1131
1132
2.87k
        if (state == json_tokener_state_array_after_sep &&
1133
197
            (tok->flags & JSON_TOKENER_STRICT))
1134
0
        {
1135
0
          tok->err = json_tokener_error_parse_unexpected;
1136
0
          goto out;
1137
0
        }
1138
2.87k
        saved_state = json_tokener_state_finish;
1139
2.87k
        state = json_tokener_state_eatws;
1140
2.87k
      }
1141
29.8k
      else
1142
29.8k
      {
1143
29.8k
        if (tok->depth >= tok->max_depth - 1)
1144
4
        {
1145
4
          tok->err = json_tokener_error_depth;
1146
4
          goto out;
1147
4
        }
1148
29.8k
        state = json_tokener_state_array_add;
1149
29.8k
        tok->depth++;
1150
29.8k
        json_tokener_reset_level(tok, tok->depth);
1151
29.8k
        goto redo_char;
1152
29.8k
      }
1153
2.87k
      break;
1154
1155
28.7k
    case json_tokener_state_array_add:
1156
28.7k
      if (json_object_array_add(current, obj) != 0)
1157
0
      {
1158
0
        tok->err = json_tokener_error_memory;
1159
0
        goto out;
1160
0
      }
1161
28.7k
      saved_state = json_tokener_state_array_sep;
1162
28.7k
      state = json_tokener_state_eatws;
1163
28.7k
      goto redo_char;
1164
1165
28.7k
    case json_tokener_state_array_sep:
1166
28.7k
      if (c == ']')
1167
1.57k
      {
1168
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1169
1.57k
        json_object_array_shrink(current, 0);
1170
1171
1.57k
        saved_state = json_tokener_state_finish;
1172
1.57k
        state = json_tokener_state_eatws;
1173
1.57k
      }
1174
27.1k
      else if (c == ',')
1175
27.0k
      {
1176
27.0k
        saved_state = json_tokener_state_array_after_sep;
1177
27.0k
        state = json_tokener_state_eatws;
1178
27.0k
      }
1179
157
      else
1180
157
      {
1181
157
        tok->err = json_tokener_error_parse_array;
1182
157
        goto out;
1183
157
      }
1184
28.6k
      break;
1185
1186
28.6k
    case json_tokener_state_object_field_start:
1187
13.3k
    case json_tokener_state_object_field_start_after_sep:
1188
13.3k
      if (c == '}')
1189
901
      {
1190
901
        if (state == json_tokener_state_object_field_start_after_sep &&
1191
194
            (tok->flags & JSON_TOKENER_STRICT))
1192
0
        {
1193
0
          tok->err = json_tokener_error_parse_unexpected;
1194
0
          goto out;
1195
0
        }
1196
901
        saved_state = json_tokener_state_finish;
1197
901
        state = json_tokener_state_eatws;
1198
901
      }
1199
12.4k
      else if (c == '"' || c == '\'')
1200
12.2k
      {
1201
12.2k
        tok->quote_char = c;
1202
12.2k
        printbuf_reset(tok->pb);
1203
12.2k
        state = json_tokener_state_object_field;
1204
12.2k
      }
1205
219
      else
1206
219
      {
1207
219
        tok->err = json_tokener_error_parse_object_key_name;
1208
219
        goto out;
1209
219
      }
1210
13.1k
      break;
1211
1212
13.1k
    case json_tokener_state_object_field:
1213
12.5k
    {
1214
      /* Advance until we change state */
1215
12.5k
      const char *case_start = str;
1216
106k
      while (1)
1217
106k
      {
1218
106k
        if (c == tok->quote_char)
1219
12.0k
        {
1220
12.0k
          printbuf_memappend_checked(tok->pb, case_start,
1221
12.0k
                                     str - case_start);
1222
12.0k
          obj_field_name = strdup(tok->pb->buf);
1223
12.0k
          if (obj_field_name == NULL)
1224
0
          {
1225
0
            tok->err = json_tokener_error_memory;
1226
0
            goto out;
1227
0
          }
1228
12.0k
          saved_state = json_tokener_state_object_field_end;
1229
12.0k
          state = json_tokener_state_eatws;
1230
12.0k
          break;
1231
12.0k
        }
1232
94.1k
        else if (c == '\\')
1233
361
        {
1234
361
          printbuf_memappend_checked(tok->pb, case_start,
1235
361
                                     str - case_start);
1236
361
          saved_state = json_tokener_state_object_field;
1237
361
          state = json_tokener_state_string_escape;
1238
361
          break;
1239
361
        }
1240
93.7k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
1241
115
        {
1242
115
          printbuf_memappend_checked(tok->pb, case_start,
1243
115
                                     str - case_start);
1244
115
          goto out;
1245
115
        }
1246
93.7k
      }
1247
12.5k
    }
1248
12.4k
    break;
1249
1250
12.4k
    case json_tokener_state_object_field_end:
1251
12.0k
      if (c == ':')
1252
12.0k
      {
1253
12.0k
        saved_state = json_tokener_state_object_value;
1254
12.0k
        state = json_tokener_state_eatws;
1255
12.0k
      }
1256
44
      else
1257
44
      {
1258
44
        tok->err = json_tokener_error_parse_object_key_sep;
1259
44
        goto out;
1260
44
      }
1261
12.0k
      break;
1262
1263
12.0k
    case json_tokener_state_object_value:
1264
12.0k
      if (tok->depth >= tok->max_depth - 1)
1265
2
      {
1266
2
        tok->err = json_tokener_error_depth;
1267
2
        goto out;
1268
2
      }
1269
12.0k
      state = json_tokener_state_object_value_add;
1270
12.0k
      tok->depth++;
1271
12.0k
      json_tokener_reset_level(tok, tok->depth);
1272
12.0k
      goto redo_char;
1273
1274
11.4k
    case json_tokener_state_object_value_add:
1275
11.4k
      if (json_object_object_add(current, obj_field_name, obj) != 0)
1276
0
      {
1277
0
        tok->err = json_tokener_error_memory;
1278
0
        goto out;
1279
0
      }
1280
11.4k
      free(obj_field_name);
1281
11.4k
      obj_field_name = NULL;
1282
11.4k
      saved_state = json_tokener_state_object_sep;
1283
11.4k
      state = json_tokener_state_eatws;
1284
11.4k
      goto redo_char;
1285
1286
11.4k
    case json_tokener_state_object_sep:
1287
      /* { */
1288
11.4k
      if (c == '}')
1289
621
      {
1290
621
        saved_state = json_tokener_state_finish;
1291
621
        state = json_tokener_state_eatws;
1292
621
      }
1293
10.8k
      else if (c == ',')
1294
10.7k
      {
1295
10.7k
        saved_state = json_tokener_state_object_field_start_after_sep;
1296
10.7k
        state = json_tokener_state_eatws;
1297
10.7k
      }
1298
107
      else
1299
107
      {
1300
107
        tok->err = json_tokener_error_parse_object_value_sep;
1301
107
        goto out;
1302
107
      }
1303
11.3k
      break;
1304
518k
    }
1305
129k
    (void)ADVANCE_CHAR(str, tok);
1306
129k
    if (!c) // This is the char *before* advancing
1307
39
      break;
1308
129k
  } /* while(PEEK_CHAR) */
1309
1310
2.50k
out:
1311
2.50k
  if ((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && (nBytes != 0))
1312
0
  {
1313
0
    tok->err = json_tokener_error_parse_utf8_string;
1314
0
  }
1315
2.50k
  if (c && (state == json_tokener_state_finish) && (tok->depth == 0) &&
1316
25
      (tok->flags & (JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS)) ==
1317
25
          JSON_TOKENER_STRICT)
1318
0
  {
1319
    /* unexpected char after JSON data */
1320
0
    tok->err = json_tokener_error_parse_unexpected;
1321
0
  }
1322
2.50k
  if (!c)
1323
2.06k
  {
1324
    /* We hit an eof char (0) */
1325
2.06k
    if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
1326
1.62k
      tok->err = json_tokener_error_parse_eof;
1327
2.06k
  }
1328
1329
2.50k
#ifdef HAVE_USELOCALE
1330
2.50k
  uselocale(oldlocale);
1331
2.50k
  freelocale(newloc);
1332
#elif defined(HAVE_SETLOCALE)
1333
  setlocale(LC_NUMERIC, oldlocale);
1334
  free(oldlocale);
1335
#endif
1336
1337
2.50k
  if (tok->err == json_tokener_success)
1338
460
  {
1339
460
    json_object *ret = json_object_get(current);
1340
460
    int ii;
1341
1342
    /* Partially reset, so we parse additional objects on subsequent calls. */
1343
1.11k
    for (ii = tok->depth; ii >= 0; ii--)
1344
655
      json_tokener_reset_level(tok, ii);
1345
460
    return ret;
1346
460
  }
1347
1348
2.04k
  MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
1349
2.04k
           tok->char_offset);
1350
2.04k
  return NULL;
1351
2.50k
}
1352
1353
static json_bool json_tokener_validate_utf8(const char c, unsigned int *nBytes)
1354
0
{
1355
0
  unsigned char chr = c;
1356
0
  if (*nBytes == 0)
1357
0
  {
1358
0
    if (chr >= 0x80)
1359
0
    {
1360
0
      if ((chr & 0xe0) == 0xc0)
1361
0
        *nBytes = 1;
1362
0
      else if ((chr & 0xf0) == 0xe0)
1363
0
        *nBytes = 2;
1364
0
      else if ((chr & 0xf8) == 0xf0)
1365
0
        *nBytes = 3;
1366
0
      else
1367
0
        return 0;
1368
0
    }
1369
0
  }
1370
0
  else
1371
0
  {
1372
0
    if ((chr & 0xC0) != 0x80)
1373
0
      return 0;
1374
0
    (*nBytes)--;
1375
0
  }
1376
0
  return 1;
1377
0
}
1378
1379
void json_tokener_set_flags(struct json_tokener *tok, int flags)
1380
0
{
1381
0
  tok->flags = flags;
1382
0
}
1383
1384
size_t json_tokener_get_parse_end(struct json_tokener *tok)
1385
0
{
1386
0
  assert(tok->char_offset >= 0); /* Drop this line when char_offset becomes a size_t */
1387
0
  return (size_t)tok->char_offset;
1388
0
}
1389
1390
static int json_tokener_parse_double(const char *buf, int len, double *retval)
1391
1.54k
{
1392
1.54k
  char *end;
1393
1.54k
  *retval = strtod(buf, &end);
1394
1.54k
  if (buf + len == end)
1395
1.53k
    return 0; // It worked
1396
10
  return 1;
1397
1.54k
}