Coverage Report

Created: 2025-10-12 06:56

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
22.4k
#define jt_hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x)&7) + 9)
48
49
#if !HAVE_STRNCASECMP && defined(_MSC_VER)
50
/* MSC has the version as _strnicmp */
51
#define strncasecmp _strnicmp
52
#elif !HAVE_STRNCASECMP
53
#error You do not have strncasecmp on your system.
54
#endif /* HAVE_STRNCASECMP */
55
56
#if defined(_MSC_VER) && (_MSC_VER <= 1800)
57
/* VS2013 doesn't know about "inline" */
58
#define inline __inline
59
#elif defined(AIX_CC)
60
#define inline
61
#endif
62
63
/* The following helper functions are used to speed up parsing. They
64
 * are faster than their ctype counterparts because they assume that
65
 * the input is in ASCII and that the locale is set to "C". The
66
 * compiler will also inline these functions, providing an additional
67
 * speedup by saving on function calls.
68
 */
69
static inline int is_ws_char(char c)
70
1.48M
{
71
1.48M
  return c == ' '
72
1.36M
      || c == '\t'
73
1.35M
      || c == '\n'
74
1.34M
      || c == '\r';
75
1.48M
}
76
77
static inline int is_hex_char(char c)
78
22.4k
{
79
22.4k
  return (c >= '0' && c <= '9')
80
9.03k
      || (c >= 'A' && c <= 'F')
81
1.84k
      || (c >= 'a' && c <= 'f');
82
22.4k
}
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.85k
{
134
1.85k
  int jerr_int = (int)jerr;
135
1.85k
  if (jerr_int < 0 ||
136
1.85k
      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.85k
  return json_tokener_errors[jerr];
140
1.85k
}
141
142
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok)
143
3.70k
{
144
3.70k
  return tok->err;
145
3.70k
}
146
147
/* Stuff for decoding unicode sequences */
148
3.61k
#define IS_HIGH_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xD800)
149
2.75k
#define IS_LOW_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xDC00)
150
516
#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
7.58k
{
155
7.58k
  struct json_tokener *tok;
156
157
7.58k
  if (depth < 1)
158
0
    return NULL;
159
160
7.58k
  tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
161
7.58k
  if (!tok)
162
0
    return NULL;
163
7.58k
  tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
164
7.58k
  if (!tok->stack)
165
0
  {
166
0
    free(tok);
167
0
    return NULL;
168
0
  }
169
7.58k
  tok->pb = printbuf_new();
170
7.58k
  if (!tok->pb)
171
0
  {
172
0
    free(tok->stack);
173
0
    free(tok);
174
0
    return NULL;
175
0
  }
176
7.58k
  tok->max_depth = depth;
177
7.58k
  json_tokener_reset(tok);
178
7.58k
  return tok;
179
7.58k
}
180
181
struct json_tokener *json_tokener_new(void)
182
7.58k
{
183
7.58k
  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
184
7.58k
}
185
186
void json_tokener_free(struct json_tokener *tok)
187
7.58k
{
188
7.58k
  if (!tok)
189
0
    return;
190
7.58k
  json_tokener_reset(tok);
191
7.58k
  if (tok->pb)
192
7.58k
    printbuf_free(tok->pb);
193
7.58k
  free(tok->stack);
194
7.58k
  free(tok);
195
7.58k
}
196
197
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
198
579k
{
199
579k
  tok->stack[depth].state = json_tokener_state_eatws;
200
579k
  tok->stack[depth].saved_state = json_tokener_state_start;
201
579k
  json_object_put(tok->stack[depth].current);
202
579k
  tok->stack[depth].current = NULL;
203
579k
  free(tok->stack[depth].obj_field_name);
204
579k
  tok->stack[depth].obj_field_name = NULL;
205
579k
}
206
207
void json_tokener_reset(struct json_tokener *tok)
208
15.1k
{
209
15.1k
  int i;
210
15.1k
  if (!tok)
211
0
    return;
212
213
33.6k
  for (i = tok->depth; i >= 0; i--)
214
18.4k
    json_tokener_reset_level(tok, i);
215
15.1k
  tok->depth = 0;
216
15.1k
  tok->err = json_tokener_success;
217
15.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.64M
#define state tok->stack[tok->depth].state
262
2.50M
#define saved_state tok->stack[tok->depth].saved_state
263
1.12M
#define current tok->stack[tok->depth].current
264
504k
#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.42M
  (((tok)->char_offset == len)                                         \
286
5.42M
       ? (((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.42M
       : (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) &&                \
291
5.42M
           (!json_tokener_validate_utf8(*str, nBytesp)))               \
292
5.42M
              ? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
293
5.42M
              : (((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.72M
#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
514k
  do {                                                  \
308
514k
    if (printbuf_memappend((p), (s), (l)) < 0)    \
309
514k
    {                                             \
310
0
      tok->err = json_tokener_error_memory; \
311
0
      goto out;                             \
312
0
    }                                             \
313
514k
  } 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
7.58k
{
319
7.58k
  struct json_object *obj = NULL;
320
7.58k
  char c = '\1';
321
7.58k
  unsigned int nBytes = 0;
322
7.58k
  unsigned int *nBytesp = &nBytes;
323
324
7.58k
#ifdef HAVE_USELOCALE
325
7.58k
  locale_t oldlocale = uselocale(NULL);
326
7.58k
  locale_t newloc;
327
#elif defined(HAVE_SETLOCALE)
328
  char *oldlocale = NULL;
329
#endif
330
331
7.58k
  tok->char_offset = 0;
332
7.58k
  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
7.58k
  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
7.58k
#ifdef HAVE_USELOCALE
347
7.58k
  {
348
7.58k
#ifdef HAVE_DUPLOCALE
349
7.58k
    locale_t duploc = duplocale(oldlocale);
350
7.58k
    if (duploc == NULL && errno == ENOMEM)
351
0
    {
352
0
      tok->err = json_tokener_error_memory;
353
0
      return NULL;
354
0
    }
355
7.58k
    newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
356
#else
357
    newloc = newlocale(LC_NUMERIC_MASK, "C", oldlocale);
358
#endif
359
7.58k
    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
7.58k
    uselocale(newloc);
375
7.58k
  }
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
963k
  while (PEEK_CHAR(c, tok)) // Note: c might be '\0' !
394
963k
  {
395
396
3.48M
  redo_char:
397
3.48M
    switch (state)
398
3.48M
    {
399
400
1.34M
    case json_tokener_state_eatws:
401
      /* Advance until we change state */
402
1.48M
      while (is_ws_char(c))
403
134k
      {
404
134k
        if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
405
0
          goto out;
406
134k
      }
407
1.34M
      if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
408
2.32k
      {
409
2.32k
        printbuf_reset(tok->pb);
410
2.32k
        printbuf_memappend_checked(tok->pb, &c, 1);
411
2.32k
        state = json_tokener_state_comment_start;
412
2.32k
      }
413
1.34M
      else
414
1.34M
      {
415
1.34M
        state = saved_state;
416
1.34M
        goto redo_char;
417
1.34M
      }
418
2.32k
      break;
419
420
286k
    case json_tokener_state_start:
421
286k
      switch (c)
422
286k
      {
423
41.7k
      case '{':
424
41.7k
        state = json_tokener_state_eatws;
425
41.7k
        saved_state = json_tokener_state_object_field_start;
426
41.7k
        current = json_object_new_object();
427
41.7k
        if (current == NULL)
428
0
        {
429
0
          tok->err = json_tokener_error_memory;
430
0
          goto out;
431
0
        }
432
41.7k
        break;
433
41.7k
      case '[':
434
11.5k
        state = json_tokener_state_eatws;
435
11.5k
        saved_state = json_tokener_state_array;
436
11.5k
        current = json_object_new_array();
437
11.5k
        if (current == NULL)
438
0
        {
439
0
          tok->err = json_tokener_error_memory;
440
0
          goto out;
441
0
        }
442
11.5k
        break;
443
11.5k
      case 'I':
444
554
      case 'i':
445
554
        state = json_tokener_state_inf;
446
554
        printbuf_reset(tok->pb);
447
554
        tok->st_pos = 0;
448
554
        goto redo_char;
449
1.08k
      case 'N':
450
15.3k
      case 'n':
451
15.3k
        state = json_tokener_state_null; // or NaN
452
15.3k
        printbuf_reset(tok->pb);
453
15.3k
        tok->st_pos = 0;
454
15.3k
        goto redo_char;
455
472
      case '\'':
456
472
        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
58.6k
      case '"':
464
58.6k
        state = json_tokener_state_string;
465
58.6k
        printbuf_reset(tok->pb);
466
58.6k
        tok->quote_char = c;
467
58.6k
        break;
468
661
      case 'T':
469
1.34k
      case 't':
470
1.47k
      case 'F':
471
1.87k
      case 'f':
472
1.87k
        state = json_tokener_state_boolean;
473
1.87k
        printbuf_reset(tok->pb);
474
1.87k
        tok->st_pos = 0;
475
1.87k
        goto redo_char;
476
17.6k
      case '0':
477
23.4k
      case '1':
478
28.5k
      case '2':
479
31.3k
      case '3':
480
34.4k
      case '4':
481
150k
      case '5':
482
151k
      case '6':
483
152k
      case '7':
484
152k
      case '8':
485
153k
      case '9':
486
156k
      case '-':
487
156k
        state = json_tokener_state_number;
488
156k
        printbuf_reset(tok->pb);
489
156k
        tok->is_double = 0;
490
156k
        goto redo_char;
491
97
      default: tok->err = json_tokener_error_parse_unexpected; goto out;
492
286k
      }
493
112k
      break;
494
495
281k
    case json_tokener_state_finish:
496
281k
      if (tok->depth == 0)
497
5.65k
        goto out;
498
275k
      obj = json_object_get(current);
499
275k
      json_tokener_reset_level(tok, tok->depth);
500
275k
      tok->depth--;
501
275k
      goto redo_char;
502
503
974
    case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
504
974
    {
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
974
      int is_negative = 0;
513
514
      /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
515
8.24k
      while (tok->st_pos < (int)json_inf_str_len)
516
7.35k
      {
517
7.35k
        char inf_char = *str;
518
7.35k
        if (inf_char != json_inf_str[tok->st_pos] &&
519
3.25k
            ((tok->flags & JSON_TOKENER_STRICT) ||
520
3.25k
              inf_char != json_inf_str_invert[tok->st_pos])
521
7.35k
           )
522
88
        {
523
88
          tok->err = json_tokener_error_parse_unexpected;
524
88
          goto out;
525
88
        }
526
7.27k
        tok->st_pos++;
527
7.27k
        (void)ADVANCE_CHAR(str, tok);
528
7.27k
        if (!PEEK_CHAR(c, tok))
529
0
        {
530
          /* out of input chars, for now at least */
531
0
          goto out;
532
0
        }
533
7.27k
      }
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
886
      if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
539
395
      {
540
395
        is_negative = 1;
541
395
      }
542
886
      current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
543
886
      if (current == NULL)
544
0
      {
545
0
        tok->err = json_tokener_error_memory;
546
0
        goto out;
547
0
      }
548
886
      saved_state = json_tokener_state_finish;
549
886
      state = json_tokener_state_eatws;
550
886
      goto redo_char;
551
886
    }
552
0
    break;
553
76.0k
    case json_tokener_state_null: /* aka starts with 'n' */
554
76.0k
    {
555
76.0k
      int size;
556
76.0k
      int size_nan;
557
76.0k
      printbuf_memappend_checked(tok->pb, &c, 1);
558
76.0k
      size = json_min(tok->st_pos + 1, json_null_str_len);
559
76.0k
      size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
560
76.0k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
561
76.0k
           strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
562
1.56k
          (strncmp(json_null_str, tok->pb->buf, size) == 0))
563
74.4k
      {
564
74.4k
        if (tok->st_pos == json_null_str_len)
565
14.7k
        {
566
14.7k
          current = NULL;
567
14.7k
          saved_state = json_tokener_state_finish;
568
14.7k
          state = json_tokener_state_eatws;
569
14.7k
          goto redo_char;
570
14.7k
        }
571
74.4k
      }
572
1.56k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
573
1.56k
                strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
574
93
               (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
575
1.47k
      {
576
1.47k
        if (tok->st_pos == json_nan_str_len)
577
483
        {
578
483
          current = json_object_new_double(NAN);
579
483
          if (current == NULL)
580
0
          {
581
0
            tok->err = json_tokener_error_memory;
582
0
            goto out;
583
0
          }
584
483
          saved_state = json_tokener_state_finish;
585
483
          state = json_tokener_state_eatws;
586
483
          goto redo_char;
587
483
        }
588
1.47k
      }
589
93
      else
590
93
      {
591
93
        tok->err = json_tokener_error_parse_null;
592
93
        goto out;
593
93
      }
594
60.6k
      tok->st_pos++;
595
60.6k
    }
596
0
    break;
597
598
2.32k
    case json_tokener_state_comment_start:
599
2.32k
      if (c == '*')
600
600
      {
601
600
        state = json_tokener_state_comment;
602
600
      }
603
1.72k
      else if (c == '/')
604
1.66k
      {
605
1.66k
        state = json_tokener_state_comment_eol;
606
1.66k
      }
607
55
      else
608
55
      {
609
55
        tok->err = json_tokener_error_parse_comment;
610
55
        goto out;
611
55
      }
612
2.26k
      printbuf_memappend_checked(tok->pb, &c, 1);
613
2.26k
      break;
614
615
2.93k
    case json_tokener_state_comment:
616
2.93k
    {
617
      /* Advance until we change state */
618
2.93k
      const char *case_start = str;
619
525k
      while (c != '*')
620
522k
      {
621
522k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
622
139
        {
623
139
          printbuf_memappend_checked(tok->pb, case_start,
624
139
                                     str - case_start);
625
139
          goto out;
626
139
        }
627
522k
      }
628
2.79k
      printbuf_memappend_checked(tok->pb, case_start, 1 + str - case_start);
629
2.79k
      state = json_tokener_state_comment_end;
630
2.79k
    }
631
0
    break;
632
633
1.66k
    case json_tokener_state_comment_eol:
634
1.66k
    {
635
      /* Advance until we change state */
636
1.66k
      const char *case_start = str;
637
244k
      while (c != '\n')
638
243k
      {
639
243k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
640
112
        {
641
112
          printbuf_memappend_checked(tok->pb, case_start,
642
112
                                     str - case_start);
643
112
          goto out;
644
112
        }
645
243k
      }
646
1.55k
      printbuf_memappend_checked(tok->pb, case_start, str - case_start);
647
1.55k
      MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
648
1.55k
      state = json_tokener_state_eatws;
649
1.55k
    }
650
0
    break;
651
652
2.79k
    case json_tokener_state_comment_end:
653
2.79k
      printbuf_memappend_checked(tok->pb, &c, 1);
654
2.79k
      if (c == '/')
655
454
      {
656
454
        MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
657
454
        state = json_tokener_state_eatws;
658
454
      }
659
2.34k
      else
660
2.34k
      {
661
2.34k
        state = json_tokener_state_comment;
662
2.34k
      }
663
2.79k
      break;
664
665
97.9k
    case json_tokener_state_string:
666
97.9k
    {
667
      /* Advance until we change state */
668
97.9k
      const char *case_start = str;
669
1.80M
      while (1)
670
1.80M
      {
671
1.80M
        if (c == tok->quote_char)
672
58.4k
        {
673
58.4k
          printbuf_memappend_checked(tok->pb, case_start,
674
58.4k
                                     str - case_start);
675
58.4k
          current =
676
58.4k
              json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
677
58.4k
          if (current == NULL)
678
0
          {
679
0
            tok->err = json_tokener_error_memory;
680
0
            goto out;
681
0
          }
682
58.4k
          saved_state = json_tokener_state_finish;
683
58.4k
          state = json_tokener_state_eatws;
684
58.4k
          break;
685
58.4k
        }
686
1.74M
        else if (c == '\\')
687
39.3k
        {
688
39.3k
          printbuf_memappend_checked(tok->pb, case_start,
689
39.3k
                                     str - case_start);
690
39.3k
          saved_state = json_tokener_state_string;
691
39.3k
          state = json_tokener_state_string_escape;
692
39.3k
          break;
693
39.3k
        }
694
1.70M
        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.70M
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
701
194
        {
702
194
          printbuf_memappend_checked(tok->pb, case_start,
703
194
                                     str - case_start);
704
194
          goto out;
705
194
        }
706
1.70M
      }
707
97.9k
    }
708
97.7k
    break;
709
710
97.7k
    case json_tokener_state_string_escape:
711
49.8k
      switch (c)
712
49.8k
      {
713
8.49k
      case '"':
714
27.5k
      case '\\':
715
28.0k
      case '/':
716
28.0k
        printbuf_memappend_checked(tok->pb, &c, 1);
717
28.0k
        state = saved_state;
718
28.0k
        break;
719
767
      case 'b':
720
15.1k
      case 'n':
721
15.7k
      case 'r':
722
16.7k
      case 't':
723
17.2k
      case 'f':
724
17.2k
        if (c == 'b')
725
767
          printbuf_memappend_checked(tok->pb, "\b", 1);
726
16.4k
        else if (c == 'n')
727
14.3k
          printbuf_memappend_checked(tok->pb, "\n", 1);
728
2.10k
        else if (c == 'r')
729
558
          printbuf_memappend_checked(tok->pb, "\r", 1);
730
1.54k
        else if (c == 't')
731
1.06k
          printbuf_memappend_checked(tok->pb, "\t", 1);
732
479
        else if (c == 'f')
733
479
          printbuf_memappend_checked(tok->pb, "\f", 1);
734
17.2k
        state = saved_state;
735
17.2k
        break;
736
4.60k
      case 'u':
737
4.60k
        tok->ucs_char = 0;
738
4.60k
        tok->st_pos = 0;
739
4.60k
        state = json_tokener_state_escape_unicode;
740
4.60k
        break;
741
36
      default: tok->err = json_tokener_error_parse_string; goto out;
742
49.8k
      }
743
49.8k
      break;
744
745
      // ===================================================
746
747
49.8k
    case json_tokener_state_escape_unicode:
748
5.66k
    {
749
      /* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */
750
22.4k
      while (1)
751
22.4k
      {
752
22.4k
        if (!c || !is_hex_char(c))
753
73
        {
754
73
          tok->err = json_tokener_error_parse_string;
755
73
          goto out;
756
73
        }
757
22.4k
        tok->ucs_char |=
758
22.4k
            ((unsigned int)jt_hexdigit(c) << ((3 - tok->st_pos) * 4));
759
22.4k
        tok->st_pos++;
760
22.4k
        if (tok->st_pos >= 4)
761
5.58k
          break;
762
763
16.8k
        (void)ADVANCE_CHAR(str, tok);
764
16.8k
        if (!PEEK_CHAR(c, tok))
765
0
        {
766
          /*
767
           * We're out of characters in the current call to
768
           * json_tokener_parse(), but a subsequent call might
769
           * provide us with more, so leave our current state
770
           * as-is (including tok->high_surrogate) and return.
771
           */
772
0
          goto out;
773
0
        }
774
16.8k
      }
775
5.58k
      tok->st_pos = 0;
776
777
      /* Now, we have a full \uNNNN sequence in tok->ucs_char */
778
779
      /* If the *previous* sequence was a high surrogate ... */
780
5.58k
      if (tok->high_surrogate)
781
1.04k
      {
782
1.04k
        if (IS_LOW_SURROGATE(tok->ucs_char))
783
516
        {
784
          /* Recalculate the ucs_char, then fall thru to process normally */
785
516
          tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate,
786
516
                                                tok->ucs_char);
787
516
        }
788
532
        else
789
532
        {
790
          /* High surrogate was not followed by a low surrogate
791
           * Replace the high and process the rest normally
792
           */
793
532
          printbuf_memappend_checked(tok->pb,
794
532
                                     (char *)utf8_replacement_char, 3);
795
532
        }
796
1.04k
        tok->high_surrogate = 0;
797
1.04k
      }
798
799
5.58k
      if (tok->ucs_char < 0x80)
800
1.05k
      {
801
1.05k
        unsigned char unescaped_utf[1];
802
1.05k
        unescaped_utf[0] = tok->ucs_char;
803
1.05k
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 1);
804
1.05k
      }
805
4.53k
      else if (tok->ucs_char < 0x800)
806
914
      {
807
914
        unsigned char unescaped_utf[2];
808
914
        unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
809
914
        unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
810
914
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 2);
811
914
      }
812
3.61k
      else if (IS_HIGH_SURROGATE(tok->ucs_char))
813
1.90k
      {
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.90k
        tok->high_surrogate = tok->ucs_char;
829
1.90k
        tok->ucs_char = 0;
830
1.90k
        state = json_tokener_state_escape_unicode_need_escape;
831
1.90k
        break;
832
1.90k
      }
833
1.71k
      else if (IS_LOW_SURROGATE(tok->ucs_char))
834
573
      {
835
        /* Got a low surrogate not preceded by a high */
836
573
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
837
573
      }
838
1.13k
      else if (tok->ucs_char < 0x10000)
839
621
      {
840
621
        unsigned char unescaped_utf[3];
841
621
        unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
842
621
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
843
621
        unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
844
621
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 3);
845
621
      }
846
516
      else if (tok->ucs_char < 0x110000)
847
516
      {
848
516
        unsigned char unescaped_utf[4];
849
516
        unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
850
516
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
851
516
        unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
852
516
        unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
853
516
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 4);
854
516
      }
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.67k
      state = saved_state; // i.e. _state_string or _state_object_field
861
3.67k
    }
862
0
    break;
863
864
1.90k
    case json_tokener_state_escape_unicode_need_escape:
865
      // We get here after processing a high_surrogate
866
      // require a '\\' char
867
1.90k
      if (!c || c != '\\')
868
518
      {
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
518
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
874
518
        tok->high_surrogate = 0;
875
518
        tok->ucs_char = 0;
876
518
        tok->st_pos = 0;
877
518
        state = saved_state;
878
518
        goto redo_char;
879
518
      }
880
1.39k
      state = json_tokener_state_escape_unicode_need_u;
881
1.39k
      break;
882
883
1.39k
    case json_tokener_state_escape_unicode_need_u:
884
      /* We already had a \ char, check that it's \u */
885
1.39k
      if (!c || c != 'u')
886
332
      {
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
332
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
893
332
        tok->high_surrogate = 0;
894
332
        tok->ucs_char = 0;
895
332
        tok->st_pos = 0;
896
332
        state = json_tokener_state_string_escape;
897
332
        goto redo_char;
898
332
      }
899
1.05k
      state = json_tokener_state_escape_unicode;
900
1.05k
      break;
901
902
      // ===================================================
903
904
9.60k
    case json_tokener_state_boolean:
905
9.60k
    {
906
9.60k
      int size1, size2;
907
9.60k
      printbuf_memappend_checked(tok->pb, &c, 1);
908
9.60k
      size1 = json_min(tok->st_pos + 1, json_true_str_len);
909
9.60k
      size2 = json_min(tok->st_pos + 1, json_false_str_len);
910
9.60k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
911
9.60k
           strncasecmp(json_true_str, tok->pb->buf, size1) == 0) ||
912
3.15k
          (strncmp(json_true_str, tok->pb->buf, size1) == 0))
913
6.45k
      {
914
6.45k
        if (tok->st_pos == json_true_str_len)
915
1.26k
        {
916
1.26k
          current = json_object_new_boolean(1);
917
1.26k
          if (current == NULL)
918
0
          {
919
0
            tok->err = json_tokener_error_memory;
920
0
            goto out;
921
0
          }
922
1.26k
          saved_state = json_tokener_state_finish;
923
1.26k
          state = json_tokener_state_eatws;
924
1.26k
          goto redo_char;
925
1.26k
        }
926
6.45k
      }
927
3.15k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
928
3.15k
                strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
929
128
               (strncmp(json_false_str, tok->pb->buf, size2) == 0))
930
3.02k
      {
931
3.02k
        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.02k
      }
944
128
      else
945
128
      {
946
128
        tok->err = json_tokener_error_parse_boolean;
947
128
        goto out;
948
128
      }
949
7.72k
      tok->st_pos++;
950
7.72k
    }
951
0
    break;
952
953
156k
    case json_tokener_state_number:
954
156k
    {
955
      /* Advance until we change state */
956
156k
      const char *case_start = str;
957
156k
      int case_len = 0;
958
156k
      int is_exponent = 0;
959
156k
      int neg_sign_ok = 1;
960
156k
      int pos_sign_ok = 0;
961
156k
      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
428k
      while (c && ((c >= '0' && c <= '9') ||
986
164k
                   (!is_exponent && (c == 'e' || c == 'E')) ||
987
161k
                   (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') ||
988
157k
                   (!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
667
        case '.':
1002
667
          tok->is_double = 1;
1003
667
          pos_sign_ok = 1;
1004
667
          neg_sign_ok = 1;
1005
667
          break;
1006
1.27k
        case 'e': /* FALLTHRU */
1007
2.58k
        case 'E':
1008
2.58k
          is_exponent = 1;
1009
2.58k
          tok->is_double = 1;
1010
          /* the exponent part can begin with a negative sign */
1011
2.58k
          pos_sign_ok = neg_sign_ok = 1;
1012
2.58k
          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
156k
      if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
1031
4.16k
          c != 'I' && c != 'i' && !is_ws_char(c))
1032
212
      {
1033
212
        tok->err = json_tokener_error_parse_number;
1034
212
        goto out;
1035
212
      }
1036
156k
      if (case_len > 0)
1037
156k
        printbuf_memappend_checked(tok->pb, case_start, case_len);
1038
1039
      // Check for -Infinity
1040
156k
      if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
1041
420
      {
1042
420
        state = json_tokener_state_inf;
1043
420
        tok->st_pos = 0;
1044
420
        goto redo_char;
1045
420
      }
1046
156k
      if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
1047
2.86k
      {
1048
        /* Trim some chars off the end, to allow things
1049
           like "123e+" to parse ok. */
1050
6.57k
        while (printbuf_length(tok->pb) > 1)
1051
4.93k
        {
1052
4.93k
          char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1];
1053
4.93k
          if (last_char != 'e' && last_char != 'E' &&
1054
2.77k
              last_char != '-' && last_char != '+')
1055
1.22k
          {
1056
1.22k
            break;
1057
1.22k
          }
1058
3.70k
          tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0';
1059
3.70k
          printbuf_length(tok->pb)--;
1060
3.70k
        }
1061
2.86k
      }
1062
156k
    }
1063
0
      {
1064
156k
        int64_t num64;
1065
156k
        uint64_t numuint64;
1066
156k
        double numd;
1067
156k
        if (!tok->is_double && tok->pb->buf[0] == '-' &&
1068
2.17k
            json_parse_int64(tok->pb->buf, &num64) == 0)
1069
2.15k
        {
1070
2.15k
          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.15k
          current = json_object_new_int64(num64);
1076
2.15k
          if (current == NULL)
1077
0
          {
1078
0
            tok->err = json_tokener_error_memory;
1079
0
            goto out;
1080
0
          }
1081
2.15k
        }
1082
153k
        else if (!tok->is_double && tok->pb->buf[0] != '-' &&
1083
151k
                 json_parse_uint64(tok->pb->buf, &numuint64) == 0)
1084
151k
        {
1085
151k
          if (errno == ERANGE && (tok->flags & JSON_TOKENER_STRICT))
1086
0
          {
1087
0
            tok->err = json_tokener_error_parse_number;
1088
0
            goto out;
1089
0
          }
1090
151k
          if (numuint64 && tok->pb->buf[0] == '0' &&
1091
2.37k
              (tok->flags & JSON_TOKENER_STRICT))
1092
0
          {
1093
0
            tok->err = json_tokener_error_parse_number;
1094
0
            goto out;
1095
0
          }
1096
151k
          if (numuint64 <= INT64_MAX)
1097
150k
          {
1098
150k
            num64 = (uint64_t)numuint64;
1099
150k
            current = json_object_new_int64(num64);
1100
150k
            if (current == NULL)
1101
0
            {
1102
0
              tok->err = json_tokener_error_memory;
1103
0
              goto out;
1104
0
            }
1105
150k
          }
1106
889
          else
1107
889
          {
1108
889
            current = json_object_new_uint64(numuint64);
1109
889
            if (current == NULL)
1110
0
            {
1111
0
              tok->err = json_tokener_error_memory;
1112
0
              goto out;
1113
0
            }
1114
889
          }
1115
151k
        }
1116
2.88k
        else if (tok->is_double &&
1117
2.86k
                 json_tokener_parse_double(
1118
2.86k
                     tok->pb->buf, printbuf_length(tok->pb), &numd) == 0)
1119
2.85k
        {
1120
2.85k
          current = json_object_new_double_s(numd, tok->pb->buf);
1121
2.85k
          if (current == NULL)
1122
0
          {
1123
0
            tok->err = json_tokener_error_memory;
1124
0
            goto out;
1125
0
          }
1126
2.85k
        }
1127
34
        else
1128
34
        {
1129
34
          tok->err = json_tokener_error_parse_number;
1130
34
          goto out;
1131
34
        }
1132
156k
        saved_state = json_tokener_state_finish;
1133
156k
        state = json_tokener_state_eatws;
1134
156k
        goto redo_char;
1135
156k
      }
1136
0
      break;
1137
1138
167k
    case json_tokener_state_array_after_sep:
1139
179k
    case json_tokener_state_array:
1140
179k
      if (c == ']')
1141
1.63k
      {
1142
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1143
1.63k
        json_object_array_shrink(current, 0);
1144
1145
1.63k
        if (state == json_tokener_state_array_after_sep &&
1146
555
            (tok->flags & JSON_TOKENER_STRICT))
1147
0
        {
1148
0
          tok->err = json_tokener_error_parse_unexpected;
1149
0
          goto out;
1150
0
        }
1151
1.63k
        saved_state = json_tokener_state_finish;
1152
1.63k
        state = json_tokener_state_eatws;
1153
1.63k
      }
1154
177k
      else
1155
177k
      {
1156
177k
        if (tok->depth >= tok->max_depth - 1)
1157
7
        {
1158
7
          tok->err = json_tokener_error_depth;
1159
7
          goto out;
1160
7
        }
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
1.63k
      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
8.18k
      {
1181
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1182
8.18k
        json_object_array_shrink(current, 0);
1183
1184
8.18k
        saved_state = json_tokener_state_finish;
1185
8.18k
        state = json_tokener_state_eatws;
1186
8.18k
      }
1187
167k
      else if (c == ',')
1188
167k
      {
1189
167k
        saved_state = json_tokener_state_array_after_sep;
1190
167k
        state = json_tokener_state_eatws;
1191
167k
      }
1192
130
      else
1193
130
      {
1194
130
        tok->err = json_tokener_error_parse_array;
1195
130
        goto out;
1196
130
      }
1197
175k
      break;
1198
1199
175k
    case json_tokener_state_object_field_start:
1200
116k
    case json_tokener_state_object_field_start_after_sep:
1201
116k
      if (c == '}')
1202
14.6k
      {
1203
14.6k
        if (state == json_tokener_state_object_field_start_after_sep &&
1204
205
            (tok->flags & JSON_TOKENER_STRICT))
1205
0
        {
1206
0
          tok->err = json_tokener_error_parse_unexpected;
1207
0
          goto out;
1208
0
        }
1209
14.6k
        saved_state = json_tokener_state_finish;
1210
14.6k
        state = json_tokener_state_eatws;
1211
14.6k
      }
1212
102k
      else if (c == '"' || c == '\'')
1213
102k
      {
1214
102k
        tok->quote_char = c;
1215
102k
        printbuf_reset(tok->pb);
1216
102k
        state = json_tokener_state_object_field;
1217
102k
      }
1218
60
      else
1219
60
      {
1220
60
        tok->err = json_tokener_error_parse_object_key_name;
1221
60
        goto out;
1222
60
      }
1223
116k
      break;
1224
1225
116k
    case json_tokener_state_object_field:
1226
112k
    {
1227
      /* Advance until we change state */
1228
112k
      const char *case_start = str;
1229
1.67M
      while (1)
1230
1.67M
      {
1231
1.67M
        if (c == tok->quote_char)
1232
101k
        {
1233
101k
          printbuf_memappend_checked(tok->pb, case_start,
1234
101k
                                     str - case_start);
1235
101k
          obj_field_name = strdup(tok->pb->buf);
1236
101k
          if (obj_field_name == NULL)
1237
0
          {
1238
0
            tok->err = json_tokener_error_memory;
1239
0
            goto out;
1240
0
          }
1241
101k
          saved_state = json_tokener_state_object_field_end;
1242
101k
          state = json_tokener_state_eatws;
1243
101k
          break;
1244
101k
        }
1245
1.57M
        else if (c == '\\')
1246
10.2k
        {
1247
10.2k
          printbuf_memappend_checked(tok->pb, case_start,
1248
10.2k
                                     str - case_start);
1249
10.2k
          saved_state = json_tokener_state_object_field;
1250
10.2k
          state = json_tokener_state_string_escape;
1251
10.2k
          break;
1252
10.2k
        }
1253
1.56M
        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.56M
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
1260
157
        {
1261
157
          printbuf_memappend_checked(tok->pb, case_start,
1262
157
                                     str - case_start);
1263
157
          goto out;
1264
157
        }
1265
1.56M
      }
1266
112k
    }
1267
112k
    break;
1268
1269
112k
    case json_tokener_state_object_field_end:
1270
101k
      if (c == ':')
1271
101k
      {
1272
101k
        saved_state = json_tokener_state_object_value;
1273
101k
        state = json_tokener_state_eatws;
1274
101k
      }
1275
95
      else
1276
95
      {
1277
95
        tok->err = json_tokener_error_parse_object_key_sep;
1278
95
        goto out;
1279
95
      }
1280
101k
      break;
1281
1282
101k
    case json_tokener_state_object_value:
1283
101k
      if (tok->depth >= tok->max_depth - 1)
1284
4
      {
1285
4
        tok->err = json_tokener_error_depth;
1286
4
        goto out;
1287
4
      }
1288
101k
      state = json_tokener_state_object_value_add;
1289
101k
      tok->depth++;
1290
101k
      json_tokener_reset_level(tok, tok->depth);
1291
101k
      goto redo_char;
1292
1293
100k
    case json_tokener_state_object_value_add:
1294
100k
      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
100k
      free(obj_field_name);
1300
100k
      obj_field_name = NULL;
1301
100k
      saved_state = json_tokener_state_object_sep;
1302
100k
      state = json_tokener_state_eatws;
1303
100k
      goto redo_char;
1304
1305
100k
    case json_tokener_state_object_sep:
1306
      /* { */
1307
100k
      if (c == '}')
1308
24.7k
      {
1309
24.7k
        saved_state = json_tokener_state_finish;
1310
24.7k
        state = json_tokener_state_eatws;
1311
24.7k
      }
1312
75.3k
      else if (c == ',')
1313
75.0k
      {
1314
75.0k
        saved_state = json_tokener_state_object_field_start_after_sep;
1315
75.0k
        state = json_tokener_state_eatws;
1316
75.0k
      }
1317
217
      else
1318
217
      {
1319
217
        tok->err = json_tokener_error_parse_object_value_sep;
1320
217
        goto out;
1321
217
      }
1322
99.8k
      break;
1323
3.48M
    }
1324
955k
    (void)ADVANCE_CHAR(str, tok);
1325
955k
    if (!c) // This is the char *before* advancing
1326
7
      break;
1327
955k
  } /* while(PEEK_CHAR) */
1328
1329
7.58k
out:
1330
7.58k
  if ((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && (nBytes != 0))
1331
0
  {
1332
0
    tok->err = json_tokener_error_parse_utf8_string;
1333
0
  }
1334
7.58k
  if (c && (state == json_tokener_state_finish) && (tok->depth == 0) &&
1335
93
      (tok->flags & (JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS)) ==
1336
93
          JSON_TOKENER_STRICT)
1337
0
  {
1338
    /* unexpected char after JSON data */
1339
0
    tok->err = json_tokener_error_parse_unexpected;
1340
0
  }
1341
7.58k
  if (!c)
1342
6.26k
  {
1343
    /* We hit an eof char (0) */
1344
6.26k
    if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
1345
608
      tok->err = json_tokener_error_parse_eof;
1346
6.26k
  }
1347
1348
7.58k
#ifdef HAVE_USELOCALE
1349
7.58k
  uselocale(oldlocale);
1350
7.58k
  freelocale(newloc);
1351
#elif defined(HAVE_SETLOCALE)
1352
  setlocale(LC_NUMERIC, oldlocale);
1353
  free(oldlocale);
1354
#endif
1355
1356
7.58k
  if (tok->err == json_tokener_success)
1357
5.74k
  {
1358
5.74k
    json_object *ret = json_object_get(current);
1359
5.74k
    int ii;
1360
1361
    /* Partially reset, so we parse additional objects on subsequent calls. */
1362
11.8k
    for (ii = tok->depth; ii >= 0; ii--)
1363
6.12k
      json_tokener_reset_level(tok, ii);
1364
5.74k
    return ret;
1365
5.74k
  }
1366
1367
1.84k
  MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
1368
1.84k
           tok->char_offset);
1369
1.84k
  return NULL;
1370
7.58k
}
1371
1372
static json_bool json_tokener_validate_utf8(const char c, unsigned int *nBytes)
1373
0
{
1374
0
  unsigned char chr = c;
1375
0
  if (*nBytes == 0)
1376
0
  {
1377
0
    if (chr >= 0x80)
1378
0
    {
1379
0
      if ((chr & 0xe0) == 0xc0)
1380
0
        *nBytes = 1;
1381
0
      else if ((chr & 0xf0) == 0xe0)
1382
0
        *nBytes = 2;
1383
0
      else if ((chr & 0xf8) == 0xf0)
1384
0
        *nBytes = 3;
1385
0
      else
1386
0
        return 0;
1387
0
    }
1388
0
  }
1389
0
  else
1390
0
  {
1391
0
    if ((chr & 0xC0) != 0x80)
1392
0
      return 0;
1393
0
    (*nBytes)--;
1394
0
  }
1395
0
  return 1;
1396
0
}
1397
1398
void json_tokener_set_flags(struct json_tokener *tok, int flags)
1399
0
{
1400
0
  tok->flags = flags;
1401
0
}
1402
1403
size_t json_tokener_get_parse_end(struct json_tokener *tok)
1404
0
{
1405
0
  assert(tok->char_offset >= 0); /* Drop this line when char_offset becomes a size_t */
1406
0
  return (size_t)tok->char_offset;
1407
0
}
1408
1409
static int json_tokener_parse_double(const char *buf, int len, double *retval)
1410
2.86k
{
1411
2.86k
  char *end;
1412
2.86k
  *retval = strtod(buf, &end);
1413
2.86k
  if (buf + len == end)
1414
2.85k
    return 0; // It worked
1415
14
  return 1;
1416
2.86k
}