Coverage Report

Created: 2026-08-12 06:14

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.3k
#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
958k
{
71
958k
  return c == ' '
72
757k
      || c == '\t'
73
734k
      || c == '\n'
74
732k
      || c == '\r';
75
958k
}
76
77
static inline int is_hex_char(char c)
78
11.3k
{
79
11.3k
  return (c >= '0' && c <= '9')
80
3.76k
      || (c >= 'A' && c <= 'F')
81
240
      || (c >= 'a' && c <= 'f');
82
11.3k
}
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
403
{
134
403
  int jerr_int = (int)jerr;
135
403
  if (jerr_int < 0 ||
136
403
      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
403
  return json_tokener_errors[jerr];
140
403
}
141
142
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok)
143
806
{
144
806
  return tok->err;
145
806
}
146
147
/* Stuff for decoding unicode sequences */
148
1.91k
#define IS_HIGH_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xD800)
149
1.64k
#define IS_LOW_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xDC00)
150
296
#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
5.91k
{
155
5.91k
  struct json_tokener *tok;
156
157
5.91k
  if (depth < 1)
158
0
    return NULL;
159
160
5.91k
  tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
161
5.91k
  if (!tok)
162
0
    return NULL;
163
5.91k
  tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
164
5.91k
  if (!tok->stack)
165
0
  {
166
0
    free(tok);
167
0
    return NULL;
168
0
  }
169
5.91k
  tok->pb = printbuf_new();
170
5.91k
  if (!tok->pb)
171
0
  {
172
0
    free(tok->stack);
173
0
    free(tok);
174
0
    return NULL;
175
0
  }
176
5.91k
  tok->max_depth = depth;
177
5.91k
  json_tokener_reset(tok);
178
5.91k
  return tok;
179
5.91k
}
180
181
struct json_tokener *json_tokener_new(void)
182
5.91k
{
183
5.91k
  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
184
5.91k
}
185
186
void json_tokener_free(struct json_tokener *tok)
187
5.91k
{
188
5.91k
  if (!tok)
189
0
    return;
190
5.91k
  json_tokener_reset(tok);
191
5.91k
  if (tok->pb)
192
5.91k
    printbuf_free(tok->pb);
193
5.91k
  free(tok->stack);
194
5.91k
  free(tok);
195
5.91k
}
196
197
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
198
271k
{
199
271k
  tok->stack[depth].state = json_tokener_state_eatws;
200
271k
  tok->stack[depth].saved_state = json_tokener_state_start;
201
271k
  json_object_put(tok->stack[depth].current);
202
271k
  tok->stack[depth].current = NULL;
203
271k
  free(tok->stack[depth].obj_field_name);
204
271k
  tok->stack[depth].obj_field_name = NULL;
205
271k
}
206
207
void json_tokener_reset(struct json_tokener *tok)
208
11.8k
{
209
11.8k
  int i;
210
11.8k
  if (!tok)
211
0
    return;
212
213
24.6k
  for (i = tok->depth; i >= 0; i--)
214
12.8k
    json_tokener_reset_level(tok, i);
215
11.8k
  tok->depth = 0;
216
11.8k
  tok->err = json_tokener_success;
217
11.8k
}
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
3.66M
#define state tok->stack[tok->depth].state
262
1.43M
#define saved_state tok->stack[tok->depth].saved_state
263
531k
#define current tok->stack[tok->depth].current
264
489k
#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
3.48M
  (((tok)->char_offset == len)                                         \
286
3.48M
       ? (((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
3.48M
       : (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) &&                \
291
3.48M
           (!json_tokener_validate_utf8(*str, nBytesp)))               \
292
3.48M
              ? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
293
3.48M
              : (((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
5.97M
#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
294k
  do {                                                  \
308
294k
    if (printbuf_memappend((p), (s), (l)) < 0)    \
309
294k
    {                                             \
310
0
      tok->err = json_tokener_error_memory; \
311
0
      goto out;                             \
312
0
    }                                             \
313
294k
  } 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
5.91k
{
319
5.91k
  struct json_object *obj = NULL;
320
5.91k
  char c = '\1';
321
5.91k
  unsigned int nBytes = 0;
322
5.91k
  unsigned int *nBytesp = &nBytes;
323
324
5.91k
#ifdef HAVE_USELOCALE
325
5.91k
  locale_t oldlocale = uselocale(NULL);
326
5.91k
  locale_t newloc;
327
#elif defined(HAVE_SETLOCALE)
328
  char *oldlocale = NULL;
329
#endif
330
331
5.91k
  tok->char_offset = 0;
332
5.91k
  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
5.91k
  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
5.91k
#ifdef HAVE_USELOCALE
347
5.91k
  {
348
5.91k
#ifdef HAVE_DUPLOCALE
349
5.91k
    locale_t duploc = duplocale(oldlocale);
350
5.91k
    if (duploc == NULL && errno == ENOMEM)
351
0
    {
352
0
      tok->err = json_tokener_error_memory;
353
0
      return NULL;
354
0
    }
355
5.91k
    newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
356
#else
357
    newloc = newlocale(LC_NUMERIC_MASK, "C", oldlocale);
358
#endif
359
5.91k
    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
5.91k
    uselocale(newloc);
375
5.91k
  }
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
751k
  while (PEEK_CHAR(c, tok)) // Note: c might be '\0' !
394
751k
  {
395
396
1.88M
  redo_char:
397
1.88M
    switch (state)
398
1.88M
    {
399
400
731k
    case json_tokener_state_eatws:
401
      /* Advance until we change state */
402
957k
      while (is_ws_char(c))
403
225k
      {
404
225k
        if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
405
0
          goto out;
406
225k
      }
407
731k
      if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
408
1.05k
      {
409
1.05k
        printbuf_reset(tok->pb);
410
1.05k
        printbuf_memappend_checked(tok->pb, &c, 1);
411
1.05k
        state = json_tokener_state_comment_start;
412
1.05k
      }
413
730k
      else
414
730k
      {
415
730k
        state = saved_state;
416
730k
        goto redo_char;
417
730k
      }
418
1.05k
      break;
419
420
132k
    case json_tokener_state_start:
421
132k
      switch (c)
422
132k
      {
423
43.4k
      case '{':
424
43.4k
        state = json_tokener_state_eatws;
425
43.4k
        saved_state = json_tokener_state_object_field_start;
426
43.4k
        current = json_object_new_object();
427
43.4k
        if (current == NULL)
428
0
        {
429
0
          tok->err = json_tokener_error_memory;
430
0
          goto out;
431
0
        }
432
43.4k
        break;
433
43.4k
      case '[':
434
9.33k
        state = json_tokener_state_eatws;
435
9.33k
        saved_state = json_tokener_state_array;
436
9.33k
        current = json_object_new_array();
437
9.33k
        if (current == NULL)
438
0
        {
439
0
          tok->err = json_tokener_error_memory;
440
0
          goto out;
441
0
        }
442
9.33k
        break;
443
9.33k
      case 'I':
444
12
      case 'i':
445
12
        state = json_tokener_state_inf;
446
12
        printbuf_reset(tok->pb);
447
12
        tok->st_pos = 0;
448
12
        goto redo_char;
449
138
      case 'N':
450
388
      case 'n':
451
388
        state = json_tokener_state_null; // or NaN
452
388
        printbuf_reset(tok->pb);
453
388
        tok->st_pos = 0;
454
388
        goto redo_char;
455
85
      case '\'':
456
85
        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
67.6k
      case '"':
464
67.6k
        state = json_tokener_state_string;
465
67.6k
        printbuf_reset(tok->pb);
466
67.6k
        tok->quote_char = c;
467
67.6k
        break;
468
23
      case 'T':
469
66
      case 't':
470
190
      case 'F':
471
315
      case 'f':
472
315
        state = json_tokener_state_boolean;
473
315
        printbuf_reset(tok->pb);
474
315
        tok->st_pos = 0;
475
315
        goto redo_char;
476
2.69k
      case '0':
477
5.33k
      case '1':
478
6.24k
      case '2':
479
6.62k
      case '3':
480
8.14k
      case '4':
481
8.79k
      case '5':
482
8.93k
      case '6':
483
9.07k
      case '7':
484
9.14k
      case '8':
485
9.57k
      case '9':
486
11.6k
      case '-':
487
11.6k
        state = json_tokener_state_number;
488
11.6k
        printbuf_reset(tok->pb);
489
11.6k
        tok->is_double = 0;
490
11.6k
        goto redo_char;
491
87
      default: tok->err = json_tokener_error_parse_unexpected; goto out;
492
132k
      }
493
120k
      break;
494
495
131k
    case json_tokener_state_finish:
496
131k
      if (tok->depth == 0)
497
5.47k
        goto out;
498
126k
      obj = json_object_get(current);
499
126k
      json_tokener_reset_level(tok, tok->depth);
500
126k
      tok->depth--;
501
126k
      goto redo_char;
502
503
14
    case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
504
14
    {
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
14
      int is_negative = 0;
513
514
      /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
515
37
      while (tok->st_pos < (int)json_inf_str_len)
516
37
      {
517
37
        char inf_char = *str;
518
37
        if (inf_char != json_inf_str[tok->st_pos] &&
519
28
            ((tok->flags & JSON_TOKENER_STRICT) ||
520
28
              inf_char != json_inf_str_invert[tok->st_pos])
521
37
           )
522
14
        {
523
14
          tok->err = json_tokener_error_parse_unexpected;
524
14
          goto out;
525
14
        }
526
23
        tok->st_pos++;
527
23
        (void)ADVANCE_CHAR(str, tok);
528
23
        if (!PEEK_CHAR(c, tok))
529
0
        {
530
          /* out of input chars, for now at least */
531
0
          goto out;
532
0
        }
533
23
      }
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
0
      if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
539
0
      {
540
0
        is_negative = 1;
541
0
      }
542
0
      current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
543
0
      if (current == NULL)
544
0
      {
545
0
        tok->err = json_tokener_error_memory;
546
0
        goto out;
547
0
      }
548
0
      saved_state = json_tokener_state_finish;
549
0
      state = json_tokener_state_eatws;
550
0
      goto redo_char;
551
0
    }
552
0
    break;
553
1.74k
    case json_tokener_state_null: /* aka starts with 'n' */
554
1.74k
    {
555
1.74k
      int size;
556
1.74k
      int size_nan;
557
1.74k
      printbuf_memappend_checked(tok->pb, &c, 1);
558
1.74k
      size = json_min(tok->st_pos + 1, json_null_str_len);
559
1.74k
      size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
560
1.74k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
561
1.74k
           strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
562
417
          (strncmp(json_null_str, tok->pb->buf, size) == 0))
563
1.33k
      {
564
1.33k
        if (tok->st_pos == json_null_str_len)
565
234
        {
566
234
          current = NULL;
567
234
          saved_state = json_tokener_state_finish;
568
234
          state = json_tokener_state_eatws;
569
234
          goto redo_char;
570
234
        }
571
1.33k
      }
572
417
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
573
417
                strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
574
24
               (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
575
393
      {
576
393
        if (tok->st_pos == json_nan_str_len)
577
130
        {
578
130
          current = json_object_new_double(NAN);
579
130
          if (current == NULL)
580
0
          {
581
0
            tok->err = json_tokener_error_memory;
582
0
            goto out;
583
0
          }
584
130
          saved_state = json_tokener_state_finish;
585
130
          state = json_tokener_state_eatws;
586
130
          goto redo_char;
587
130
        }
588
393
      }
589
24
      else
590
24
      {
591
24
        tok->err = json_tokener_error_parse_null;
592
24
        goto out;
593
24
      }
594
1.35k
      tok->st_pos++;
595
1.35k
    }
596
0
    break;
597
598
1.05k
    case json_tokener_state_comment_start:
599
1.05k
      if (c == '*')
600
272
      {
601
272
        state = json_tokener_state_comment;
602
272
      }
603
787
      else if (c == '/')
604
773
      {
605
773
        state = json_tokener_state_comment_eol;
606
773
      }
607
14
      else
608
14
      {
609
14
        tok->err = json_tokener_error_parse_comment;
610
14
        goto out;
611
14
      }
612
1.04k
      printbuf_memappend_checked(tok->pb, &c, 1);
613
1.04k
      break;
614
615
1.38k
    case json_tokener_state_comment:
616
1.38k
    {
617
      /* Advance until we change state */
618
1.38k
      const char *case_start = str;
619
23.8k
      while (c != '*')
620
22.4k
      {
621
22.4k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
622
26
        {
623
26
          printbuf_memappend_checked(tok->pb, case_start,
624
26
                                     str - case_start);
625
26
          goto out;
626
26
        }
627
22.4k
      }
628
1.35k
      printbuf_memappend_checked(tok->pb, case_start, 1 + str - case_start);
629
1.35k
      state = json_tokener_state_comment_end;
630
1.35k
    }
631
0
    break;
632
633
773
    case json_tokener_state_comment_eol:
634
773
    {
635
      /* Advance until we change state */
636
773
      const char *case_start = str;
637
56.1k
      while (c != '\n')
638
55.4k
      {
639
55.4k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
640
44
        {
641
44
          printbuf_memappend_checked(tok->pb, case_start,
642
44
                                     str - case_start);
643
44
          goto out;
644
44
        }
645
55.4k
      }
646
729
      printbuf_memappend_checked(tok->pb, case_start, str - case_start);
647
729
      MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
648
729
      state = json_tokener_state_eatws;
649
729
    }
650
0
    break;
651
652
1.35k
    case json_tokener_state_comment_end:
653
1.35k
      printbuf_memappend_checked(tok->pb, &c, 1);
654
1.35k
      if (c == '/')
655
241
      {
656
241
        MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
657
241
        state = json_tokener_state_eatws;
658
241
      }
659
1.11k
      else
660
1.11k
      {
661
1.11k
        state = json_tokener_state_comment;
662
1.11k
      }
663
1.35k
      break;
664
665
114k
    case json_tokener_state_string:
666
114k
    {
667
      /* Advance until we change state */
668
114k
      const char *case_start = str;
669
1.69M
      while (1)
670
1.69M
      {
671
1.69M
        if (c == tok->quote_char)
672
67.5k
        {
673
67.5k
          printbuf_memappend_checked(tok->pb, case_start,
674
67.5k
                                     str - case_start);
675
67.5k
          current =
676
67.5k
              json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
677
67.5k
          if (current == NULL)
678
0
          {
679
0
            tok->err = json_tokener_error_memory;
680
0
            goto out;
681
0
          }
682
67.5k
          saved_state = json_tokener_state_finish;
683
67.5k
          state = json_tokener_state_eatws;
684
67.5k
          break;
685
67.5k
        }
686
1.63M
        else if (c == '\\')
687
46.3k
        {
688
46.3k
          printbuf_memappend_checked(tok->pb, case_start,
689
46.3k
                                     str - case_start);
690
46.3k
          saved_state = json_tokener_state_string;
691
46.3k
          state = json_tokener_state_string_escape;
692
46.3k
          break;
693
46.3k
        }
694
1.58M
        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.58M
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
701
40
        {
702
40
          printbuf_memappend_checked(tok->pb, case_start,
703
40
                                     str - case_start);
704
40
          goto out;
705
40
        }
706
1.58M
      }
707
114k
    }
708
113k
    break;
709
710
113k
    case json_tokener_state_string_escape:
711
53.9k
      switch (c)
712
53.9k
      {
713
10.4k
      case '"':
714
31.7k
      case '\\':
715
31.9k
      case '/':
716
31.9k
        printbuf_memappend_checked(tok->pb, &c, 1);
717
31.9k
        state = saved_state;
718
31.9k
        break;
719
763
      case 'b':
720
18.3k
      case 'n':
721
18.6k
      case 'r':
722
19.3k
      case 't':
723
19.5k
      case 'f':
724
19.5k
        if (c == 'b')
725
763
          printbuf_memappend_checked(tok->pb, "\b", 1);
726
18.7k
        else if (c == 'n')
727
17.6k
          printbuf_memappend_checked(tok->pb, "\n", 1);
728
1.17k
        else if (c == 'r')
729
279
          printbuf_memappend_checked(tok->pb, "\r", 1);
730
897
        else if (c == 't')
731
663
          printbuf_memappend_checked(tok->pb, "\t", 1);
732
234
        else if (c == 'f')
733
234
          printbuf_memappend_checked(tok->pb, "\f", 1);
734
19.5k
        state = saved_state;
735
19.5k
        break;
736
2.40k
      case 'u':
737
2.40k
        tok->ucs_char = 0;
738
2.40k
        tok->st_pos = 0;
739
2.40k
        state = json_tokener_state_escape_unicode;
740
2.40k
        break;
741
13
      default: tok->err = json_tokener_error_parse_string; goto out;
742
53.9k
      }
743
53.8k
      break;
744
745
      // ===================================================
746
747
53.8k
    case json_tokener_state_escape_unicode:
748
2.84k
    {
749
      /* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */
750
11.3k
      while (1)
751
11.3k
      {
752
11.3k
        if (!c || !is_hex_char(c))
753
12
        {
754
12
          tok->err = json_tokener_error_parse_string;
755
12
          goto out;
756
12
        }
757
11.3k
        tok->ucs_char |=
758
11.3k
            ((unsigned int)jt_hexdigit(c) << ((3 - tok->st_pos) * 4));
759
11.3k
        tok->st_pos++;
760
11.3k
        if (tok->st_pos >= 4)
761
2.83k
          break;
762
763
8.51k
        (void)ADVANCE_CHAR(str, tok);
764
8.51k
        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
8.51k
      }
775
2.83k
      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
2.83k
      if (tok->high_surrogate)
781
436
      {
782
436
        if (IS_LOW_SURROGATE(tok->ucs_char))
783
296
        {
784
          /* Recalculate the ucs_char, then fall thru to process normally */
785
296
          tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate,
786
296
                                                tok->ucs_char);
787
296
        }
788
140
        else
789
140
        {
790
          /* High surrogate was not followed by a low surrogate
791
           * Replace the high and process the rest normally
792
           */
793
140
          printbuf_memappend_checked(tok->pb,
794
140
                                     (char *)utf8_replacement_char, 3);
795
140
        }
796
436
        tok->high_surrogate = 0;
797
436
      }
798
799
2.83k
      if (tok->ucs_char < 0x80)
800
871
      {
801
871
        unsigned char unescaped_utf[1];
802
871
        unescaped_utf[0] = tok->ucs_char;
803
871
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 1);
804
871
      }
805
1.95k
      else if (tok->ucs_char < 0x800)
806
48
      {
807
48
        unsigned char unescaped_utf[2];
808
48
        unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
809
48
        unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
810
48
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 2);
811
48
      }
812
1.91k
      else if (IS_HIGH_SURROGATE(tok->ucs_char))
813
703
      {
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
703
        tok->high_surrogate = tok->ucs_char;
829
703
        tok->ucs_char = 0;
830
703
        state = json_tokener_state_escape_unicode_need_escape;
831
703
        break;
832
703
      }
833
1.20k
      else if (IS_LOW_SURROGATE(tok->ucs_char))
834
418
      {
835
        /* Got a low surrogate not preceded by a high */
836
418
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
837
418
      }
838
790
      else if (tok->ucs_char < 0x10000)
839
494
      {
840
494
        unsigned char unescaped_utf[3];
841
494
        unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
842
494
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
843
494
        unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
844
494
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 3);
845
494
      }
846
296
      else if (tok->ucs_char < 0x110000)
847
296
      {
848
296
        unsigned char unescaped_utf[4];
849
296
        unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
850
296
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
851
296
        unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
852
296
        unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
853
296
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 4);
854
296
      }
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
2.12k
      state = saved_state; // i.e. _state_string or _state_object_field
861
2.12k
    }
862
0
    break;
863
864
703
    case json_tokener_state_escape_unicode_need_escape:
865
      // We get here after processing a high_surrogate
866
      // require a '\\' char
867
703
      if (!c || c != '\\')
868
166
      {
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
166
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
874
166
        tok->high_surrogate = 0;
875
166
        tok->ucs_char = 0;
876
166
        tok->st_pos = 0;
877
166
        state = saved_state;
878
166
        goto redo_char;
879
166
      }
880
537
      state = json_tokener_state_escape_unicode_need_u;
881
537
      break;
882
883
537
    case json_tokener_state_escape_unicode_need_u:
884
      /* We already had a \ char, check that it's \u */
885
537
      if (!c || c != 'u')
886
99
      {
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
99
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
893
99
        tok->high_surrogate = 0;
894
99
        tok->ucs_char = 0;
895
99
        tok->st_pos = 0;
896
99
        state = json_tokener_state_string_escape;
897
99
        goto redo_char;
898
99
      }
899
438
      state = json_tokener_state_escape_unicode;
900
438
      break;
901
902
      // ===================================================
903
904
1.76k
    case json_tokener_state_boolean:
905
1.76k
    {
906
1.76k
      int size1, size2;
907
1.76k
      printbuf_memappend_checked(tok->pb, &c, 1);
908
1.76k
      size1 = json_min(tok->st_pos + 1, json_true_str_len);
909
1.76k
      size2 = json_min(tok->st_pos + 1, json_false_str_len);
910
1.76k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
911
1.76k
           strncasecmp(json_true_str, tok->pb->buf, size1) == 0) ||
912
1.48k
          (strncmp(json_true_str, tok->pb->buf, size1) == 0))
913
278
      {
914
278
        if (tok->st_pos == json_true_str_len)
915
52
        {
916
52
          current = json_object_new_boolean(1);
917
52
          if (current == NULL)
918
0
          {
919
0
            tok->err = json_tokener_error_memory;
920
0
            goto out;
921
0
          }
922
52
          saved_state = json_tokener_state_finish;
923
52
          state = json_tokener_state_eatws;
924
52
          goto redo_char;
925
52
        }
926
278
      }
927
1.48k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
928
1.48k
                strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
929
23
               (strncmp(json_false_str, tok->pb->buf, size2) == 0))
930
1.45k
      {
931
1.45k
        if (tok->st_pos == json_false_str_len)
932
240
        {
933
240
          current = json_object_new_boolean(0);
934
240
          if (current == NULL)
935
0
          {
936
0
            tok->err = json_tokener_error_memory;
937
0
            goto out;
938
0
          }
939
240
          saved_state = json_tokener_state_finish;
940
240
          state = json_tokener_state_eatws;
941
240
          goto redo_char;
942
240
        }
943
1.45k
      }
944
23
      else
945
23
      {
946
23
        tok->err = json_tokener_error_parse_boolean;
947
23
        goto out;
948
23
      }
949
1.44k
      tok->st_pos++;
950
1.44k
    }
951
0
    break;
952
953
11.6k
    case json_tokener_state_number:
954
11.6k
    {
955
      /* Advance until we change state */
956
11.6k
      const char *case_start = str;
957
11.6k
      int case_len = 0;
958
11.6k
      int is_exponent = 0;
959
11.6k
      int neg_sign_ok = 1;
960
11.6k
      int pos_sign_ok = 0;
961
11.6k
      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
83.7k
      while (c && ((c >= '0' && c <= '9') ||
986
15.0k
                   (!is_exponent && (c == 'e' || c == 'E')) ||
987
14.5k
                   (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') ||
988
12.0k
                   (!tok->is_double && c == '.')))
989
72.0k
      {
990
72.0k
        pos_sign_ok = neg_sign_ok = 0;
991
72.0k
        ++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
72.0k
        switch (c)
1000
72.0k
        {
1001
490
        case '.':
1002
490
          tok->is_double = 1;
1003
490
          pos_sign_ok = 1;
1004
490
          neg_sign_ok = 1;
1005
490
          break;
1006
449
        case 'e': /* FALLTHRU */
1007
481
        case 'E':
1008
481
          is_exponent = 1;
1009
481
          tok->is_double = 1;
1010
          /* the exponent part can begin with a negative sign */
1011
481
          pos_sign_ok = neg_sign_ok = 1;
1012
481
          break;
1013
71.1k
        default: break;
1014
72.0k
        }
1015
1016
72.0k
        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
72.0k
      }
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
11.6k
      if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
1031
926
          c != 'I' && c != 'i' && !is_ws_char(c))
1032
39
      {
1033
39
        tok->err = json_tokener_error_parse_number;
1034
39
        goto out;
1035
39
      }
1036
11.5k
      if (case_len > 0)
1037
11.5k
        printbuf_memappend_checked(tok->pb, case_start, case_len);
1038
1039
      // Check for -Infinity
1040
11.5k
      if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
1041
2
      {
1042
2
        state = json_tokener_state_inf;
1043
2
        tok->st_pos = 0;
1044
2
        goto redo_char;
1045
2
      }
1046
11.5k
      if (tok->flags & JSON_TOKENER_STRICT)
1047
0
      {
1048
        /* RFC 8259 forbids leading zeros in the integer part:
1049
         * a '0' may only be followed by '.', 'e'/'E' or the end
1050
         * of the number, so "01", "00" and "-0123" are invalid
1051
         * while "0", "-0" and "0.5" remain valid.
1052
         */
1053
0
        const char *num = tok->pb->buf;
1054
0
        if (*num == '-')
1055
0
          num++;
1056
0
        if (num[0] == '0' && num[1] >= '0' && num[1] <= '9')
1057
0
        {
1058
0
          tok->err = json_tokener_error_parse_number;
1059
0
          goto out;
1060
0
        }
1061
0
      }
1062
11.5k
      if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
1063
564
      {
1064
        /* Trim some chars off the end, to allow things
1065
           like "123e+" to parse ok. */
1066
1.16k
        while (printbuf_length(tok->pb) > 1)
1067
1.14k
        {
1068
1.14k
          char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1];
1069
1.14k
          if (last_char != 'e' && last_char != 'E' &&
1070
817
              last_char != '-' && last_char != '+')
1071
541
          {
1072
541
            break;
1073
541
          }
1074
600
          tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0';
1075
600
          printbuf_length(tok->pb)--;
1076
600
        }
1077
564
      }
1078
11.5k
    }
1079
0
      {
1080
11.5k
        int64_t num64;
1081
11.5k
        uint64_t numuint64;
1082
11.5k
        double numd;
1083
11.5k
        if (!tok->is_double && tok->pb->buf[0] == '-' &&
1084
1.58k
            json_parse_int64(tok->pb->buf, &num64) == 0)
1085
1.58k
        {
1086
1.58k
          if (errno == ERANGE && (tok->flags & JSON_TOKENER_STRICT))
1087
0
          {
1088
0
            tok->err = json_tokener_error_parse_number;
1089
0
            goto out;
1090
0
          }
1091
1.58k
          current = json_object_new_int64(num64);
1092
1.58k
          if (current == NULL)
1093
0
          {
1094
0
            tok->err = json_tokener_error_memory;
1095
0
            goto out;
1096
0
          }
1097
1.58k
        }
1098
10.0k
        else if (!tok->is_double && tok->pb->buf[0] != '-' &&
1099
9.44k
                 json_parse_uint64(tok->pb->buf, &numuint64) == 0)
1100
9.44k
        {
1101
9.44k
          if (errno == ERANGE && (tok->flags & JSON_TOKENER_STRICT))
1102
0
          {
1103
0
            tok->err = json_tokener_error_parse_number;
1104
0
            goto out;
1105
0
          }
1106
9.44k
          if (numuint64 <= INT64_MAX)
1107
8.95k
          {
1108
8.95k
            num64 = (uint64_t)numuint64;
1109
8.95k
            current = json_object_new_int64(num64);
1110
8.95k
            if (current == NULL)
1111
0
            {
1112
0
              tok->err = json_tokener_error_memory;
1113
0
              goto out;
1114
0
            }
1115
8.95k
          }
1116
488
          else
1117
488
          {
1118
488
            current = json_object_new_uint64(numuint64);
1119
488
            if (current == NULL)
1120
0
            {
1121
0
              tok->err = json_tokener_error_memory;
1122
0
              goto out;
1123
0
            }
1124
488
          }
1125
9.44k
        }
1126
567
        else if (tok->is_double &&
1127
564
                 json_tokener_parse_double(
1128
564
                     tok->pb->buf, printbuf_length(tok->pb), &numd) == 0)
1129
563
        {
1130
563
          current = json_object_new_double_s(numd, tok->pb->buf);
1131
563
          if (current == NULL)
1132
0
          {
1133
0
            tok->err = json_tokener_error_memory;
1134
0
            goto out;
1135
0
          }
1136
563
        }
1137
4
        else
1138
4
        {
1139
4
          tok->err = json_tokener_error_parse_number;
1140
4
          goto out;
1141
4
        }
1142
11.5k
        saved_state = json_tokener_state_finish;
1143
11.5k
        state = json_tokener_state_eatws;
1144
11.5k
        goto redo_char;
1145
11.5k
      }
1146
0
      break;
1147
1148
19.7k
    case json_tokener_state_array_after_sep:
1149
29.1k
    case json_tokener_state_array:
1150
29.1k
      if (c == ']')
1151
391
      {
1152
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1153
391
        json_object_array_shrink(current, 0);
1154
1155
391
        if (state == json_tokener_state_array_after_sep &&
1156
21
            (tok->flags & JSON_TOKENER_STRICT))
1157
0
        {
1158
0
          tok->err = json_tokener_error_parse_unexpected;
1159
0
          goto out;
1160
0
        }
1161
391
        saved_state = json_tokener_state_finish;
1162
391
        state = json_tokener_state_eatws;
1163
391
      }
1164
28.7k
      else
1165
28.7k
      {
1166
28.7k
        if (tok->depth >= tok->max_depth - 1)
1167
1
        {
1168
1
          tok->err = json_tokener_error_depth;
1169
1
          goto out;
1170
1
        }
1171
28.7k
        state = json_tokener_state_array_add;
1172
28.7k
        tok->depth++;
1173
28.7k
        json_tokener_reset_level(tok, tok->depth);
1174
28.7k
        goto redo_char;
1175
28.7k
      }
1176
391
      break;
1177
1178
28.3k
    case json_tokener_state_array_add:
1179
28.3k
      if (json_object_array_add(current, obj) != 0)
1180
0
      {
1181
0
        tok->err = json_tokener_error_memory;
1182
0
        goto out;
1183
0
      }
1184
28.3k
      saved_state = json_tokener_state_array_sep;
1185
28.3k
      state = json_tokener_state_eatws;
1186
28.3k
      goto redo_char;
1187
1188
28.3k
    case json_tokener_state_array_sep:
1189
28.3k
      if (c == ']')
1190
8.52k
      {
1191
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1192
8.52k
        json_object_array_shrink(current, 0);
1193
1194
8.52k
        saved_state = json_tokener_state_finish;
1195
8.52k
        state = json_tokener_state_eatws;
1196
8.52k
      }
1197
19.7k
      else if (c == ',')
1198
19.7k
      {
1199
19.7k
        saved_state = json_tokener_state_array_after_sep;
1200
19.7k
        state = json_tokener_state_eatws;
1201
19.7k
      }
1202
20
      else
1203
20
      {
1204
20
        tok->err = json_tokener_error_parse_array;
1205
20
        goto out;
1206
20
      }
1207
28.3k
      break;
1208
1209
43.4k
    case json_tokener_state_object_field_start:
1210
114k
    case json_tokener_state_object_field_start_after_sep:
1211
114k
      if (c == '}')
1212
16.5k
      {
1213
16.5k
        if (state == json_tokener_state_object_field_start_after_sep &&
1214
4
            (tok->flags & JSON_TOKENER_STRICT))
1215
0
        {
1216
0
          tok->err = json_tokener_error_parse_unexpected;
1217
0
          goto out;
1218
0
        }
1219
16.5k
        saved_state = json_tokener_state_finish;
1220
16.5k
        state = json_tokener_state_eatws;
1221
16.5k
      }
1222
98.3k
      else if (c == '"' || c == '\'')
1223
98.3k
      {
1224
98.3k
        tok->quote_char = c;
1225
98.3k
        printbuf_reset(tok->pb);
1226
98.3k
        state = json_tokener_state_object_field;
1227
98.3k
      }
1228
21
      else
1229
21
      {
1230
21
        tok->err = json_tokener_error_parse_object_key_name;
1231
21
        goto out;
1232
21
      }
1233
114k
      break;
1234
1235
114k
    case json_tokener_state_object_field:
1236
105k
    {
1237
      /* Advance until we change state */
1238
105k
      const char *case_start = str;
1239
866k
      while (1)
1240
866k
      {
1241
866k
        if (c == tok->quote_char)
1242
98.2k
        {
1243
98.2k
          printbuf_memappend_checked(tok->pb, case_start,
1244
98.2k
                                     str - case_start);
1245
98.2k
          obj_field_name = strdup(tok->pb->buf);
1246
98.2k
          if (obj_field_name == NULL)
1247
0
          {
1248
0
            tok->err = json_tokener_error_memory;
1249
0
            goto out;
1250
0
          }
1251
98.2k
          saved_state = json_tokener_state_object_field_end;
1252
98.2k
          state = json_tokener_state_eatws;
1253
98.2k
          break;
1254
98.2k
        }
1255
768k
        else if (c == '\\')
1256
7.41k
        {
1257
7.41k
          printbuf_memappend_checked(tok->pb, case_start,
1258
7.41k
                                     str - case_start);
1259
7.41k
          saved_state = json_tokener_state_object_field;
1260
7.41k
          state = json_tokener_state_string_escape;
1261
7.41k
          break;
1262
7.41k
        }
1263
760k
        else if ((tok->flags & JSON_TOKENER_STRICT) && (unsigned char)c <= 0x1f)
1264
0
        {
1265
          // Disallow control characters in strict mode
1266
0
          tok->err = json_tokener_error_parse_string;
1267
0
          goto out;
1268
0
        }
1269
760k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
1270
18
        {
1271
18
          printbuf_memappend_checked(tok->pb, case_start,
1272
18
                                     str - case_start);
1273
18
          goto out;
1274
18
        }
1275
760k
      }
1276
105k
    }
1277
105k
    break;
1278
1279
105k
    case json_tokener_state_object_field_end:
1280
98.2k
      if (c == ':')
1281
98.2k
      {
1282
98.2k
        saved_state = json_tokener_state_object_value;
1283
98.2k
        state = json_tokener_state_eatws;
1284
98.2k
      }
1285
19
      else
1286
19
      {
1287
19
        tok->err = json_tokener_error_parse_object_key_sep;
1288
19
        goto out;
1289
19
      }
1290
98.2k
      break;
1291
1292
98.2k
    case json_tokener_state_object_value:
1293
98.2k
      if (tok->depth >= tok->max_depth - 1)
1294
0
      {
1295
0
        tok->err = json_tokener_error_depth;
1296
0
        goto out;
1297
0
      }
1298
98.2k
      state = json_tokener_state_object_value_add;
1299
98.2k
      tok->depth++;
1300
98.2k
      json_tokener_reset_level(tok, tok->depth);
1301
98.2k
      goto redo_char;
1302
1303
97.7k
    case json_tokener_state_object_value_add:
1304
97.7k
      if (json_object_object_add(current, obj_field_name, obj) != 0)
1305
0
      {
1306
0
        tok->err = json_tokener_error_memory;
1307
0
        goto out;
1308
0
      }
1309
97.7k
      free(obj_field_name);
1310
97.7k
      obj_field_name = NULL;
1311
97.7k
      saved_state = json_tokener_state_object_sep;
1312
97.7k
      state = json_tokener_state_eatws;
1313
97.7k
      goto redo_char;
1314
1315
97.7k
    case json_tokener_state_object_sep:
1316
      /* { */
1317
97.7k
      if (c == '}')
1318
26.2k
      {
1319
26.2k
        saved_state = json_tokener_state_finish;
1320
26.2k
        state = json_tokener_state_eatws;
1321
26.2k
      }
1322
71.4k
      else if (c == ',')
1323
71.4k
      {
1324
71.4k
        saved_state = json_tokener_state_object_field_start_after_sep;
1325
71.4k
        state = json_tokener_state_eatws;
1326
71.4k
      }
1327
16
      else
1328
16
      {
1329
16
        tok->err = json_tokener_error_parse_object_value_sep;
1330
16
        goto out;
1331
16
      }
1332
97.6k
      break;
1333
1.88M
    }
1334
745k
    (void)ADVANCE_CHAR(str, tok);
1335
745k
    if (!c) // This is the char *before* advancing
1336
5
      break;
1337
745k
  } /* while(PEEK_CHAR) */
1338
1339
5.91k
out:
1340
5.91k
  if ((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && (nBytes != 0))
1341
0
  {
1342
0
    tok->err = json_tokener_error_parse_utf8_string;
1343
0
  }
1344
5.91k
  if (c && (state == json_tokener_state_finish) && (tok->depth == 0) &&
1345
55
      (tok->flags & (JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS)) ==
1346
55
          JSON_TOKENER_STRICT)
1347
0
  {
1348
    /* unexpected char after JSON data */
1349
0
    tok->err = json_tokener_error_parse_unexpected;
1350
0
  }
1351
5.91k
  if (!c)
1352
5.65k
  {
1353
    /* We hit an eof char (0) */
1354
5.65k
    if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
1355
190
      tok->err = json_tokener_error_parse_eof;
1356
5.65k
  }
1357
1358
5.91k
#ifdef HAVE_USELOCALE
1359
5.91k
  uselocale(oldlocale);
1360
5.91k
  freelocale(newloc);
1361
#elif defined(HAVE_SETLOCALE)
1362
  setlocale(LC_NUMERIC, oldlocale);
1363
  free(oldlocale);
1364
#endif
1365
1366
5.91k
  if (tok->err == json_tokener_success)
1367
5.51k
  {
1368
5.51k
    json_object *ret = json_object_get(current);
1369
5.51k
    int ii;
1370
1371
    /* Partially reset, so we parse additional objects on subsequent calls. */
1372
11.0k
    for (ii = tok->depth; ii >= 0; ii--)
1373
5.56k
      json_tokener_reset_level(tok, ii);
1374
5.51k
    return ret;
1375
5.51k
  }
1376
1377
402
  MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
1378
402
           tok->char_offset);
1379
402
  return NULL;
1380
5.91k
}
1381
1382
static json_bool json_tokener_validate_utf8(const char c, unsigned int *nBytes)
1383
0
{
1384
0
  unsigned char chr = c;
1385
0
  if (*nBytes == 0)
1386
0
  {
1387
0
    if (chr >= 0x80)
1388
0
    {
1389
0
      if ((chr & 0xe0) == 0xc0)
1390
0
        *nBytes = 1;
1391
0
      else if ((chr & 0xf0) == 0xe0)
1392
0
        *nBytes = 2;
1393
0
      else if ((chr & 0xf8) == 0xf0)
1394
0
        *nBytes = 3;
1395
0
      else
1396
0
        return 0;
1397
0
    }
1398
0
  }
1399
0
  else
1400
0
  {
1401
0
    if ((chr & 0xC0) != 0x80)
1402
0
      return 0;
1403
0
    (*nBytes)--;
1404
0
  }
1405
0
  return 1;
1406
0
}
1407
1408
void json_tokener_set_flags(struct json_tokener *tok, int flags)
1409
0
{
1410
0
  tok->flags = flags;
1411
0
}
1412
1413
size_t json_tokener_get_parse_end(struct json_tokener *tok)
1414
0
{
1415
0
  assert(tok->char_offset >= 0); /* Drop this line when char_offset becomes a size_t */
1416
0
  return (size_t)tok->char_offset;
1417
0
}
1418
1419
static int json_tokener_parse_double(const char *buf, int len, double *retval)
1420
564
{
1421
564
  char *end;
1422
564
  *retval = strtod(buf, &end);
1423
564
  if (buf + len == end)
1424
563
    return 0; // It worked
1425
1
  return 1;
1426
564
}