Coverage Report

Created: 2025-11-11 06:20

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
19.8k
#define jt_hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x)&7) + 9)
48
49
#if !HAVE_STRNCASECMP && defined(_MSC_VER)
50
/* MSC has the version as _strnicmp */
51
#define strncasecmp _strnicmp
52
#elif !HAVE_STRNCASECMP
53
#error You do not have strncasecmp on your system.
54
#endif /* HAVE_STRNCASECMP */
55
56
#if defined(_MSC_VER) && (_MSC_VER <= 1800)
57
/* VS2013 doesn't know about "inline" */
58
#define inline __inline
59
#elif defined(AIX_CC)
60
#define inline
61
#endif
62
63
/* The following helper functions are used to speed up parsing. They
64
 * are faster than their ctype counterparts because they assume that
65
 * the input is in ASCII and that the locale is set to "C". The
66
 * compiler will also inline these functions, providing an additional
67
 * speedup by saving on function calls.
68
 */
69
static inline int is_ws_char(char c)
70
1.70M
{
71
1.70M
  return c == ' '
72
1.53M
      || c == '\t'
73
1.51M
      || c == '\n'
74
1.51M
      || c == '\r';
75
1.70M
}
76
77
static inline int is_hex_char(char c)
78
19.9k
{
79
19.9k
  return (c >= '0' && c <= '9')
80
8.56k
      || (c >= 'A' && c <= 'F')
81
1.82k
      || (c >= 'a' && c <= 'f');
82
19.9k
}
83
84
/* Use C99 NAN by default; if not available, nan("") should work too. */
85
#ifndef NAN
86
#define NAN nan("")
87
#endif /* !NAN */
88
89
static const char json_null_str[] = "null";
90
static const int json_null_str_len = sizeof(json_null_str) - 1;
91
static const char json_inf_str[] = "Infinity";
92
/* Swapped case "Infinity" to avoid need to call tolower() on input chars: */
93
static const char json_inf_str_invert[] = "iNFINITY";
94
static const unsigned int json_inf_str_len = sizeof(json_inf_str) - 1;
95
static const char json_nan_str[] = "NaN";
96
static const int json_nan_str_len = sizeof(json_nan_str) - 1;
97
static const char json_true_str[] = "true";
98
static const int json_true_str_len = sizeof(json_true_str) - 1;
99
static const char json_false_str[] = "false";
100
static const int json_false_str_len = sizeof(json_false_str) - 1;
101
102
/* clang-format off */
103
static const char *json_tokener_errors[] = {
104
  "success",
105
  "continue",
106
  "nesting too deep",
107
  "unexpected end of data",
108
  "unexpected character",
109
  "null expected",
110
  "boolean expected",
111
  "number expected",
112
  "array value separator ',' expected",
113
  "quoted object property name expected",
114
  "object property name separator ':' expected",
115
  "object value separator ',' expected",
116
  "invalid string sequence",
117
  "expected comment",
118
  "invalid utf-8 string",
119
  "buffer size overflow",
120
  "out of memory"
121
};
122
/* clang-format on */
123
124
/**
125
 * validete the utf-8 string in strict model.
126
 * if not utf-8 format, return err.
127
 */
128
static json_bool json_tokener_validate_utf8(const char c, unsigned int *nBytes);
129
130
static int json_tokener_parse_double(const char *buf, int len, double *retval);
131
132
const char *json_tokener_error_desc(enum json_tokener_error jerr)
133
2.27k
{
134
2.27k
  int jerr_int = (int)jerr;
135
2.27k
  if (jerr_int < 0 ||
136
2.27k
      jerr_int >= (int)(sizeof(json_tokener_errors) / sizeof(json_tokener_errors[0])))
137
0
    return "Unknown error, "
138
0
           "invalid json_tokener_error value passed to json_tokener_error_desc()";
139
2.27k
  return json_tokener_errors[jerr];
140
2.27k
}
141
142
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok)
143
4.55k
{
144
4.55k
  return tok->err;
145
4.55k
}
146
147
/* Stuff for decoding unicode sequences */
148
3.42k
#define IS_HIGH_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xD800)
149
2.62k
#define IS_LOW_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xDC00)
150
527
#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
10.2k
{
155
10.2k
  struct json_tokener *tok;
156
157
10.2k
  if (depth < 1)
158
0
    return NULL;
159
160
10.2k
  tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
161
10.2k
  if (!tok)
162
0
    return NULL;
163
10.2k
  tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
164
10.2k
  if (!tok->stack)
165
0
  {
166
0
    free(tok);
167
0
    return NULL;
168
0
  }
169
10.2k
  tok->pb = printbuf_new();
170
10.2k
  if (!tok->pb)
171
0
  {
172
0
    free(tok->stack);
173
0
    free(tok);
174
0
    return NULL;
175
0
  }
176
10.2k
  tok->max_depth = depth;
177
10.2k
  json_tokener_reset(tok);
178
10.2k
  return tok;
179
10.2k
}
180
181
struct json_tokener *json_tokener_new(void)
182
10.2k
{
183
10.2k
  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
184
10.2k
}
185
186
void json_tokener_free(struct json_tokener *tok)
187
10.2k
{
188
10.2k
  if (!tok)
189
0
    return;
190
10.2k
  json_tokener_reset(tok);
191
10.2k
  if (tok->pb)
192
10.2k
    printbuf_free(tok->pb);
193
10.2k
  free(tok->stack);
194
10.2k
  free(tok);
195
10.2k
}
196
197
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
198
638k
{
199
638k
  tok->stack[depth].state = json_tokener_state_eatws;
200
638k
  tok->stack[depth].saved_state = json_tokener_state_start;
201
638k
  json_object_put(tok->stack[depth].current);
202
638k
  tok->stack[depth].current = NULL;
203
638k
  free(tok->stack[depth].obj_field_name);
204
638k
  tok->stack[depth].obj_field_name = NULL;
205
638k
}
206
207
void json_tokener_reset(struct json_tokener *tok)
208
20.5k
{
209
20.5k
  int i;
210
20.5k
  if (!tok)
211
0
    return;
212
213
44.8k
  for (i = tok->depth; i >= 0; i--)
214
24.3k
    json_tokener_reset_level(tok, i);
215
20.5k
  tok->depth = 0;
216
20.5k
  tok->err = json_tokener_success;
217
20.5k
}
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
7.41M
#define state tok->stack[tok->depth].state
262
2.80M
#define saved_state tok->stack[tok->depth].saved_state
263
1.23M
#define current tok->stack[tok->depth].current
264
632k
#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
6.24M
  (((tok)->char_offset == len)                                         \
286
6.24M
       ? (((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
6.24M
       : (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) &&                \
291
6.24M
           (!json_tokener_validate_utf8(*str, nBytesp)))               \
292
6.24M
              ? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
293
6.24M
              : (((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
11.1M
#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
547k
  do {                                                  \
308
547k
    if (printbuf_memappend((p), (s), (l)) < 0)    \
309
547k
    {                                             \
310
0
      tok->err = json_tokener_error_memory; \
311
0
      goto out;                             \
312
0
    }                                             \
313
547k
  } 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
10.2k
{
319
10.2k
  struct json_object *obj = NULL;
320
10.2k
  char c = '\1';
321
10.2k
  unsigned int nBytes = 0;
322
10.2k
  unsigned int *nBytesp = &nBytes;
323
324
10.2k
#ifdef HAVE_USELOCALE
325
10.2k
  locale_t oldlocale = uselocale(NULL);
326
10.2k
  locale_t newloc;
327
#elif defined(HAVE_SETLOCALE)
328
  char *oldlocale = NULL;
329
#endif
330
331
10.2k
  tok->char_offset = 0;
332
10.2k
  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
10.2k
  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
10.2k
#ifdef HAVE_USELOCALE
347
10.2k
  {
348
10.2k
#ifdef HAVE_DUPLOCALE
349
10.2k
    locale_t duploc = duplocale(oldlocale);
350
10.2k
    if (duploc == NULL && errno == ENOMEM)
351
0
    {
352
0
      tok->err = json_tokener_error_memory;
353
0
      return NULL;
354
0
    }
355
10.2k
    newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
356
#else
357
    newloc = newlocale(LC_NUMERIC_MASK, "C", oldlocale);
358
#endif
359
10.2k
    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
10.2k
    uselocale(newloc);
375
10.2k
  }
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.12M
  while (PEEK_CHAR(c, tok)) // Note: c might be '\0' !
394
1.12M
  {
395
396
3.87M
  redo_char:
397
3.87M
    switch (state)
398
3.87M
    {
399
400
1.51M
    case json_tokener_state_eatws:
401
      /* Advance until we change state */
402
1.70M
      while (is_ws_char(c))
403
189k
      {
404
189k
        if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
405
0
          goto out;
406
189k
      }
407
1.51M
      if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
408
2.43k
      {
409
2.43k
        printbuf_reset(tok->pb);
410
2.43k
        printbuf_memappend_checked(tok->pb, &c, 1);
411
2.43k
        state = json_tokener_state_comment_start;
412
2.43k
      }
413
1.50M
      else
414
1.50M
      {
415
1.50M
        state = saved_state;
416
1.50M
        goto redo_char;
417
1.50M
      }
418
2.43k
      break;
419
420
315k
    case json_tokener_state_start:
421
315k
      switch (c)
422
315k
      {
423
57.5k
      case '{':
424
57.5k
        state = json_tokener_state_eatws;
425
57.5k
        saved_state = json_tokener_state_object_field_start;
426
57.5k
        current = json_object_new_object();
427
57.5k
        if (current == NULL)
428
0
        {
429
0
          tok->err = json_tokener_error_memory;
430
0
          goto out;
431
0
        }
432
57.5k
        break;
433
57.5k
      case '[':
434
15.0k
        state = json_tokener_state_eatws;
435
15.0k
        saved_state = json_tokener_state_array;
436
15.0k
        current = json_object_new_array();
437
15.0k
        if (current == NULL)
438
0
        {
439
0
          tok->err = json_tokener_error_memory;
440
0
          goto out;
441
0
        }
442
15.0k
        break;
443
15.0k
      case 'I':
444
468
      case 'i':
445
468
        state = json_tokener_state_inf;
446
468
        printbuf_reset(tok->pb);
447
468
        tok->st_pos = 0;
448
468
        goto redo_char;
449
1.04k
      case 'N':
450
13.3k
      case 'n':
451
13.3k
        state = json_tokener_state_null; // or NaN
452
13.3k
        printbuf_reset(tok->pb);
453
13.3k
        tok->st_pos = 0;
454
13.3k
        goto redo_char;
455
494
      case '\'':
456
494
        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
76.9k
      case '"':
464
76.9k
        state = json_tokener_state_string;
465
76.9k
        printbuf_reset(tok->pb);
466
76.9k
        tok->quote_char = c;
467
76.9k
        break;
468
667
      case 'T':
469
1.18k
      case 't':
470
1.32k
      case 'F':
471
1.73k
      case 'f':
472
1.73k
        state = json_tokener_state_boolean;
473
1.73k
        printbuf_reset(tok->pb);
474
1.73k
        tok->st_pos = 0;
475
1.73k
        goto redo_char;
476
23.5k
      case '0':
477
31.1k
      case '1':
478
34.6k
      case '2':
479
36.5k
      case '3':
480
39.2k
      case '4':
481
142k
      case '5':
482
143k
      case '6':
483
144k
      case '7':
484
145k
      case '8':
485
146k
      case '9':
486
150k
      case '-':
487
150k
        state = json_tokener_state_number;
488
150k
        printbuf_reset(tok->pb);
489
150k
        tok->is_double = 0;
490
150k
        goto redo_char;
491
134
      default: tok->err = json_tokener_error_parse_unexpected; goto out;
492
315k
      }
493
149k
      break;
494
495
309k
    case json_tokener_state_finish:
496
309k
      if (tok->depth == 0)
497
7.90k
        goto out;
498
301k
      obj = json_object_get(current);
499
301k
      json_tokener_reset_level(tok, tok->depth);
500
301k
      tok->depth--;
501
301k
      goto redo_char;
502
503
903
    case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
504
903
    {
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
903
      int is_negative = 0;
513
514
      /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
515
7.63k
      while (tok->st_pos < (int)json_inf_str_len)
516
6.81k
      {
517
6.81k
        char inf_char = *str;
518
6.81k
        if (inf_char != json_inf_str[tok->st_pos] &&
519
3.02k
            ((tok->flags & JSON_TOKENER_STRICT) ||
520
3.02k
              inf_char != json_inf_str_invert[tok->st_pos])
521
6.81k
           )
522
80
        {
523
80
          tok->err = json_tokener_error_parse_unexpected;
524
80
          goto out;
525
80
        }
526
6.73k
        tok->st_pos++;
527
6.73k
        (void)ADVANCE_CHAR(str, tok);
528
6.73k
        if (!PEEK_CHAR(c, tok))
529
0
        {
530
          /* out of input chars, for now at least */
531
0
          goto out;
532
0
        }
533
6.73k
      }
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
823
      if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
539
413
      {
540
413
        is_negative = 1;
541
413
      }
542
823
      current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
543
823
      if (current == NULL)
544
0
      {
545
0
        tok->err = json_tokener_error_memory;
546
0
        goto out;
547
0
      }
548
823
      saved_state = json_tokener_state_finish;
549
823
      state = json_tokener_state_eatws;
550
823
      goto redo_char;
551
823
    }
552
0
    break;
553
65.8k
    case json_tokener_state_null: /* aka starts with 'n' */
554
65.8k
    {
555
65.8k
      int size;
556
65.8k
      int size_nan;
557
65.8k
      printbuf_memappend_checked(tok->pb, &c, 1);
558
65.8k
      size = json_min(tok->st_pos + 1, json_null_str_len);
559
65.8k
      size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
560
65.8k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
561
65.8k
           strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
562
1.52k
          (strncmp(json_null_str, tok->pb->buf, size) == 0))
563
64.3k
      {
564
64.3k
        if (tok->st_pos == json_null_str_len)
565
12.7k
        {
566
12.7k
          current = NULL;
567
12.7k
          saved_state = json_tokener_state_finish;
568
12.7k
          state = json_tokener_state_eatws;
569
12.7k
          goto redo_char;
570
12.7k
        }
571
64.3k
      }
572
1.52k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
573
1.52k
                strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
574
100
               (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
575
1.42k
      {
576
1.42k
        if (tok->st_pos == json_nan_str_len)
577
467
        {
578
467
          current = json_object_new_double(NAN);
579
467
          if (current == NULL)
580
0
          {
581
0
            tok->err = json_tokener_error_memory;
582
0
            goto out;
583
0
          }
584
467
          saved_state = json_tokener_state_finish;
585
467
          state = json_tokener_state_eatws;
586
467
          goto redo_char;
587
467
        }
588
1.42k
      }
589
100
      else
590
100
      {
591
100
        tok->err = json_tokener_error_parse_null;
592
100
        goto out;
593
100
      }
594
52.5k
      tok->st_pos++;
595
52.5k
    }
596
0
    break;
597
598
2.43k
    case json_tokener_state_comment_start:
599
2.43k
      if (c == '*')
600
643
      {
601
643
        state = json_tokener_state_comment;
602
643
      }
603
1.79k
      else if (c == '/')
604
1.71k
      {
605
1.71k
        state = json_tokener_state_comment_eol;
606
1.71k
      }
607
76
      else
608
76
      {
609
76
        tok->err = json_tokener_error_parse_comment;
610
76
        goto out;
611
76
      }
612
2.35k
      printbuf_memappend_checked(tok->pb, &c, 1);
613
2.35k
      break;
614
615
3.45k
    case json_tokener_state_comment:
616
3.45k
    {
617
      /* Advance until we change state */
618
3.45k
      const char *case_start = str;
619
630k
      while (c != '*')
620
627k
      {
621
627k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
622
190
        {
623
190
          printbuf_memappend_checked(tok->pb, case_start,
624
190
                                     str - case_start);
625
190
          goto out;
626
190
        }
627
627k
      }
628
3.26k
      printbuf_memappend_checked(tok->pb, case_start, 1 + str - case_start);
629
3.26k
      state = json_tokener_state_comment_end;
630
3.26k
    }
631
0
    break;
632
633
1.71k
    case json_tokener_state_comment_eol:
634
1.71k
    {
635
      /* Advance until we change state */
636
1.71k
      const char *case_start = str;
637
186k
      while (c != '\n')
638
184k
      {
639
184k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
640
121
        {
641
121
          printbuf_memappend_checked(tok->pb, case_start,
642
121
                                     str - case_start);
643
121
          goto out;
644
121
        }
645
184k
      }
646
1.59k
      printbuf_memappend_checked(tok->pb, case_start, str - case_start);
647
1.59k
      MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
648
1.59k
      state = json_tokener_state_eatws;
649
1.59k
    }
650
0
    break;
651
652
3.26k
    case json_tokener_state_comment_end:
653
3.26k
      printbuf_memappend_checked(tok->pb, &c, 1);
654
3.26k
      if (c == '/')
655
445
      {
656
445
        MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
657
445
        state = json_tokener_state_eatws;
658
445
      }
659
2.82k
      else
660
2.82k
      {
661
2.82k
        state = json_tokener_state_comment;
662
2.82k
      }
663
3.26k
      break;
664
665
119k
    case json_tokener_state_string:
666
119k
    {
667
      /* Advance until we change state */
668
119k
      const char *case_start = str;
669
2.06M
      while (1)
670
2.06M
      {
671
2.06M
        if (c == tok->quote_char)
672
76.7k
        {
673
76.7k
          printbuf_memappend_checked(tok->pb, case_start,
674
76.7k
                                     str - case_start);
675
76.7k
          current =
676
76.7k
              json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
677
76.7k
          if (current == NULL)
678
0
          {
679
0
            tok->err = json_tokener_error_memory;
680
0
            goto out;
681
0
          }
682
76.7k
          saved_state = json_tokener_state_finish;
683
76.7k
          state = json_tokener_state_eatws;
684
76.7k
          break;
685
76.7k
        }
686
1.99M
        else if (c == '\\')
687
42.3k
        {
688
42.3k
          printbuf_memappend_checked(tok->pb, case_start,
689
42.3k
                                     str - case_start);
690
42.3k
          saved_state = json_tokener_state_string;
691
42.3k
          state = json_tokener_state_string_escape;
692
42.3k
          break;
693
42.3k
        }
694
1.94M
        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.94M
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
701
249
        {
702
249
          printbuf_memappend_checked(tok->pb, case_start,
703
249
                                     str - case_start);
704
249
          goto out;
705
249
        }
706
1.94M
      }
707
119k
    }
708
119k
    break;
709
710
119k
    case json_tokener_state_string_escape:
711
52.2k
      switch (c)
712
52.2k
      {
713
8.96k
      case '"':
714
29.4k
      case '\\':
715
29.7k
      case '/':
716
29.7k
        printbuf_memappend_checked(tok->pb, &c, 1);
717
29.7k
        state = saved_state;
718
29.7k
        break;
719
928
      case 'b':
720
16.5k
      case 'n':
721
17.0k
      case 'r':
722
18.0k
      case 't':
723
18.5k
      case 'f':
724
18.5k
        if (c == 'b')
725
928
          printbuf_memappend_checked(tok->pb, "\b", 1);
726
17.6k
        else if (c == 'n')
727
15.5k
          printbuf_memappend_checked(tok->pb, "\n", 1);
728
2.00k
        else if (c == 'r')
729
546
          printbuf_memappend_checked(tok->pb, "\r", 1);
730
1.46k
        else if (c == 't')
731
982
          printbuf_memappend_checked(tok->pb, "\t", 1);
732
481
        else if (c == 'f')
733
481
          printbuf_memappend_checked(tok->pb, "\f", 1);
734
18.5k
        state = saved_state;
735
18.5k
        break;
736
3.94k
      case 'u':
737
3.94k
        tok->ucs_char = 0;
738
3.94k
        tok->st_pos = 0;
739
3.94k
        state = json_tokener_state_escape_unicode;
740
3.94k
        break;
741
45
      default: tok->err = json_tokener_error_parse_string; goto out;
742
52.2k
      }
743
52.2k
      break;
744
745
      // ===================================================
746
747
52.2k
    case json_tokener_state_escape_unicode:
748
5.01k
    {
749
      /* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */
750
19.9k
      while (1)
751
19.9k
      {
752
19.9k
        if (!c || !is_hex_char(c))
753
79
        {
754
79
          tok->err = json_tokener_error_parse_string;
755
79
          goto out;
756
79
        }
757
19.8k
        tok->ucs_char |=
758
19.8k
            ((unsigned int)jt_hexdigit(c) << ((3 - tok->st_pos) * 4));
759
19.8k
        tok->st_pos++;
760
19.8k
        if (tok->st_pos >= 4)
761
4.94k
          break;
762
763
14.9k
        (void)ADVANCE_CHAR(str, tok);
764
14.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
14.9k
      }
775
4.94k
      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
4.94k
      if (tok->high_surrogate)
781
1.07k
      {
782
1.07k
        if (IS_LOW_SURROGATE(tok->ucs_char))
783
527
        {
784
          /* Recalculate the ucs_char, then fall thru to process normally */
785
527
          tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate,
786
527
                                                tok->ucs_char);
787
527
        }
788
544
        else
789
544
        {
790
          /* High surrogate was not followed by a low surrogate
791
           * Replace the high and process the rest normally
792
           */
793
544
          printbuf_memappend_checked(tok->pb,
794
544
                                     (char *)utf8_replacement_char, 3);
795
544
        }
796
1.07k
        tok->high_surrogate = 0;
797
1.07k
      }
798
799
4.94k
      if (tok->ucs_char < 0x80)
800
1.11k
      {
801
1.11k
        unsigned char unescaped_utf[1];
802
1.11k
        unescaped_utf[0] = tok->ucs_char;
803
1.11k
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 1);
804
1.11k
      }
805
3.82k
      else if (tok->ucs_char < 0x800)
806
398
      {
807
398
        unsigned char unescaped_utf[2];
808
398
        unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
809
398
        unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
810
398
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 2);
811
398
      }
812
3.42k
      else if (IS_HIGH_SURROGATE(tok->ucs_char))
813
1.86k
      {
814
        /*
815
         * The next two characters should be \u, HOWEVER,
816
         * we can't simply peek ahead here, because the
817
         * characters we need might not be passed to us
818
         * until a subsequent call to json_tokener_parse.
819
         * Instead, transition through a couple of states.
820
         * (now):
821
         *   _escape_unicode => _unicode_need_escape
822
         * (see a '\\' char):
823
         *   _unicode_need_escape => _unicode_need_u
824
         * (see a 'u' char):
825
         *   _unicode_need_u => _escape_unicode
826
         *      ...and we'll end up back around here.
827
         */
828
1.86k
        tok->high_surrogate = tok->ucs_char;
829
1.86k
        tok->ucs_char = 0;
830
1.86k
        state = json_tokener_state_escape_unicode_need_escape;
831
1.86k
        break;
832
1.86k
      }
833
1.55k
      else if (IS_LOW_SURROGATE(tok->ucs_char))
834
445
      {
835
        /* Got a low surrogate not preceded by a high */
836
445
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
837
445
      }
838
1.11k
      else if (tok->ucs_char < 0x10000)
839
585
      {
840
585
        unsigned char unescaped_utf[3];
841
585
        unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
842
585
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
843
585
        unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
844
585
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 3);
845
585
      }
846
527
      else if (tok->ucs_char < 0x110000)
847
527
      {
848
527
        unsigned char unescaped_utf[4];
849
527
        unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
850
527
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
851
527
        unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
852
527
        unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
853
527
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 4);
854
527
      }
855
0
      else
856
0
      {
857
        /* Don't know what we got--insert the replacement char */
858
0
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
859
0
      }
860
3.07k
      state = saved_state; // i.e. _state_string or _state_object_field
861
3.07k
    }
862
0
    break;
863
864
1.86k
    case json_tokener_state_escape_unicode_need_escape:
865
      // We get here after processing a high_surrogate
866
      // require a '\\' char
867
1.86k
      if (!c || c != '\\')
868
494
      {
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
494
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
874
494
        tok->high_surrogate = 0;
875
494
        tok->ucs_char = 0;
876
494
        tok->st_pos = 0;
877
494
        state = saved_state;
878
494
        goto redo_char;
879
494
      }
880
1.37k
      state = json_tokener_state_escape_unicode_need_u;
881
1.37k
      break;
882
883
1.37k
    case json_tokener_state_escape_unicode_need_u:
884
      /* We already had a \ char, check that it's \u */
885
1.37k
      if (!c || c != 'u')
886
293
      {
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
293
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
893
293
        tok->high_surrogate = 0;
894
293
        tok->ucs_char = 0;
895
293
        tok->st_pos = 0;
896
293
        state = json_tokener_state_string_escape;
897
293
        goto redo_char;
898
293
      }
899
1.07k
      state = json_tokener_state_escape_unicode;
900
1.07k
      break;
901
902
      // ===================================================
903
904
8.83k
    case json_tokener_state_boolean:
905
8.83k
    {
906
8.83k
      int size1, size2;
907
8.83k
      printbuf_memappend_checked(tok->pb, &c, 1);
908
8.83k
      size1 = json_min(tok->st_pos + 1, json_true_str_len);
909
8.83k
      size2 = json_min(tok->st_pos + 1, json_false_str_len);
910
8.83k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
911
8.83k
           strncasecmp(json_true_str, tok->pb->buf, size1) == 0) ||
912
3.22k
          (strncmp(json_true_str, tok->pb->buf, size1) == 0))
913
5.61k
      {
914
5.61k
        if (tok->st_pos == json_true_str_len)
915
1.09k
        {
916
1.09k
          current = json_object_new_boolean(1);
917
1.09k
          if (current == NULL)
918
0
          {
919
0
            tok->err = json_tokener_error_memory;
920
0
            goto out;
921
0
          }
922
1.09k
          saved_state = json_tokener_state_finish;
923
1.09k
          state = json_tokener_state_eatws;
924
1.09k
          goto redo_char;
925
1.09k
        }
926
5.61k
      }
927
3.22k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
928
3.22k
                strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
929
159
               (strncmp(json_false_str, tok->pb->buf, size2) == 0))
930
3.06k
      {
931
3.06k
        if (tok->st_pos == json_false_str_len)
932
485
        {
933
485
          current = json_object_new_boolean(0);
934
485
          if (current == NULL)
935
0
          {
936
0
            tok->err = json_tokener_error_memory;
937
0
            goto out;
938
0
          }
939
485
          saved_state = json_tokener_state_finish;
940
485
          state = json_tokener_state_eatws;
941
485
          goto redo_char;
942
485
        }
943
3.06k
      }
944
159
      else
945
159
      {
946
159
        tok->err = json_tokener_error_parse_boolean;
947
159
        goto out;
948
159
      }
949
7.09k
      tok->st_pos++;
950
7.09k
    }
951
0
    break;
952
953
150k
    case json_tokener_state_number:
954
150k
    {
955
      /* Advance until we change state */
956
150k
      const char *case_start = str;
957
150k
      int case_len = 0;
958
150k
      int is_exponent = 0;
959
150k
      int neg_sign_ok = 1;
960
150k
      int pos_sign_ok = 0;
961
150k
      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
422k
      while (c && ((c >= '0' && c <= '9') ||
986
159k
                   (!is_exponent && (c == 'e' || c == 'E')) ||
987
156k
                   (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') ||
988
150k
                   (!tok->is_double && c == '.')))
989
272k
      {
990
272k
        pos_sign_ok = neg_sign_ok = 0;
991
272k
        ++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
272k
        switch (c)
1000
272k
        {
1001
887
        case '.':
1002
887
          tok->is_double = 1;
1003
887
          pos_sign_ok = 1;
1004
887
          neg_sign_ok = 1;
1005
887
          break;
1006
1.78k
        case 'e': /* FALLTHRU */
1007
2.82k
        case 'E':
1008
2.82k
          is_exponent = 1;
1009
2.82k
          tok->is_double = 1;
1010
          /* the exponent part can begin with a negative sign */
1011
2.82k
          pos_sign_ok = neg_sign_ok = 1;
1012
2.82k
          break;
1013
268k
        default: break;
1014
272k
        }
1015
1016
272k
        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
272k
      }
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
150k
      if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
1031
3.53k
          c != 'I' && c != 'i' && !is_ws_char(c))
1032
267
      {
1033
267
        tok->err = json_tokener_error_parse_number;
1034
267
        goto out;
1035
267
      }
1036
149k
      if (case_len > 0)
1037
149k
        printbuf_memappend_checked(tok->pb, case_start, case_len);
1038
1039
      // Check for -Infinity
1040
149k
      if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
1041
435
      {
1042
435
        state = json_tokener_state_inf;
1043
435
        tok->st_pos = 0;
1044
435
        goto redo_char;
1045
435
      }
1046
149k
      if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
1047
3.11k
      {
1048
        /* Trim some chars off the end, to allow things
1049
           like "123e+" to parse ok. */
1050
7.33k
        while (printbuf_length(tok->pb) > 1)
1051
5.80k
        {
1052
5.80k
          char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1];
1053
5.80k
          if (last_char != 'e' && last_char != 'E' &&
1054
3.52k
              last_char != '-' && last_char != '+')
1055
1.57k
          {
1056
1.57k
            break;
1057
1.57k
          }
1058
4.22k
          tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0';
1059
4.22k
          printbuf_length(tok->pb)--;
1060
4.22k
        }
1061
3.11k
      }
1062
149k
    }
1063
0
      {
1064
149k
        int64_t num64;
1065
149k
        uint64_t numuint64;
1066
149k
        double numd;
1067
149k
        if (!tok->is_double && tok->pb->buf[0] == '-' &&
1068
2.36k
            json_parse_int64(tok->pb->buf, &num64) == 0)
1069
2.33k
        {
1070
2.33k
          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.33k
          current = json_object_new_int64(num64);
1076
2.33k
          if (current == NULL)
1077
0
          {
1078
0
            tok->err = json_tokener_error_memory;
1079
0
            goto out;
1080
0
          }
1081
2.33k
        }
1082
146k
        else if (!tok->is_double && tok->pb->buf[0] != '-' &&
1083
143k
                 json_parse_uint64(tok->pb->buf, &numuint64) == 0)
1084
143k
        {
1085
143k
          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
143k
          if (numuint64 && tok->pb->buf[0] == '0' &&
1091
3.04k
              (tok->flags & JSON_TOKENER_STRICT))
1092
0
          {
1093
0
            tok->err = json_tokener_error_parse_number;
1094
0
            goto out;
1095
0
          }
1096
143k
          if (numuint64 <= INT64_MAX)
1097
143k
          {
1098
143k
            num64 = (uint64_t)numuint64;
1099
143k
            current = json_object_new_int64(num64);
1100
143k
            if (current == NULL)
1101
0
            {
1102
0
              tok->err = json_tokener_error_memory;
1103
0
              goto out;
1104
0
            }
1105
143k
          }
1106
668
          else
1107
668
          {
1108
668
            current = json_object_new_uint64(numuint64);
1109
668
            if (current == NULL)
1110
0
            {
1111
0
              tok->err = json_tokener_error_memory;
1112
0
              goto out;
1113
0
            }
1114
668
          }
1115
143k
        }
1116
3.13k
        else if (tok->is_double &&
1117
3.11k
                 json_tokener_parse_double(
1118
3.11k
                     tok->pb->buf, printbuf_length(tok->pb), &numd) == 0)
1119
3.09k
        {
1120
3.09k
          current = json_object_new_double_s(numd, tok->pb->buf);
1121
3.09k
          if (current == NULL)
1122
0
          {
1123
0
            tok->err = json_tokener_error_memory;
1124
0
            goto out;
1125
0
          }
1126
3.09k
        }
1127
40
        else
1128
40
        {
1129
40
          tok->err = json_tokener_error_parse_number;
1130
40
          goto out;
1131
40
        }
1132
149k
        saved_state = json_tokener_state_finish;
1133
149k
        state = json_tokener_state_eatws;
1134
149k
        goto redo_char;
1135
149k
      }
1136
0
      break;
1137
1138
164k
    case json_tokener_state_array_after_sep:
1139
179k
    case json_tokener_state_array:
1140
179k
      if (c == ']')
1141
2.11k
      {
1142
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1143
2.11k
        json_object_array_shrink(current, 0);
1144
1145
2.11k
        if (state == json_tokener_state_array_after_sep &&
1146
687
            (tok->flags & JSON_TOKENER_STRICT))
1147
0
        {
1148
0
          tok->err = json_tokener_error_parse_unexpected;
1149
0
          goto out;
1150
0
        }
1151
2.11k
        saved_state = json_tokener_state_finish;
1152
2.11k
        state = json_tokener_state_eatws;
1153
2.11k
      }
1154
177k
      else
1155
177k
      {
1156
177k
        if (tok->depth >= tok->max_depth - 1)
1157
6
        {
1158
6
          tok->err = json_tokener_error_depth;
1159
6
          goto out;
1160
6
        }
1161
177k
        state = json_tokener_state_array_add;
1162
177k
        tok->depth++;
1163
177k
        json_tokener_reset_level(tok, tok->depth);
1164
177k
        goto redo_char;
1165
177k
      }
1166
2.11k
      break;
1167
1168
175k
    case json_tokener_state_array_add:
1169
175k
      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
175k
      saved_state = json_tokener_state_array_sep;
1175
175k
      state = json_tokener_state_eatws;
1176
175k
      goto redo_char;
1177
1178
175k
    case json_tokener_state_array_sep:
1179
175k
      if (c == ']')
1180
10.7k
      {
1181
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1182
10.7k
        json_object_array_shrink(current, 0);
1183
1184
10.7k
        saved_state = json_tokener_state_finish;
1185
10.7k
        state = json_tokener_state_eatws;
1186
10.7k
      }
1187
164k
      else if (c == ',')
1188
164k
      {
1189
164k
        saved_state = json_tokener_state_array_after_sep;
1190
164k
        state = json_tokener_state_eatws;
1191
164k
      }
1192
155
      else
1193
155
      {
1194
155
        tok->err = json_tokener_error_parse_array;
1195
155
        goto out;
1196
155
      }
1197
175k
      break;
1198
1199
175k
    case json_tokener_state_object_field_start:
1200
149k
    case json_tokener_state_object_field_start_after_sep:
1201
149k
      if (c == '}')
1202
21.1k
      {
1203
21.1k
        if (state == json_tokener_state_object_field_start_after_sep &&
1204
197
            (tok->flags & JSON_TOKENER_STRICT))
1205
0
        {
1206
0
          tok->err = json_tokener_error_parse_unexpected;
1207
0
          goto out;
1208
0
        }
1209
21.1k
        saved_state = json_tokener_state_finish;
1210
21.1k
        state = json_tokener_state_eatws;
1211
21.1k
      }
1212
128k
      else if (c == '"' || c == '\'')
1213
128k
      {
1214
128k
        tok->quote_char = c;
1215
128k
        printbuf_reset(tok->pb);
1216
128k
        state = json_tokener_state_object_field;
1217
128k
      }
1218
68
      else
1219
68
      {
1220
68
        tok->err = json_tokener_error_parse_object_key_name;
1221
68
        goto out;
1222
68
      }
1223
149k
      break;
1224
1225
149k
    case json_tokener_state_object_field:
1226
137k
    {
1227
      /* Advance until we change state */
1228
137k
      const char *case_start = str;
1229
2.00M
      while (1)
1230
2.00M
      {
1231
2.00M
        if (c == tok->quote_char)
1232
127k
        {
1233
127k
          printbuf_memappend_checked(tok->pb, case_start,
1234
127k
                                     str - case_start);
1235
127k
          obj_field_name = strdup(tok->pb->buf);
1236
127k
          if (obj_field_name == NULL)
1237
0
          {
1238
0
            tok->err = json_tokener_error_memory;
1239
0
            goto out;
1240
0
          }
1241
127k
          saved_state = json_tokener_state_object_field_end;
1242
127k
          state = json_tokener_state_eatws;
1243
127k
          break;
1244
127k
        }
1245
1.87M
        else if (c == '\\')
1246
9.69k
        {
1247
9.69k
          printbuf_memappend_checked(tok->pb, case_start,
1248
9.69k
                                     str - case_start);
1249
9.69k
          saved_state = json_tokener_state_object_field;
1250
9.69k
          state = json_tokener_state_string_escape;
1251
9.69k
          break;
1252
9.69k
        }
1253
1.87M
        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.87M
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
1260
181
        {
1261
181
          printbuf_memappend_checked(tok->pb, case_start,
1262
181
                                     str - case_start);
1263
181
          goto out;
1264
181
        }
1265
1.87M
      }
1266
137k
    }
1267
137k
    break;
1268
1269
137k
    case json_tokener_state_object_field_end:
1270
127k
      if (c == ':')
1271
127k
      {
1272
127k
        saved_state = json_tokener_state_object_value;
1273
127k
        state = json_tokener_state_eatws;
1274
127k
      }
1275
134
      else
1276
134
      {
1277
134
        tok->err = json_tokener_error_parse_object_key_sep;
1278
134
        goto out;
1279
134
      }
1280
127k
      break;
1281
1282
127k
    case json_tokener_state_object_value:
1283
127k
      if (tok->depth >= tok->max_depth - 1)
1284
3
      {
1285
3
        tok->err = json_tokener_error_depth;
1286
3
        goto out;
1287
3
      }
1288
127k
      state = json_tokener_state_object_value_add;
1289
127k
      tok->depth++;
1290
127k
      json_tokener_reset_level(tok, tok->depth);
1291
127k
      goto redo_char;
1292
1293
125k
    case json_tokener_state_object_value_add:
1294
125k
      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
125k
      free(obj_field_name);
1300
125k
      obj_field_name = NULL;
1301
125k
      saved_state = json_tokener_state_object_sep;
1302
125k
      state = json_tokener_state_eatws;
1303
125k
      goto redo_char;
1304
1305
125k
    case json_tokener_state_object_sep:
1306
      /* { */
1307
125k
      if (c == '}')
1308
33.5k
      {
1309
33.5k
        saved_state = json_tokener_state_finish;
1310
33.5k
        state = json_tokener_state_eatws;
1311
33.5k
      }
1312
92.1k
      else if (c == ',')
1313
91.8k
      {
1314
91.8k
        saved_state = json_tokener_state_object_field_start_after_sep;
1315
91.8k
        state = json_tokener_state_eatws;
1316
91.8k
      }
1317
274
      else
1318
274
      {
1319
274
        tok->err = json_tokener_error_parse_object_value_sep;
1320
274
        goto out;
1321
274
      }
1322
125k
      break;
1323
3.87M
    }
1324
1.11M
    (void)ADVANCE_CHAR(str, tok);
1325
1.11M
    if (!c) // This is the char *before* advancing
1326
8
      break;
1327
1.11M
  } /* while(PEEK_CHAR) */
1328
1329
10.2k
out:
1330
10.2k
  if ((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && (nBytes != 0))
1331
0
  {
1332
0
    tok->err = json_tokener_error_parse_utf8_string;
1333
0
  }
1334
10.2k
  if (c && (state == json_tokener_state_finish) && (tok->depth == 0) &&
1335
113
      (tok->flags & (JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS)) ==
1336
113
          JSON_TOKENER_STRICT)
1337
0
  {
1338
    /* unexpected char after JSON data */
1339
0
    tok->err = json_tokener_error_parse_unexpected;
1340
0
  }
1341
10.2k
  if (!c)
1342
8.66k
  {
1343
    /* We hit an eof char (0) */
1344
8.66k
    if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
1345
778
      tok->err = json_tokener_error_parse_eof;
1346
8.66k
  }
1347
1348
10.2k
#ifdef HAVE_USELOCALE
1349
10.2k
  uselocale(oldlocale);
1350
10.2k
  freelocale(newloc);
1351
#elif defined(HAVE_SETLOCALE)
1352
  setlocale(LC_NUMERIC, oldlocale);
1353
  free(oldlocale);
1354
#endif
1355
1356
10.2k
  if (tok->err == json_tokener_success)
1357
7.99k
  {
1358
7.99k
    json_object *ret = json_object_get(current);
1359
7.99k
    int ii;
1360
1361
    /* Partially reset, so we parse additional objects on subsequent calls. */
1362
16.3k
    for (ii = tok->depth; ii >= 0; ii--)
1363
8.38k
      json_tokener_reset_level(tok, ii);
1364
7.99k
    return ret;
1365
7.99k
  }
1366
1367
2.27k
  MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
1368
2.27k
           tok->char_offset);
1369
2.27k
  return NULL;
1370
10.2k
}
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.11k
{
1411
3.11k
  char *end;
1412
3.11k
  *retval = strtod(buf, &end);
1413
3.11k
  if (buf + len == end)
1414
3.09k
    return 0; // It worked
1415
15
  return 1;
1416
3.11k
}