Coverage Report

Created: 2026-02-11 06:19

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
34.5k
#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.42M
      || c == '\t'
73
1.40M
      || c == '\n'
74
1.40M
      || c == '\r';
75
1.58M
}
76
77
static inline int is_hex_char(char c)
78
34.6k
{
79
34.6k
  return (c >= '0' && c <= '9')
80
8.81k
      || (c >= 'A' && c <= 'F')
81
1.72k
      || (c >= 'a' && c <= 'f');
82
34.6k
}
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
1.88k
{
134
1.88k
  int jerr_int = (int)jerr;
135
1.88k
  if (jerr_int < 0 ||
136
1.88k
      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
1.88k
  return json_tokener_errors[jerr];
140
1.88k
}
141
142
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok)
143
3.76k
{
144
3.76k
  return tok->err;
145
3.76k
}
146
147
/* Stuff for decoding unicode sequences */
148
4.40k
#define IS_HIGH_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xD800)
149
3.38k
#define IS_LOW_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xDC00)
150
512
#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
9.08k
{
155
9.08k
  struct json_tokener *tok;
156
157
9.08k
  if (depth < 1)
158
0
    return NULL;
159
160
9.08k
  tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
161
9.08k
  if (!tok)
162
0
    return NULL;
163
9.08k
  tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
164
9.08k
  if (!tok->stack)
165
0
  {
166
0
    free(tok);
167
0
    return NULL;
168
0
  }
169
9.08k
  tok->pb = printbuf_new();
170
9.08k
  if (!tok->pb)
171
0
  {
172
0
    free(tok->stack);
173
0
    free(tok);
174
0
    return NULL;
175
0
  }
176
9.08k
  tok->max_depth = depth;
177
9.08k
  json_tokener_reset(tok);
178
9.08k
  return tok;
179
9.08k
}
180
181
struct json_tokener *json_tokener_new(void)
182
9.08k
{
183
9.08k
  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
184
9.08k
}
185
186
void json_tokener_free(struct json_tokener *tok)
187
9.08k
{
188
9.08k
  if (!tok)
189
0
    return;
190
9.08k
  json_tokener_reset(tok);
191
9.08k
  if (tok->pb)
192
9.08k
    printbuf_free(tok->pb);
193
9.08k
  free(tok->stack);
194
9.08k
  free(tok);
195
9.08k
}
196
197
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
198
588k
{
199
588k
  tok->stack[depth].state = json_tokener_state_eatws;
200
588k
  tok->stack[depth].saved_state = json_tokener_state_start;
201
588k
  json_object_put(tok->stack[depth].current);
202
588k
  tok->stack[depth].current = NULL;
203
588k
  free(tok->stack[depth].obj_field_name);
204
588k
  tok->stack[depth].obj_field_name = NULL;
205
588k
}
206
207
void json_tokener_reset(struct json_tokener *tok)
208
18.1k
{
209
18.1k
  int i;
210
18.1k
  if (!tok)
211
0
    return;
212
213
40.0k
  for (i = tok->depth; i >= 0; i--)
214
21.8k
    json_tokener_reset_level(tok, i);
215
18.1k
  tok->depth = 0;
216
18.1k
  tok->err = json_tokener_success;
217
18.1k
}
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.93M
#define state tok->stack[tok->depth].state
262
2.61M
#define saved_state tok->stack[tok->depth].saved_state
263
1.13M
#define current tok->stack[tok->depth].current
264
605k
#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.62M
  (((tok)->char_offset == len)                                         \
286
5.62M
       ? (((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.62M
       : (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) &&                \
291
5.62M
           (!json_tokener_validate_utf8(*str, nBytesp)))               \
292
5.62M
              ? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
293
5.62M
              : (((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
9.95M
#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
545k
  do {                                                  \
308
545k
    if (printbuf_memappend((p), (s), (l)) < 0)    \
309
545k
    {                                             \
310
0
      tok->err = json_tokener_error_memory; \
311
0
      goto out;                             \
312
0
    }                                             \
313
545k
  } 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
9.08k
{
319
9.08k
  struct json_object *obj = NULL;
320
9.08k
  char c = '\1';
321
9.08k
  unsigned int nBytes = 0;
322
9.08k
  unsigned int *nBytesp = &nBytes;
323
324
9.08k
#ifdef HAVE_USELOCALE
325
9.08k
  locale_t oldlocale = uselocale(NULL);
326
9.08k
  locale_t newloc;
327
#elif defined(HAVE_SETLOCALE)
328
  char *oldlocale = NULL;
329
#endif
330
331
9.08k
  tok->char_offset = 0;
332
9.08k
  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
9.08k
  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
9.08k
#ifdef HAVE_USELOCALE
347
9.08k
  {
348
9.08k
#ifdef HAVE_DUPLOCALE
349
9.08k
    locale_t duploc = duplocale(oldlocale);
350
9.08k
    if (duploc == NULL && errno == ENOMEM)
351
0
    {
352
0
      tok->err = json_tokener_error_memory;
353
0
      return NULL;
354
0
    }
355
9.08k
    newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
356
#else
357
    newloc = newlocale(LC_NUMERIC_MASK, "C", oldlocale);
358
#endif
359
9.08k
    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
9.08k
    uselocale(newloc);
375
9.08k
  }
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.08M
  while (PEEK_CHAR(c, tok)) // Note: c might be '\0' !
394
1.08M
  {
395
396
3.63M
  redo_char:
397
3.63M
    switch (state)
398
3.63M
    {
399
400
1.40M
    case json_tokener_state_eatws:
401
      /* Advance until we change state */
402
1.58M
      while (is_ws_char(c))
403
177k
      {
404
177k
        if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
405
0
          goto out;
406
177k
      }
407
1.40M
      if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
408
2.31k
      {
409
2.31k
        printbuf_reset(tok->pb);
410
2.31k
        printbuf_memappend_checked(tok->pb, &c, 1);
411
2.31k
        state = json_tokener_state_comment_start;
412
2.31k
      }
413
1.40M
      else
414
1.40M
      {
415
1.40M
        state = saved_state;
416
1.40M
        goto redo_char;
417
1.40M
      }
418
2.31k
      break;
419
420
290k
    case json_tokener_state_start:
421
290k
      switch (c)
422
290k
      {
423
51.8k
      case '{':
424
51.8k
        state = json_tokener_state_eatws;
425
51.8k
        saved_state = json_tokener_state_object_field_start;
426
51.8k
        current = json_object_new_object();
427
51.8k
        if (current == NULL)
428
0
        {
429
0
          tok->err = json_tokener_error_memory;
430
0
          goto out;
431
0
        }
432
51.8k
        break;
433
51.8k
      case '[':
434
13.9k
        state = json_tokener_state_eatws;
435
13.9k
        saved_state = json_tokener_state_array;
436
13.9k
        current = json_object_new_array();
437
13.9k
        if (current == NULL)
438
0
        {
439
0
          tok->err = json_tokener_error_memory;
440
0
          goto out;
441
0
        }
442
13.9k
        break;
443
13.9k
      case 'I':
444
673
      case 'i':
445
673
        state = json_tokener_state_inf;
446
673
        printbuf_reset(tok->pb);
447
673
        tok->st_pos = 0;
448
673
        goto redo_char;
449
1.13k
      case 'N':
450
18.1k
      case 'n':
451
18.1k
        state = json_tokener_state_null; // or NaN
452
18.1k
        printbuf_reset(tok->pb);
453
18.1k
        tok->st_pos = 0;
454
18.1k
        goto redo_char;
455
519
      case '\'':
456
519
        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.9k
      case '"':
464
67.9k
        state = json_tokener_state_string;
465
67.9k
        printbuf_reset(tok->pb);
466
67.9k
        tok->quote_char = c;
467
67.9k
        break;
468
601
      case 'T':
469
1.23k
      case 't':
470
1.36k
      case 'F':
471
1.85k
      case 'f':
472
1.85k
        state = json_tokener_state_boolean;
473
1.85k
        printbuf_reset(tok->pb);
474
1.85k
        tok->st_pos = 0;
475
1.85k
        goto redo_char;
476
20.7k
      case '0':
477
27.3k
      case '1':
478
32.5k
      case '2':
479
34.4k
      case '3':
480
37.2k
      case '4':
481
129k
      case '5':
482
129k
      case '6':
483
130k
      case '7':
484
131k
      case '8':
485
132k
      case '9':
486
136k
      case '-':
487
136k
        state = json_tokener_state_number;
488
136k
        printbuf_reset(tok->pb);
489
136k
        tok->is_double = 0;
490
136k
        goto redo_char;
491
125
      default: tok->err = json_tokener_error_parse_unexpected; goto out;
492
290k
      }
493
133k
      break;
494
495
284k
    case json_tokener_state_finish:
496
284k
      if (tok->depth == 0)
497
7.11k
        goto out;
498
277k
      obj = json_object_get(current);
499
277k
      json_tokener_reset_level(tok, tok->depth);
500
277k
      tok->depth--;
501
277k
      goto redo_char;
502
503
1.14k
    case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
504
1.14k
    {
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
1.14k
      int is_negative = 0;
513
514
      /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
515
9.83k
      while (tok->st_pos < (int)json_inf_str_len)
516
8.77k
      {
517
8.77k
        char inf_char = *str;
518
8.77k
        if (inf_char != json_inf_str[tok->st_pos] &&
519
3.77k
            ((tok->flags & JSON_TOKENER_STRICT) ||
520
3.77k
              inf_char != json_inf_str_invert[tok->st_pos])
521
8.77k
           )
522
77
        {
523
77
          tok->err = json_tokener_error_parse_unexpected;
524
77
          goto out;
525
77
        }
526
8.69k
        tok->st_pos++;
527
8.69k
        (void)ADVANCE_CHAR(str, tok);
528
8.69k
        if (!PEEK_CHAR(c, tok))
529
0
        {
530
          /* out of input chars, for now at least */
531
0
          goto out;
532
0
        }
533
8.69k
      }
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
1.06k
      if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
539
445
      {
540
445
        is_negative = 1;
541
445
      }
542
1.06k
      current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
543
1.06k
      if (current == NULL)
544
0
      {
545
0
        tok->err = json_tokener_error_memory;
546
0
        goto out;
547
0
      }
548
1.06k
      saved_state = json_tokener_state_finish;
549
1.06k
      state = json_tokener_state_eatws;
550
1.06k
      goto redo_char;
551
1.06k
    }
552
0
    break;
553
90.0k
    case json_tokener_state_null: /* aka starts with 'n' */
554
90.0k
    {
555
90.0k
      int size;
556
90.0k
      int size_nan;
557
90.0k
      printbuf_memappend_checked(tok->pb, &c, 1);
558
90.0k
      size = json_min(tok->st_pos + 1, json_null_str_len);
559
90.0k
      size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
560
90.0k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
561
90.0k
           strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
562
1.46k
          (strncmp(json_null_str, tok->pb->buf, size) == 0))
563
88.5k
      {
564
88.5k
        if (tok->st_pos == json_null_str_len)
565
17.5k
        {
566
17.5k
          current = NULL;
567
17.5k
          saved_state = json_tokener_state_finish;
568
17.5k
          state = json_tokener_state_eatws;
569
17.5k
          goto redo_char;
570
17.5k
        }
571
88.5k
      }
572
1.46k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
573
1.46k
                strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
574
83
               (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
575
1.38k
      {
576
1.38k
        if (tok->st_pos == json_nan_str_len)
577
454
        {
578
454
          current = json_object_new_double(NAN);
579
454
          if (current == NULL)
580
0
          {
581
0
            tok->err = json_tokener_error_memory;
582
0
            goto out;
583
0
          }
584
454
          saved_state = json_tokener_state_finish;
585
454
          state = json_tokener_state_eatws;
586
454
          goto redo_char;
587
454
        }
588
1.38k
      }
589
83
      else
590
83
      {
591
83
        tok->err = json_tokener_error_parse_null;
592
83
        goto out;
593
83
      }
594
71.8k
      tok->st_pos++;
595
71.8k
    }
596
0
    break;
597
598
2.31k
    case json_tokener_state_comment_start:
599
2.31k
      if (c == '*')
600
625
      {
601
625
        state = json_tokener_state_comment;
602
625
      }
603
1.69k
      else if (c == '/')
604
1.62k
      {
605
1.62k
        state = json_tokener_state_comment_eol;
606
1.62k
      }
607
62
      else
608
62
      {
609
62
        tok->err = json_tokener_error_parse_comment;
610
62
        goto out;
611
62
      }
612
2.25k
      printbuf_memappend_checked(tok->pb, &c, 1);
613
2.25k
      break;
614
615
3.82k
    case json_tokener_state_comment:
616
3.82k
    {
617
      /* Advance until we change state */
618
3.82k
      const char *case_start = str;
619
340k
      while (c != '*')
620
336k
      {
621
336k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
622
147
        {
623
147
          printbuf_memappend_checked(tok->pb, case_start,
624
147
                                     str - case_start);
625
147
          goto out;
626
147
        }
627
336k
      }
628
3.67k
      printbuf_memappend_checked(tok->pb, case_start, 1 + str - case_start);
629
3.67k
      state = json_tokener_state_comment_end;
630
3.67k
    }
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
198k
      while (c != '\n')
638
197k
      {
639
197k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
640
111
        {
641
111
          printbuf_memappend_checked(tok->pb, case_start,
642
111
                                     str - case_start);
643
111
          goto out;
644
111
        }
645
197k
      }
646
1.51k
      printbuf_memappend_checked(tok->pb, case_start, str - case_start);
647
1.51k
      MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
648
1.51k
      state = json_tokener_state_eatws;
649
1.51k
    }
650
0
    break;
651
652
3.67k
    case json_tokener_state_comment_end:
653
3.67k
      printbuf_memappend_checked(tok->pb, &c, 1);
654
3.67k
      if (c == '/')
655
471
      {
656
471
        MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
657
471
        state = json_tokener_state_eatws;
658
471
      }
659
3.20k
      else
660
3.20k
      {
661
3.20k
        state = json_tokener_state_comment;
662
3.20k
      }
663
3.67k
      break;
664
665
106k
    case json_tokener_state_string:
666
106k
    {
667
      /* Advance until we change state */
668
106k
      const char *case_start = str;
669
1.78M
      while (1)
670
1.78M
      {
671
1.78M
        if (c == tok->quote_char)
672
67.7k
        {
673
67.7k
          printbuf_memappend_checked(tok->pb, case_start,
674
67.7k
                                     str - case_start);
675
67.7k
          current =
676
67.7k
              json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
677
67.7k
          if (current == NULL)
678
0
          {
679
0
            tok->err = json_tokener_error_memory;
680
0
            goto out;
681
0
          }
682
67.7k
          saved_state = json_tokener_state_finish;
683
67.7k
          state = json_tokener_state_eatws;
684
67.7k
          break;
685
67.7k
        }
686
1.71M
        else if (c == '\\')
687
38.0k
        {
688
38.0k
          printbuf_memappend_checked(tok->pb, case_start,
689
38.0k
                                     str - case_start);
690
38.0k
          saved_state = json_tokener_state_string;
691
38.0k
          state = json_tokener_state_string_escape;
692
38.0k
          break;
693
38.0k
        }
694
1.68M
        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.68M
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
701
195
        {
702
195
          printbuf_memappend_checked(tok->pb, case_start,
703
195
                                     str - case_start);
704
195
          goto out;
705
195
        }
706
1.68M
      }
707
106k
    }
708
105k
    break;
709
710
105k
    case json_tokener_state_string_escape:
711
52.8k
      switch (c)
712
52.8k
      {
713
8.74k
      case '"':
714
26.7k
      case '\\':
715
27.0k
      case '/':
716
27.0k
        printbuf_memappend_checked(tok->pb, &c, 1);
717
27.0k
        state = saved_state;
718
27.0k
        break;
719
1.01k
      case 'b':
720
16.1k
      case 'n':
721
16.7k
      case 'r':
722
17.8k
      case 't':
723
18.2k
      case 'f':
724
18.2k
        if (c == 'b')
725
1.01k
          printbuf_memappend_checked(tok->pb, "\b", 1);
726
17.2k
        else if (c == 'n')
727
15.1k
          printbuf_memappend_checked(tok->pb, "\n", 1);
728
2.08k
        else if (c == 'r')
729
573
          printbuf_memappend_checked(tok->pb, "\r", 1);
730
1.51k
        else if (c == 't')
731
1.10k
          printbuf_memappend_checked(tok->pb, "\t", 1);
732
411
        else if (c == 'f')
733
411
          printbuf_memappend_checked(tok->pb, "\f", 1);
734
18.2k
        state = saved_state;
735
18.2k
        break;
736
7.53k
      case 'u':
737
7.53k
        tok->ucs_char = 0;
738
7.53k
        tok->st_pos = 0;
739
7.53k
        state = json_tokener_state_escape_unicode;
740
7.53k
        break;
741
34
      default: tok->err = json_tokener_error_parse_string; goto out;
742
52.8k
      }
743
52.7k
      break;
744
745
      // ===================================================
746
747
52.7k
    case json_tokener_state_escape_unicode:
748
8.68k
    {
749
      /* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */
750
34.6k
      while (1)
751
34.6k
      {
752
34.6k
        if (!c || !is_hex_char(c))
753
67
        {
754
67
          tok->err = json_tokener_error_parse_string;
755
67
          goto out;
756
67
        }
757
34.5k
        tok->ucs_char |=
758
34.5k
            ((unsigned int)jt_hexdigit(c) << ((3 - tok->st_pos) * 4));
759
34.5k
        tok->st_pos++;
760
34.5k
        if (tok->st_pos >= 4)
761
8.61k
          break;
762
763
25.9k
        (void)ADVANCE_CHAR(str, tok);
764
25.9k
        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
25.9k
      }
775
8.61k
      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
8.61k
      if (tok->high_surrogate)
781
1.13k
      {
782
1.13k
        if (IS_LOW_SURROGATE(tok->ucs_char))
783
512
        {
784
          /* Recalculate the ucs_char, then fall thru to process normally */
785
512
          tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate,
786
512
                                                tok->ucs_char);
787
512
        }
788
627
        else
789
627
        {
790
          /* High surrogate was not followed by a low surrogate
791
           * Replace the high and process the rest normally
792
           */
793
627
          printbuf_memappend_checked(tok->pb,
794
627
                                     (char *)utf8_replacement_char, 3);
795
627
        }
796
1.13k
        tok->high_surrogate = 0;
797
1.13k
      }
798
799
8.61k
      if (tok->ucs_char < 0x80)
800
1.53k
      {
801
1.53k
        unsigned char unescaped_utf[1];
802
1.53k
        unescaped_utf[0] = tok->ucs_char;
803
1.53k
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 1);
804
1.53k
      }
805
7.08k
      else if (tok->ucs_char < 0x800)
806
2.68k
      {
807
2.68k
        unsigned char unescaped_utf[2];
808
2.68k
        unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
809
2.68k
        unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
810
2.68k
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 2);
811
2.68k
      }
812
4.40k
      else if (IS_HIGH_SURROGATE(tok->ucs_char))
813
2.16k
      {
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
2.16k
        tok->high_surrogate = tok->ucs_char;
829
2.16k
        tok->ucs_char = 0;
830
2.16k
        state = json_tokener_state_escape_unicode_need_escape;
831
2.16k
        break;
832
2.16k
      }
833
2.24k
      else if (IS_LOW_SURROGATE(tok->ucs_char))
834
597
      {
835
        /* Got a low surrogate not preceded by a high */
836
597
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
837
597
      }
838
1.64k
      else if (tok->ucs_char < 0x10000)
839
1.13k
      {
840
1.13k
        unsigned char unescaped_utf[3];
841
1.13k
        unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
842
1.13k
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
843
1.13k
        unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
844
1.13k
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 3);
845
1.13k
      }
846
512
      else if (tok->ucs_char < 0x110000)
847
512
      {
848
512
        unsigned char unescaped_utf[4];
849
512
        unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
850
512
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
851
512
        unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
852
512
        unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
853
512
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 4);
854
512
      }
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
6.45k
      state = saved_state; // i.e. _state_string or _state_object_field
861
6.45k
    }
862
0
    break;
863
864
2.16k
    case json_tokener_state_escape_unicode_need_escape:
865
      // We get here after processing a high_surrogate
866
      // require a '\\' char
867
2.16k
      if (!c || c != '\\')
868
479
      {
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
479
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
874
479
        tok->high_surrogate = 0;
875
479
        tok->ucs_char = 0;
876
479
        tok->st_pos = 0;
877
479
        state = saved_state;
878
479
        goto redo_char;
879
479
      }
880
1.68k
      state = json_tokener_state_escape_unicode_need_u;
881
1.68k
      break;
882
883
1.68k
    case json_tokener_state_escape_unicode_need_u:
884
      /* We already had a \ char, check that it's \u */
885
1.68k
      if (!c || c != 'u')
886
526
      {
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
526
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
893
526
        tok->high_surrogate = 0;
894
526
        tok->ucs_char = 0;
895
526
        tok->st_pos = 0;
896
526
        state = json_tokener_state_string_escape;
897
526
        goto redo_char;
898
526
      }
899
1.15k
      state = json_tokener_state_escape_unicode;
900
1.15k
      break;
901
902
      // ===================================================
903
904
9.53k
    case json_tokener_state_boolean:
905
9.53k
    {
906
9.53k
      int size1, size2;
907
9.53k
      printbuf_memappend_checked(tok->pb, &c, 1);
908
9.53k
      size1 = json_min(tok->st_pos + 1, json_true_str_len);
909
9.53k
      size2 = json_min(tok->st_pos + 1, json_false_str_len);
910
9.53k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
911
9.53k
           strncasecmp(json_true_str, tok->pb->buf, size1) == 0) ||
912
3.63k
          (strncmp(json_true_str, tok->pb->buf, size1) == 0))
913
5.90k
      {
914
5.90k
        if (tok->st_pos == json_true_str_len)
915
1.15k
        {
916
1.15k
          current = json_object_new_boolean(1);
917
1.15k
          if (current == NULL)
918
0
          {
919
0
            tok->err = json_tokener_error_memory;
920
0
            goto out;
921
0
          }
922
1.15k
          saved_state = json_tokener_state_finish;
923
1.15k
          state = json_tokener_state_eatws;
924
1.15k
          goto redo_char;
925
1.15k
        }
926
5.90k
      }
927
3.63k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
928
3.63k
                strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
929
133
               (strncmp(json_false_str, tok->pb->buf, size2) == 0))
930
3.50k
      {
931
3.50k
        if (tok->st_pos == json_false_str_len)
932
562
        {
933
562
          current = json_object_new_boolean(0);
934
562
          if (current == NULL)
935
0
          {
936
0
            tok->err = json_tokener_error_memory;
937
0
            goto out;
938
0
          }
939
562
          saved_state = json_tokener_state_finish;
940
562
          state = json_tokener_state_eatws;
941
562
          goto redo_char;
942
562
        }
943
3.50k
      }
944
133
      else
945
133
      {
946
133
        tok->err = json_tokener_error_parse_boolean;
947
133
        goto out;
948
133
      }
949
7.68k
      tok->st_pos++;
950
7.68k
    }
951
0
    break;
952
953
136k
    case json_tokener_state_number:
954
136k
    {
955
      /* Advance until we change state */
956
136k
      const char *case_start = str;
957
136k
      int case_len = 0;
958
136k
      int is_exponent = 0;
959
136k
      int neg_sign_ok = 1;
960
136k
      int pos_sign_ok = 0;
961
136k
      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
410k
      while (c && ((c >= '0' && c <= '9') ||
986
144k
                   (!is_exponent && (c == 'e' || c == 'E')) ||
987
141k
                   (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') ||
988
136k
                   (!tok->is_double && c == '.')))
989
274k
      {
990
274k
        pos_sign_ok = neg_sign_ok = 0;
991
274k
        ++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
274k
        switch (c)
1000
274k
        {
1001
946
        case '.':
1002
946
          tok->is_double = 1;
1003
946
          pos_sign_ok = 1;
1004
946
          neg_sign_ok = 1;
1005
946
          break;
1006
1.68k
        case 'e': /* FALLTHRU */
1007
2.67k
        case 'E':
1008
2.67k
          is_exponent = 1;
1009
2.67k
          tok->is_double = 1;
1010
          /* the exponent part can begin with a negative sign */
1011
2.67k
          pos_sign_ok = neg_sign_ok = 1;
1012
2.67k
          break;
1013
271k
        default: break;
1014
274k
        }
1015
1016
274k
        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
274k
      }
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
136k
      if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
1031
3.21k
          c != 'I' && c != 'i' && !is_ws_char(c))
1032
200
      {
1033
200
        tok->err = json_tokener_error_parse_number;
1034
200
        goto out;
1035
200
      }
1036
135k
      if (case_len > 0)
1037
135k
        printbuf_memappend_checked(tok->pb, case_start, case_len);
1038
1039
      // Check for -Infinity
1040
135k
      if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
1041
470
      {
1042
470
        state = json_tokener_state_inf;
1043
470
        tok->st_pos = 0;
1044
470
        goto redo_char;
1045
470
      }
1046
135k
      if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
1047
3.03k
      {
1048
        /* Trim some chars off the end, to allow things
1049
           like "123e+" to parse ok. */
1050
6.51k
        while (printbuf_length(tok->pb) > 1)
1051
5.26k
        {
1052
5.26k
          char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1];
1053
5.26k
          if (last_char != 'e' && last_char != 'E' &&
1054
3.34k
              last_char != '-' && last_char != '+')
1055
1.79k
          {
1056
1.79k
            break;
1057
1.79k
          }
1058
3.47k
          tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0';
1059
3.47k
          printbuf_length(tok->pb)--;
1060
3.47k
        }
1061
3.03k
      }
1062
135k
    }
1063
0
      {
1064
135k
        int64_t num64;
1065
135k
        uint64_t numuint64;
1066
135k
        double numd;
1067
135k
        if (!tok->is_double && tok->pb->buf[0] == '-' &&
1068
2.33k
            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
133k
        else if (!tok->is_double && tok->pb->buf[0] != '-' &&
1083
129k
                 json_parse_uint64(tok->pb->buf, &numuint64) == 0)
1084
129k
        {
1085
129k
          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
129k
          if (numuint64 && tok->pb->buf[0] == '0' &&
1091
3.61k
              (tok->flags & JSON_TOKENER_STRICT))
1092
0
          {
1093
0
            tok->err = json_tokener_error_parse_number;
1094
0
            goto out;
1095
0
          }
1096
129k
          if (numuint64 <= INT64_MAX)
1097
129k
          {
1098
129k
            num64 = (uint64_t)numuint64;
1099
129k
            current = json_object_new_int64(num64);
1100
129k
            if (current == NULL)
1101
0
            {
1102
0
              tok->err = json_tokener_error_memory;
1103
0
              goto out;
1104
0
            }
1105
129k
          }
1106
898
          else
1107
898
          {
1108
898
            current = json_object_new_uint64(numuint64);
1109
898
            if (current == NULL)
1110
0
            {
1111
0
              tok->err = json_tokener_error_memory;
1112
0
              goto out;
1113
0
            }
1114
898
          }
1115
129k
        }
1116
3.05k
        else if (tok->is_double &&
1117
3.03k
                 json_tokener_parse_double(
1118
3.03k
                     tok->pb->buf, printbuf_length(tok->pb), &numd) == 0)
1119
3.01k
        {
1120
3.01k
          current = json_object_new_double_s(numd, tok->pb->buf);
1121
3.01k
          if (current == NULL)
1122
0
          {
1123
0
            tok->err = json_tokener_error_memory;
1124
0
            goto out;
1125
0
          }
1126
3.01k
        }
1127
37
        else
1128
37
        {
1129
37
          tok->err = json_tokener_error_parse_number;
1130
37
          goto out;
1131
37
        }
1132
135k
        saved_state = json_tokener_state_finish;
1133
135k
        state = json_tokener_state_eatws;
1134
135k
        goto redo_char;
1135
135k
      }
1136
0
      break;
1137
1138
147k
    case json_tokener_state_array_after_sep:
1139
161k
    case json_tokener_state_array:
1140
161k
      if (c == ']')
1141
2.10k
      {
1142
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1143
2.10k
        json_object_array_shrink(current, 0);
1144
1145
2.10k
        if (state == json_tokener_state_array_after_sep &&
1146
620
            (tok->flags & JSON_TOKENER_STRICT))
1147
0
        {
1148
0
          tok->err = json_tokener_error_parse_unexpected;
1149
0
          goto out;
1150
0
        }
1151
2.10k
        saved_state = json_tokener_state_finish;
1152
2.10k
        state = json_tokener_state_eatws;
1153
2.10k
      }
1154
159k
      else
1155
159k
      {
1156
159k
        if (tok->depth >= tok->max_depth - 1)
1157
8
        {
1158
8
          tok->err = json_tokener_error_depth;
1159
8
          goto out;
1160
8
        }
1161
159k
        state = json_tokener_state_array_add;
1162
159k
        tok->depth++;
1163
159k
        json_tokener_reset_level(tok, tok->depth);
1164
159k
        goto redo_char;
1165
159k
      }
1166
2.10k
      break;
1167
1168
157k
    case json_tokener_state_array_add:
1169
157k
      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
157k
      saved_state = json_tokener_state_array_sep;
1175
157k
      state = json_tokener_state_eatws;
1176
157k
      goto redo_char;
1177
1178
157k
    case json_tokener_state_array_sep:
1179
157k
      if (c == ']')
1180
9.64k
      {
1181
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1182
9.64k
        json_object_array_shrink(current, 0);
1183
1184
9.64k
        saved_state = json_tokener_state_finish;
1185
9.64k
        state = json_tokener_state_eatws;
1186
9.64k
      }
1187
147k
      else if (c == ',')
1188
147k
      {
1189
147k
        saved_state = json_tokener_state_array_after_sep;
1190
147k
        state = json_tokener_state_eatws;
1191
147k
      }
1192
126
      else
1193
126
      {
1194
126
        tok->err = json_tokener_error_parse_array;
1195
126
        goto out;
1196
126
      }
1197
157k
      break;
1198
1199
157k
    case json_tokener_state_object_field_start:
1200
141k
    case json_tokener_state_object_field_start_after_sep:
1201
141k
      if (c == '}')
1202
19.0k
      {
1203
19.0k
        if (state == json_tokener_state_object_field_start_after_sep &&
1204
211
            (tok->flags & JSON_TOKENER_STRICT))
1205
0
        {
1206
0
          tok->err = json_tokener_error_parse_unexpected;
1207
0
          goto out;
1208
0
        }
1209
19.0k
        saved_state = json_tokener_state_finish;
1210
19.0k
        state = json_tokener_state_eatws;
1211
19.0k
      }
1212
122k
      else if (c == '"' || c == '\'')
1213
122k
      {
1214
122k
        tok->quote_char = c;
1215
122k
        printbuf_reset(tok->pb);
1216
122k
        state = json_tokener_state_object_field;
1217
122k
      }
1218
69
      else
1219
69
      {
1220
69
        tok->err = json_tokener_error_parse_object_key_name;
1221
69
        goto out;
1222
69
      }
1223
141k
      break;
1224
1225
141k
    case json_tokener_state_object_field:
1226
136k
    {
1227
      /* Advance until we change state */
1228
136k
      const char *case_start = str;
1229
1.97M
      while (1)
1230
1.97M
      {
1231
1.97M
        if (c == tok->quote_char)
1232
122k
        {
1233
122k
          printbuf_memappend_checked(tok->pb, case_start,
1234
122k
                                     str - case_start);
1235
122k
          obj_field_name = strdup(tok->pb->buf);
1236
122k
          if (obj_field_name == NULL)
1237
0
          {
1238
0
            tok->err = json_tokener_error_memory;
1239
0
            goto out;
1240
0
          }
1241
122k
          saved_state = json_tokener_state_object_field_end;
1242
122k
          state = json_tokener_state_eatws;
1243
122k
          break;
1244
122k
        }
1245
1.85M
        else if (c == '\\')
1246
14.2k
        {
1247
14.2k
          printbuf_memappend_checked(tok->pb, case_start,
1248
14.2k
                                     str - case_start);
1249
14.2k
          saved_state = json_tokener_state_object_field;
1250
14.2k
          state = json_tokener_state_string_escape;
1251
14.2k
          break;
1252
14.2k
        }
1253
1.84M
        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.84M
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
1260
154
        {
1261
154
          printbuf_memappend_checked(tok->pb, case_start,
1262
154
                                     str - case_start);
1263
154
          goto out;
1264
154
        }
1265
1.84M
      }
1266
136k
    }
1267
136k
    break;
1268
1269
136k
    case json_tokener_state_object_field_end:
1270
122k
      if (c == ':')
1271
121k
      {
1272
121k
        saved_state = json_tokener_state_object_value;
1273
121k
        state = json_tokener_state_eatws;
1274
121k
      }
1275
112
      else
1276
112
      {
1277
112
        tok->err = json_tokener_error_parse_object_key_sep;
1278
112
        goto out;
1279
112
      }
1280
121k
      break;
1281
1282
121k
    case json_tokener_state_object_value:
1283
121k
      if (tok->depth >= tok->max_depth - 1)
1284
6
      {
1285
6
        tok->err = json_tokener_error_depth;
1286
6
        goto out;
1287
6
      }
1288
121k
      state = json_tokener_state_object_value_add;
1289
121k
      tok->depth++;
1290
121k
      json_tokener_reset_level(tok, tok->depth);
1291
121k
      goto redo_char;
1292
1293
120k
    case json_tokener_state_object_value_add:
1294
120k
      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
120k
      free(obj_field_name);
1300
120k
      obj_field_name = NULL;
1301
120k
      saved_state = json_tokener_state_object_sep;
1302
120k
      state = json_tokener_state_eatws;
1303
120k
      goto redo_char;
1304
1305
120k
    case json_tokener_state_object_sep:
1306
      /* { */
1307
120k
      if (c == '}')
1308
30.3k
      {
1309
30.3k
        saved_state = json_tokener_state_finish;
1310
30.3k
        state = json_tokener_state_eatws;
1311
30.3k
      }
1312
89.9k
      else if (c == ',')
1313
89.7k
      {
1314
89.7k
        saved_state = json_tokener_state_object_field_start_after_sep;
1315
89.7k
        state = json_tokener_state_eatws;
1316
89.7k
      }
1317
213
      else
1318
213
      {
1319
213
        tok->err = json_tokener_error_parse_object_value_sep;
1320
213
        goto out;
1321
213
      }
1322
120k
      break;
1323
3.63M
    }
1324
1.07M
    (void)ADVANCE_CHAR(str, tok);
1325
1.07M
    if (!c) // This is the char *before* advancing
1326
7
      break;
1327
1.07M
  } /* while(PEEK_CHAR) */
1328
1329
9.08k
out:
1330
9.08k
  if ((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && (nBytes != 0))
1331
0
  {
1332
0
    tok->err = json_tokener_error_parse_utf8_string;
1333
0
  }
1334
9.08k
  if (c && (state == json_tokener_state_finish) && (tok->depth == 0) &&
1335
104
      (tok->flags & (JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS)) ==
1336
104
          JSON_TOKENER_STRICT)
1337
0
  {
1338
    /* unexpected char after JSON data */
1339
0
    tok->err = json_tokener_error_parse_unexpected;
1340
0
  }
1341
9.08k
  if (!c)
1342
7.72k
  {
1343
    /* We hit an eof char (0) */
1344
7.72k
    if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
1345
629
      tok->err = json_tokener_error_parse_eof;
1346
7.72k
  }
1347
1348
9.08k
#ifdef HAVE_USELOCALE
1349
9.08k
  uselocale(oldlocale);
1350
9.08k
  freelocale(newloc);
1351
#elif defined(HAVE_SETLOCALE)
1352
  setlocale(LC_NUMERIC, oldlocale);
1353
  free(oldlocale);
1354
#endif
1355
1356
9.08k
  if (tok->err == json_tokener_success)
1357
7.20k
  {
1358
7.20k
    json_object *ret = json_object_get(current);
1359
7.20k
    int ii;
1360
1361
    /* Partially reset, so we parse additional objects on subsequent calls. */
1362
14.8k
    for (ii = tok->depth; ii >= 0; ii--)
1363
7.60k
      json_tokener_reset_level(tok, ii);
1364
7.20k
    return ret;
1365
7.20k
  }
1366
1367
1.87k
  MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
1368
1.87k
           tok->char_offset);
1369
1.87k
  return NULL;
1370
9.08k
}
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
3.03k
{
1411
3.03k
  char *end;
1412
3.03k
  *retval = strtod(buf, &end);
1413
3.03k
  if (buf + len == end)
1414
3.01k
    return 0; // It worked
1415
22
  return 1;
1416
3.03k
}