Coverage Report

Created: 2026-02-22 06:11

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