Coverage Report

Created: 2026-09-28 06:27

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.4k
#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
198k
{
71
198k
  return c == ' '
72
197k
      || c == '\t'
73
196k
      || c == '\n'
74
196k
      || c == '\r';
75
198k
}
76
77
static inline int is_hex_char(char c)
78
11.5k
{
79
11.5k
  return (c >= '0' && c <= '9')
80
8.20k
      || (c >= 'A' && c <= 'F')
81
4.79k
      || (c >= 'a' && c <= 'f');
82
11.5k
}
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.40k
#define IS_HIGH_SURROGATE(uc) (((uc)&0xFC00) == 0xD800)
149
1.89k
#define IS_LOW_SURROGATE(uc) (((uc)&0xFC00) == 0xDC00)
150
432
#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.44k
{
155
2.44k
  struct json_tokener *tok;
156
157
2.44k
  tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
158
2.44k
  if (!tok)
159
0
    return NULL;
160
2.44k
  tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
161
2.44k
  if (!tok->stack)
162
0
  {
163
0
    free(tok);
164
0
    return NULL;
165
0
  }
166
2.44k
  tok->pb = printbuf_new();
167
2.44k
  if (!tok->pb)
168
0
  {
169
0
    free(tok->stack);
170
0
    free(tok);
171
0
    return NULL;
172
0
  }
173
2.44k
  tok->max_depth = depth;
174
2.44k
  json_tokener_reset(tok);
175
2.44k
  return tok;
176
2.44k
}
177
178
struct json_tokener *json_tokener_new(void)
179
2.44k
{
180
2.44k
  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
181
2.44k
}
182
183
void json_tokener_free(struct json_tokener *tok)
184
2.44k
{
185
2.44k
  json_tokener_reset(tok);
186
2.44k
  if (tok->pb)
187
2.44k
    printbuf_free(tok->pb);
188
2.44k
  free(tok->stack);
189
2.44k
  free(tok);
190
2.44k
}
191
192
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
193
90.3k
{
194
90.3k
  tok->stack[depth].state = json_tokener_state_eatws;
195
90.3k
  tok->stack[depth].saved_state = json_tokener_state_start;
196
90.3k
  json_object_put(tok->stack[depth].current);
197
90.3k
  tok->stack[depth].current = NULL;
198
90.3k
  free(tok->stack[depth].obj_field_name);
199
90.3k
  tok->stack[depth].obj_field_name = NULL;
200
90.3k
}
201
202
void json_tokener_reset(struct json_tokener *tok)
203
4.89k
{
204
4.89k
  int i;
205
4.89k
  if (!tok)
206
0
    return;
207
208
11.4k
  for (i = tok->depth; i >= 0; i--)
209
6.58k
    json_tokener_reset_level(tok, i);
210
4.89k
  tok->depth = 0;
211
4.89k
  tok->err = json_tokener_success;
212
4.89k
}
213
214
struct json_object *json_tokener_parse(const char *str)
215
2.44k
{
216
2.44k
  enum json_tokener_error jerr_ignored;
217
2.44k
  struct json_object *obj;
218
2.44k
  obj = json_tokener_parse_verbose(str, &jerr_ignored);
219
2.44k
  return obj;
220
2.44k
}
221
222
struct json_object *json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
223
2.44k
{
224
2.44k
  struct json_tokener *tok;
225
2.44k
  struct json_object *obj;
226
227
2.44k
  tok = json_tokener_new();
228
2.44k
  if (!tok)
229
0
  {
230
0
    *error = json_tokener_error_memory;
231
0
    return NULL;
232
0
  }
233
2.44k
  obj = json_tokener_parse_ex(tok, str, -1);
234
2.44k
  *error = tok->err;
235
2.44k
  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.44k
  )
245
246
2.01k
  {
247
2.01k
    if (obj != NULL)
248
0
      json_object_put(obj);
249
2.01k
    obj = NULL;
250
2.01k
  }
251
252
2.44k
  json_tokener_free(tok);
253
2.44k
  return obj;
254
2.44k
}
255
256
971k
#define state tok->stack[tok->depth].state
257
352k
#define saved_state tok->stack[tok->depth].saved_state
258
172k
#define current tok->stack[tok->depth].current
259
49.9k
#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
482k
  (((tok)->char_offset == len)                                         \
281
482k
       ? (((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
482k
       : (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) &&                \
286
482k
           (!json_tokener_validate_utf8(*str, nBytesp)))               \
287
482k
              ? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
288
482k
              : (((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
819k
#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
75.9k
  do {                                                  \
303
75.9k
    if (printbuf_memappend((p), (s), (l)) < 0)    \
304
75.9k
    {                                             \
305
0
      tok->err = json_tokener_error_memory; \
306
0
      goto out;                             \
307
0
    }                                             \
308
75.9k
  } 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.44k
{
314
2.44k
  struct json_object *obj = NULL;
315
2.44k
  char c = '\1';
316
2.44k
  unsigned int nBytes = 0;
317
2.44k
  unsigned int *nBytesp = &nBytes;
318
319
2.44k
#ifdef HAVE_USELOCALE
320
2.44k
  locale_t oldlocale = uselocale(NULL);
321
2.44k
  locale_t newloc;
322
#elif defined(HAVE_SETLOCALE)
323
  char *oldlocale = NULL;
324
#endif
325
326
2.44k
  tok->char_offset = 0;
327
2.44k
  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.44k
  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.44k
#ifdef HAVE_USELOCALE
342
2.44k
  {
343
2.44k
    locale_t duploc = duplocale(oldlocale);
344
2.44k
    if (duploc == NULL && errno == ENOMEM)
345
0
    {
346
0
      tok->err = json_tokener_error_memory;
347
0
      return NULL;
348
0
    }
349
2.44k
    newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
350
2.44k
    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.44k
    uselocale(newloc);
362
2.44k
  }
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
123k
  while (PEEK_CHAR(c, tok)) // Note: c might be '\0' !
381
123k
  {
382
383
511k
  redo_char:
384
511k
    switch (state)
385
511k
    {
386
387
195k
    case json_tokener_state_eatws:
388
      /* Advance until we change state */
389
196k
      while (is_ws_char(c))
390
1.87k
      {
391
1.87k
        if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
392
0
          goto out;
393
1.87k
      }
394
195k
      if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
395
1.28k
      {
396
1.28k
        printbuf_reset(tok->pb);
397
1.28k
        printbuf_memappend_checked(tok->pb, &c, 1);
398
1.28k
        state = json_tokener_state_comment_start;
399
1.28k
      }
400
193k
      else
401
193k
      {
402
193k
        state = saved_state;
403
193k
        goto redo_char;
404
193k
      }
405
1.28k
      break;
406
407
44.6k
    case json_tokener_state_start:
408
44.6k
      switch (c)
409
44.6k
      {
410
2.61k
      case '{':
411
2.61k
        state = json_tokener_state_eatws;
412
2.61k
        saved_state = json_tokener_state_object_field_start;
413
2.61k
        current = json_object_new_object();
414
2.61k
        if (current == NULL)
415
0
        {
416
0
          tok->err = json_tokener_error_memory;
417
0
          goto out;
418
0
        }
419
2.61k
        break;
420
5.63k
      case '[':
421
5.63k
        state = json_tokener_state_eatws;
422
5.63k
        saved_state = json_tokener_state_array;
423
5.63k
        current = json_object_new_array();
424
5.63k
        if (current == NULL)
425
0
        {
426
0
          tok->err = json_tokener_error_memory;
427
0
          goto out;
428
0
        }
429
5.63k
        break;
430
5.63k
      case 'I':
431
683
      case 'i':
432
683
        state = json_tokener_state_inf;
433
683
        printbuf_reset(tok->pb);
434
683
        tok->st_pos = 0;
435
683
        goto redo_char;
436
736
      case 'N':
437
1.77k
      case 'n':
438
1.77k
        state = json_tokener_state_null; // or NaN
439
1.77k
        printbuf_reset(tok->pb);
440
1.77k
        tok->st_pos = 0;
441
1.77k
        goto redo_char;
442
923
      case '\'':
443
923
        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.58k
      case '"':
451
1.58k
        state = json_tokener_state_string;
452
1.58k
        printbuf_reset(tok->pb);
453
1.58k
        tok->quote_char = c;
454
1.58k
        break;
455
571
      case 'T':
456
882
      case 't':
457
1.39k
      case 'F':
458
1.92k
      case 'f':
459
1.92k
        state = json_tokener_state_boolean;
460
1.92k
        printbuf_reset(tok->pb);
461
1.92k
        tok->st_pos = 0;
462
1.92k
        goto redo_char;
463
16.3k
      case '0':
464
18.8k
      case '1':
465
19.8k
      case '2':
466
20.5k
      case '3':
467
21.0k
      case '4':
468
21.9k
      case '5':
469
24.3k
      case '6':
470
25.1k
      case '7':
471
27.7k
      case '8':
472
28.3k
      case '9':
473
30.2k
      case '-':
474
30.2k
        state = json_tokener_state_number;
475
30.2k
        printbuf_reset(tok->pb);
476
30.2k
        tok->is_double = 0;
477
30.2k
        goto redo_char;
478
223
      default: tok->err = json_tokener_error_parse_unexpected; goto out;
479
44.6k
      }
480
9.82k
      break;
481
482
41.1k
    case json_tokener_state_finish:
483
41.1k
      if (tok->depth == 0)
484
397
        goto out;
485
40.7k
      obj = json_object_get(current);
486
40.7k
      json_tokener_reset_level(tok, tok->depth);
487
40.7k
      tok->depth--;
488
40.7k
      goto redo_char;
489
490
1.41k
    case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
491
1.41k
    {
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.41k
      int is_negative = 0;
500
501
      /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
502
12.2k
      while (tok->st_pos < (int)json_inf_str_len)
503
10.9k
      {
504
10.9k
        char inf_char = *str;
505
10.9k
        if (inf_char != json_inf_str[tok->st_pos] &&
506
5.74k
            ((tok->flags & JSON_TOKENER_STRICT) ||
507
5.74k
              inf_char != json_inf_str_invert[tok->st_pos])
508
10.9k
           )
509
69
        {
510
69
          tok->err = json_tokener_error_parse_unexpected;
511
69
          goto out;
512
69
        }
513
10.8k
        tok->st_pos++;
514
10.8k
        (void)ADVANCE_CHAR(str, tok);
515
10.8k
        if (!PEEK_CHAR(c, tok))
516
0
        {
517
          /* out of input chars, for now at least */
518
0
          goto out;
519
0
        }
520
10.8k
      }
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.34k
      if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
526
711
      {
527
711
        is_negative = 1;
528
711
      }
529
1.34k
      current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
530
1.34k
      if (current == NULL)
531
0
      {
532
0
        tok->err = json_tokener_error_memory;
533
0
        goto out;
534
0
      }
535
1.34k
      saved_state = json_tokener_state_finish;
536
1.34k
      state = json_tokener_state_eatws;
537
1.34k
      goto redo_char;
538
1.34k
    }
539
0
    break;
540
7.54k
    case json_tokener_state_null: /* aka starts with 'n' */
541
7.54k
    {
542
7.54k
      int size;
543
7.54k
      int size_nan;
544
7.54k
      printbuf_memappend_checked(tok->pb, &c, 1);
545
7.54k
      size = json_min(tok->st_pos + 1, json_null_str_len);
546
7.54k
      size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
547
7.54k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
548
7.54k
           strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
549
3.53k
          (strncmp(json_null_str, tok->pb->buf, size) == 0))
550
4.01k
      {
551
4.01k
        if (tok->st_pos == json_null_str_len)
552
550
        {
553
550
          current = NULL;
554
550
          saved_state = json_tokener_state_finish;
555
550
          state = json_tokener_state_eatws;
556
550
          goto redo_char;
557
550
        }
558
4.01k
      }
559
3.53k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
560
3.53k
                strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
561
85
               (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
562
3.45k
      {
563
3.45k
        if (tok->st_pos == json_nan_str_len)
564
1.14k
        {
565
1.14k
          current = json_object_new_double(NAN);
566
1.14k
          if (current == NULL)
567
0
          {
568
0
            tok->err = json_tokener_error_memory;
569
0
            goto out;
570
0
          }
571
1.14k
          saved_state = json_tokener_state_finish;
572
1.14k
          state = json_tokener_state_eatws;
573
1.14k
          goto redo_char;
574
1.14k
        }
575
3.45k
      }
576
85
      else
577
85
      {
578
85
        tok->err = json_tokener_error_parse_null;
579
85
        goto out;
580
85
      }
581
5.76k
      tok->st_pos++;
582
5.76k
    }
583
0
    break;
584
585
1.28k
    case json_tokener_state_comment_start:
586
1.28k
      if (c == '*')
587
397
      {
588
397
        state = json_tokener_state_comment;
589
397
      }
590
891
      else if (c == '/')
591
853
      {
592
853
        state = json_tokener_state_comment_eol;
593
853
      }
594
38
      else
595
38
      {
596
38
        tok->err = json_tokener_error_parse_comment;
597
38
        goto out;
598
38
      }
599
1.25k
      printbuf_memappend_checked(tok->pb, &c, 1);
600
1.25k
      break;
601
602
1.92k
    case json_tokener_state_comment:
603
1.92k
    {
604
      /* Advance until we change state */
605
1.92k
      const char *case_start = str;
606
95.6k
      while (c != '*')
607
93.8k
      {
608
93.8k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
609
120
        {
610
120
          printbuf_memappend_checked(tok->pb, case_start,
611
120
                                     str - case_start);
612
120
          goto out;
613
120
        }
614
93.8k
      }
615
1.80k
      printbuf_memappend_checked(tok->pb, case_start, 1 + str - case_start);
616
1.80k
      state = json_tokener_state_comment_end;
617
1.80k
    }
618
0
    break;
619
620
853
    case json_tokener_state_comment_eol:
621
853
    {
622
      /* Advance until we change state */
623
853
      const char *case_start = str;
624
32.8k
      while (c != '\n')
625
32.1k
      {
626
32.1k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
627
73
        {
628
73
          printbuf_memappend_checked(tok->pb, case_start,
629
73
                                     str - case_start);
630
73
          goto out;
631
73
        }
632
32.1k
      }
633
780
      printbuf_memappend_checked(tok->pb, case_start, str - case_start);
634
780
      MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
635
780
      state = json_tokener_state_eatws;
636
780
    }
637
0
    break;
638
639
1.80k
    case json_tokener_state_comment_end:
640
1.80k
      printbuf_memappend_checked(tok->pb, &c, 1);
641
1.80k
      if (c == '/')
642
238
      {
643
238
        MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
644
238
        state = json_tokener_state_eatws;
645
238
      }
646
1.56k
      else
647
1.56k
      {
648
1.56k
        state = json_tokener_state_comment;
649
1.56k
      }
650
1.80k
      break;
651
652
5.29k
    case json_tokener_state_string:
653
5.29k
    {
654
      /* Advance until we change state */
655
5.29k
      const char *case_start = str;
656
53.8k
      while (1)
657
53.8k
      {
658
53.8k
        if (c == tok->quote_char)
659
1.19k
        {
660
1.19k
          printbuf_memappend_checked(tok->pb, case_start,
661
1.19k
                                     str - case_start);
662
1.19k
          current =
663
1.19k
              json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
664
1.19k
          if (current == NULL)
665
0
          {
666
0
            tok->err = json_tokener_error_memory;
667
0
            goto out;
668
0
          }
669
1.19k
          saved_state = json_tokener_state_finish;
670
1.19k
          state = json_tokener_state_eatws;
671
1.19k
          break;
672
1.19k
        }
673
52.6k
        else if (c == '\\')
674
3.82k
        {
675
3.82k
          printbuf_memappend_checked(tok->pb, case_start,
676
3.82k
                                     str - case_start);
677
3.82k
          saved_state = json_tokener_state_string;
678
3.82k
          state = json_tokener_state_string_escape;
679
3.82k
          break;
680
3.82k
        }
681
48.8k
        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
48.8k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
688
278
        {
689
278
          printbuf_memappend_checked(tok->pb, case_start,
690
278
                                     str - case_start);
691
278
          goto out;
692
278
        }
693
48.8k
      }
694
5.29k
    }
695
5.01k
    break;
696
697
5.01k
    case json_tokener_state_string_escape:
698
4.34k
      switch (c)
699
4.34k
      {
700
230
      case '"':
701
772
      case '\\':
702
996
      case '/':
703
996
        printbuf_memappend_checked(tok->pb, &c, 1);
704
996
        state = saved_state;
705
996
        break;
706
239
      case 'b':
707
450
      case 'n':
708
648
      case 'r':
709
936
      case 't':
710
1.39k
      case 'f':
711
1.39k
        if (c == 'b')
712
239
          printbuf_memappend_checked(tok->pb, "\b", 1);
713
1.15k
        else if (c == 'n')
714
211
          printbuf_memappend_checked(tok->pb, "\n", 1);
715
941
        else if (c == 'r')
716
198
          printbuf_memappend_checked(tok->pb, "\r", 1);
717
743
        else if (c == 't')
718
288
          printbuf_memappend_checked(tok->pb, "\t", 1);
719
455
        else if (c == 'f')
720
455
          printbuf_memappend_checked(tok->pb, "\f", 1);
721
1.39k
        state = saved_state;
722
1.39k
        break;
723
1.90k
      case 'u':
724
1.90k
        tok->ucs_char = 0;
725
1.90k
        tok->st_pos = 0;
726
1.90k
        state = json_tokener_state_escape_unicode;
727
1.90k
        break;
728
56
      default: tok->err = json_tokener_error_parse_string; goto out;
729
4.34k
      }
730
4.29k
      break;
731
732
      // ===================================================
733
734
4.29k
    case json_tokener_state_escape_unicode:
735
2.93k
    {
736
      /* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */
737
11.5k
      while (1)
738
11.5k
      {
739
11.5k
        if (!c || !is_hex_char(c))
740
80
        {
741
80
          tok->err = json_tokener_error_parse_string;
742
80
          goto out;
743
80
        }
744
11.4k
        tok->ucs_char |=
745
11.4k
            ((unsigned int)jt_hexdigit(c) << ((3 - tok->st_pos) * 4));
746
11.4k
        tok->st_pos++;
747
11.4k
        if (tok->st_pos >= 4)
748
2.85k
          break;
749
750
8.63k
        (void)ADVANCE_CHAR(str, tok);
751
8.63k
        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.63k
      }
762
2.85k
      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.85k
      if (tok->high_surrogate)
768
1.01k
      {
769
1.01k
        if (IS_LOW_SURROGATE(tok->ucs_char))
770
432
        {
771
          /* Recalculate the ucs_char, then fall thru to process normally */
772
432
          tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate,
773
432
                                                tok->ucs_char);
774
432
        }
775
583
        else
776
583
        {
777
          /* High surrogate was not followed by a low surrogate
778
           * Replace the high and process the rest normally
779
           */
780
583
          printbuf_memappend_checked(tok->pb,
781
583
                                     (char *)utf8_replacement_char, 3);
782
583
        }
783
1.01k
        tok->high_surrogate = 0;
784
1.01k
      }
785
786
2.85k
      if (tok->ucs_char < 0x80)
787
254
      {
788
254
        unsigned char unescaped_utf[1];
789
254
        unescaped_utf[0] = tok->ucs_char;
790
254
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 1);
791
254
      }
792
2.60k
      else if (tok->ucs_char < 0x800)
793
198
      {
794
198
        unsigned char unescaped_utf[2];
795
198
        unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
796
198
        unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
797
198
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 2);
798
198
      }
799
2.40k
      else if (IS_HIGH_SURROGATE(tok->ucs_char))
800
1.52k
      {
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.52k
        tok->high_surrogate = tok->ucs_char;
816
1.52k
        tok->ucs_char = 0;
817
1.52k
        state = json_tokener_state_escape_unicode_need_escape;
818
1.52k
        break;
819
1.52k
      }
820
883
      else if (IS_LOW_SURROGATE(tok->ucs_char))
821
226
      {
822
        /* Got a low surrogate not preceded by a high */
823
226
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
824
226
      }
825
657
      else if (tok->ucs_char < 0x10000)
826
424
      {
827
424
        unsigned char unescaped_utf[3];
828
424
        unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
829
424
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
830
424
        unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
831
424
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 3);
832
424
      }
833
233
      else if (tok->ucs_char < 0x110000)
834
233
      {
835
233
        unsigned char unescaped_utf[4];
836
233
        unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
837
233
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
838
233
        unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
839
233
        unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
840
233
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 4);
841
233
      }
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.33k
      state = saved_state; // i.e. _state_string or _state_object_field
848
1.33k
    }
849
0
    break;
850
851
1.52k
    case json_tokener_state_escape_unicode_need_escape:
852
      // We get here after processing a high_surrogate
853
      // require a '\\' char
854
1.52k
      if (!c || c != '\\')
855
256
      {
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
256
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
861
256
        tok->high_surrogate = 0;
862
256
        tok->ucs_char = 0;
863
256
        tok->st_pos = 0;
864
256
        state = saved_state;
865
256
        goto redo_char;
866
256
      }
867
1.26k
      state = json_tokener_state_escape_unicode_need_u;
868
1.26k
      break;
869
870
1.26k
    case json_tokener_state_escape_unicode_need_u:
871
      /* We already had a \ char, check that it's \u */
872
1.26k
      if (!c || c != 'u')
873
235
      {
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
235
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
880
235
        tok->high_surrogate = 0;
881
235
        tok->ucs_char = 0;
882
235
        tok->st_pos = 0;
883
235
        state = json_tokener_state_string_escape;
884
235
        goto redo_char;
885
235
      }
886
1.03k
      state = json_tokener_state_escape_unicode;
887
1.03k
      break;
888
889
      // ===================================================
890
891
10.2k
    case json_tokener_state_boolean:
892
10.2k
    {
893
10.2k
      int size1, size2;
894
10.2k
      printbuf_memappend_checked(tok->pb, &c, 1);
895
10.2k
      size1 = json_min(tok->st_pos + 1, json_true_str_len);
896
10.2k
      size2 = json_min(tok->st_pos + 1, json_false_str_len);
897
10.2k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
898
10.2k
           strncasecmp(json_true_str, tok->pb->buf, size1) == 0) ||
899
6.10k
          (strncmp(json_true_str, tok->pb->buf, size1) == 0))
900
4.19k
      {
901
4.19k
        if (tok->st_pos == json_true_str_len)
902
816
        {
903
816
          current = json_object_new_boolean(1);
904
816
          if (current == NULL)
905
0
          {
906
0
            tok->err = json_tokener_error_memory;
907
0
            goto out;
908
0
          }
909
816
          saved_state = json_tokener_state_finish;
910
816
          state = json_tokener_state_eatws;
911
816
          goto redo_char;
912
816
        }
913
4.19k
      }
914
6.10k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
915
6.10k
                strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
916
141
               (strncmp(json_false_str, tok->pb->buf, size2) == 0))
917
5.96k
      {
918
5.96k
        if (tok->st_pos == json_false_str_len)
919
968
        {
920
968
          current = json_object_new_boolean(0);
921
968
          if (current == NULL)
922
0
          {
923
0
            tok->err = json_tokener_error_memory;
924
0
            goto out;
925
0
          }
926
968
          saved_state = json_tokener_state_finish;
927
968
          state = json_tokener_state_eatws;
928
968
          goto redo_char;
929
968
        }
930
5.96k
      }
931
141
      else
932
141
      {
933
141
        tok->err = json_tokener_error_parse_boolean;
934
141
        goto out;
935
141
      }
936
8.37k
      tok->st_pos++;
937
8.37k
    }
938
0
    break;
939
940
30.2k
    case json_tokener_state_number:
941
30.2k
    {
942
      /* Advance until we change state */
943
30.2k
      const char *case_start = str;
944
30.2k
      int case_len = 0;
945
30.2k
      int is_exponent = 0;
946
30.2k
      int neg_sign_ok = 1;
947
30.2k
      int pos_sign_ok = 0;
948
30.2k
      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
34.1k
                   (!is_exponent && (c == 'e' || c == 'E')) ||
974
33.1k
                   (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') ||
975
30.5k
                   (!tok->is_double && c == '.')))
976
65.6k
      {
977
65.6k
        pos_sign_ok = neg_sign_ok = 0;
978
65.6k
        ++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.6k
        switch (c)
987
65.6k
        {
988
709
        case '.':
989
709
          tok->is_double = 1;
990
709
          pos_sign_ok = 1;
991
709
          neg_sign_ok = 1;
992
709
          break;
993
357
        case 'e': /* FALLTHRU */
994
1.04k
        case 'E':
995
1.04k
          is_exponent = 1;
996
1.04k
          tok->is_double = 1;
997
          /* the exponent part can begin with a negative sign */
998
1.04k
          pos_sign_ok = neg_sign_ok = 1;
999
1.04k
          break;
1000
63.8k
        default: break;
1001
65.6k
        }
1002
1003
65.6k
        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.6k
      }
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
30.2k
      if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
1018
1.85k
          c != 'I' && c != 'i' && !is_ws_char(c))
1019
168
      {
1020
168
        tok->err = json_tokener_error_parse_number;
1021
168
        goto out;
1022
168
      }
1023
30.0k
      if (case_len > 0)
1024
30.0k
        printbuf_memappend_checked(tok->pb, case_start, case_len);
1025
1026
      // Check for -Infinity
1027
30.0k
      if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
1028
729
      {
1029
729
        state = json_tokener_state_inf;
1030
729
        tok->st_pos = 0;
1031
729
        goto redo_char;
1032
729
      }
1033
29.3k
      if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
1034
1.43k
      {
1035
        /* Trim some chars off the end, to allow things
1036
           like "123e+" to parse ok. */
1037
3.16k
        while (printbuf_length(tok->pb) > 1)
1038
2.53k
        {
1039
2.53k
          char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1];
1040
2.53k
          if (last_char != 'e' && last_char != 'E' &&
1041
1.51k
              last_char != '-' && last_char != '+')
1042
803
          {
1043
803
            break;
1044
803
          }
1045
1.73k
          tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0';
1046
1.73k
          printbuf_length(tok->pb)--;
1047
1.73k
        }
1048
1.43k
      }
1049
29.3k
    }
1050
0
      {
1051
29.3k
        int64_t num64;
1052
29.3k
        uint64_t numuint64;
1053
29.3k
        double numd;
1054
29.3k
        if (!tok->is_double && tok->pb->buf[0] == '-' &&
1055
834
            json_parse_int64(tok->pb->buf, &num64) == 0)
1056
804
        {
1057
804
          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
804
          current = json_object_new_int64(num64);
1063
804
          if (current == NULL)
1064
0
          {
1065
0
            tok->err = json_tokener_error_memory;
1066
0
            goto out;
1067
0
          }
1068
804
        }
1069
28.5k
        else if (!tok->is_double && tok->pb->buf[0] != '-' &&
1070
27.0k
                 json_parse_uint64(tok->pb->buf, &numuint64) == 0)
1071
27.0k
        {
1072
27.0k
          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
27.0k
          if (numuint64 && tok->pb->buf[0] == '0' &&
1078
209
              (tok->flags & JSON_TOKENER_STRICT))
1079
0
          {
1080
0
            tok->err = json_tokener_error_parse_number;
1081
0
            goto out;
1082
0
          }
1083
27.0k
          if (numuint64 <= INT64_MAX)
1084
26.5k
          {
1085
26.5k
            num64 = (uint64_t)numuint64;
1086
26.5k
            current = json_object_new_int64(num64);
1087
26.5k
            if (current == NULL)
1088
0
            {
1089
0
              tok->err = json_tokener_error_memory;
1090
0
              goto out;
1091
0
            }
1092
26.5k
          }
1093
460
          else
1094
460
          {
1095
460
            current = json_object_new_uint64(numuint64);
1096
460
            if (current == NULL)
1097
0
            {
1098
0
              tok->err = json_tokener_error_memory;
1099
0
              goto out;
1100
0
            }
1101
460
          }
1102
27.0k
        }
1103
1.46k
        else if (tok->is_double &&
1104
1.43k
                 json_tokener_parse_double(
1105
1.43k
                     tok->pb->buf, printbuf_length(tok->pb), &numd) == 0)
1106
1.41k
        {
1107
1.41k
          current = json_object_new_double_s(numd, tok->pb->buf);
1108
1.41k
          if (current == NULL)
1109
0
          {
1110
0
            tok->err = json_tokener_error_memory;
1111
0
            goto out;
1112
0
          }
1113
1.41k
        }
1114
44
        else
1115
44
        {
1116
44
          tok->err = json_tokener_error_parse_number;
1117
44
          goto out;
1118
44
        }
1119
29.2k
        saved_state = json_tokener_state_finish;
1120
29.2k
        state = json_tokener_state_eatws;
1121
29.2k
        goto redo_char;
1122
29.3k
      }
1123
0
      break;
1124
1125
29.4k
    case json_tokener_state_array_after_sep:
1126
35.0k
    case json_tokener_state_array:
1127
35.0k
      if (c == ']')
1128
2.95k
      {
1129
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1130
2.95k
        json_object_array_shrink(current, 0);
1131
1132
2.95k
        if (state == json_tokener_state_array_after_sep &&
1133
210
            (tok->flags & JSON_TOKENER_STRICT))
1134
0
        {
1135
0
          tok->err = json_tokener_error_parse_unexpected;
1136
0
          goto out;
1137
0
        }
1138
2.95k
        saved_state = json_tokener_state_finish;
1139
2.95k
        state = json_tokener_state_eatws;
1140
2.95k
      }
1141
32.0k
      else
1142
32.0k
      {
1143
32.0k
        if (tok->depth >= tok->max_depth - 1)
1144
4
        {
1145
4
          tok->err = json_tokener_error_depth;
1146
4
          goto out;
1147
4
        }
1148
32.0k
        state = json_tokener_state_array_add;
1149
32.0k
        tok->depth++;
1150
32.0k
        json_tokener_reset_level(tok, tok->depth);
1151
32.0k
        goto redo_char;
1152
32.0k
      }
1153
2.95k
      break;
1154
1155
31.0k
    case json_tokener_state_array_add:
1156
31.0k
      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
31.0k
      saved_state = json_tokener_state_array_sep;
1162
31.0k
      state = json_tokener_state_eatws;
1163
31.0k
      goto redo_char;
1164
1165
31.0k
    case json_tokener_state_array_sep:
1166
31.0k
      if (c == ']')
1167
1.44k
      {
1168
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1169
1.44k
        json_object_array_shrink(current, 0);
1170
1171
1.44k
        saved_state = json_tokener_state_finish;
1172
1.44k
        state = json_tokener_state_eatws;
1173
1.44k
      }
1174
29.5k
      else if (c == ',')
1175
29.4k
      {
1176
29.4k
        saved_state = json_tokener_state_array_after_sep;
1177
29.4k
        state = json_tokener_state_eatws;
1178
29.4k
      }
1179
157
      else
1180
157
      {
1181
157
        tok->err = json_tokener_error_parse_array;
1182
157
        goto out;
1183
157
      }
1184
30.8k
      break;
1185
1186
30.8k
    case json_tokener_state_object_field_start:
1187
11.5k
    case json_tokener_state_object_field_start_after_sep:
1188
11.5k
      if (c == '}')
1189
811
      {
1190
811
        if (state == json_tokener_state_object_field_start_after_sep &&
1191
195
            (tok->flags & JSON_TOKENER_STRICT))
1192
0
        {
1193
0
          tok->err = json_tokener_error_parse_unexpected;
1194
0
          goto out;
1195
0
        }
1196
811
        saved_state = json_tokener_state_finish;
1197
811
        state = json_tokener_state_eatws;
1198
811
      }
1199
10.7k
      else if (c == '"' || c == '\'')
1200
10.5k
      {
1201
10.5k
        tok->quote_char = c;
1202
10.5k
        printbuf_reset(tok->pb);
1203
10.5k
        state = json_tokener_state_object_field;
1204
10.5k
      }
1205
169
      else
1206
169
      {
1207
169
        tok->err = json_tokener_error_parse_object_key_name;
1208
169
        goto out;
1209
169
      }
1210
11.3k
      break;
1211
1212
11.3k
    case json_tokener_state_object_field:
1213
10.8k
    {
1214
      /* Advance until we change state */
1215
10.8k
      const char *case_start = str;
1216
108k
      while (1)
1217
108k
      {
1218
108k
        if (c == tok->quote_char)
1219
10.3k
        {
1220
10.3k
          printbuf_memappend_checked(tok->pb, case_start,
1221
10.3k
                                     str - case_start);
1222
10.3k
          obj_field_name = strdup(tok->pb->buf);
1223
10.3k
          if (obj_field_name == NULL)
1224
0
          {
1225
0
            tok->err = json_tokener_error_memory;
1226
0
            goto out;
1227
0
          }
1228
10.3k
          saved_state = json_tokener_state_object_field_end;
1229
10.3k
          state = json_tokener_state_eatws;
1230
10.3k
          break;
1231
10.3k
        }
1232
98.3k
        else if (c == '\\')
1233
290
        {
1234
290
          printbuf_memappend_checked(tok->pb, case_start,
1235
290
                                     str - case_start);
1236
290
          saved_state = json_tokener_state_object_field;
1237
290
          state = json_tokener_state_string_escape;
1238
290
          break;
1239
290
        }
1240
98.1k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
1241
119
        {
1242
119
          printbuf_memappend_checked(tok->pb, case_start,
1243
119
                                     str - case_start);
1244
119
          goto out;
1245
119
        }
1246
98.1k
      }
1247
10.8k
    }
1248
10.6k
    break;
1249
1250
10.6k
    case json_tokener_state_object_field_end:
1251
10.3k
      if (c == ':')
1252
10.3k
      {
1253
10.3k
        saved_state = json_tokener_state_object_value;
1254
10.3k
        state = json_tokener_state_eatws;
1255
10.3k
      }
1256
59
      else
1257
59
      {
1258
59
        tok->err = json_tokener_error_parse_object_key_sep;
1259
59
        goto out;
1260
59
      }
1261
10.3k
      break;
1262
1263
10.3k
    case json_tokener_state_object_value:
1264
10.3k
      if (tok->depth >= tok->max_depth - 1)
1265
2
      {
1266
2
        tok->err = json_tokener_error_depth;
1267
2
        goto out;
1268
2
      }
1269
10.3k
      state = json_tokener_state_object_value_add;
1270
10.3k
      tok->depth++;
1271
10.3k
      json_tokener_reset_level(tok, tok->depth);
1272
10.3k
      goto redo_char;
1273
1274
9.71k
    case json_tokener_state_object_value_add:
1275
9.71k
      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
9.71k
      free(obj_field_name);
1281
9.71k
      obj_field_name = NULL;
1282
9.71k
      saved_state = json_tokener_state_object_sep;
1283
9.71k
      state = json_tokener_state_eatws;
1284
9.71k
      goto redo_char;
1285
1286
9.71k
    case json_tokener_state_object_sep:
1287
      /* { */
1288
9.71k
      if (c == '}')
1289
681
      {
1290
681
        saved_state = json_tokener_state_finish;
1291
681
        state = json_tokener_state_eatws;
1292
681
      }
1293
9.03k
      else if (c == ',')
1294
8.91k
      {
1295
8.91k
        saved_state = json_tokener_state_object_field_start_after_sep;
1296
8.91k
        state = json_tokener_state_eatws;
1297
8.91k
      }
1298
126
      else
1299
126
      {
1300
126
        tok->err = json_tokener_error_parse_object_value_sep;
1301
126
        goto out;
1302
126
      }
1303
9.59k
      break;
1304
511k
    }
1305
121k
    (void)ADVANCE_CHAR(str, tok);
1306
121k
    if (!c) // This is the char *before* advancing
1307
39
      break;
1308
121k
  } /* while(PEEK_CHAR) */
1309
1310
2.44k
out:
1311
2.44k
  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.44k
  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.44k
  if (!c)
1323
1.98k
  {
1324
    /* We hit an eof char (0) */
1325
1.98k
    if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
1326
1.56k
      tok->err = json_tokener_error_parse_eof;
1327
1.98k
  }
1328
1329
2.44k
#ifdef HAVE_USELOCALE
1330
2.44k
  uselocale(oldlocale);
1331
2.44k
  freelocale(newloc);
1332
#elif defined(HAVE_SETLOCALE)
1333
  setlocale(LC_NUMERIC, oldlocale);
1334
  free(oldlocale);
1335
#endif
1336
1337
2.44k
  if (tok->err == json_tokener_success)
1338
432
  {
1339
432
    json_object *ret = json_object_get(current);
1340
432
    int ii;
1341
1342
    /* Partially reset, so we parse additional objects on subsequent calls. */
1343
1.05k
    for (ii = tok->depth; ii >= 0; ii--)
1344
618
      json_tokener_reset_level(tok, ii);
1345
432
    return ret;
1346
432
  }
1347
1348
2.01k
  MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
1349
2.01k
           tok->char_offset);
1350
2.01k
  return NULL;
1351
2.44k
}
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.43k
{
1392
1.43k
  char *end;
1393
1.43k
  *retval = strtod(buf, &end);
1394
1.43k
  if (buf + len == end)
1395
1.41k
    return 0; // It worked
1396
14
  return 1;
1397
1.43k
}