Coverage Report

Created: 2025-12-14 06:36

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
18.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.61M
{
71
1.61M
  return c == ' '
72
1.48M
      || c == '\t'
73
1.46M
      || c == '\n'
74
1.45M
      || c == '\r';
75
1.61M
}
76
77
static inline int is_hex_char(char c)
78
18.8k
{
79
18.8k
  return (c >= '0' && c <= '9')
80
7.83k
      || (c >= 'A' && c <= 'F')
81
1.69k
      || (c >= 'a' && c <= 'f');
82
18.8k
}
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.28k
{
134
2.28k
  int jerr_int = (int)jerr;
135
2.28k
  if (jerr_int < 0 ||
136
2.28k
      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.28k
  return json_tokener_errors[jerr];
140
2.28k
}
141
142
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok)
143
4.56k
{
144
4.56k
  return tok->err;
145
4.56k
}
146
147
/* Stuff for decoding unicode sequences */
148
3.33k
#define IS_HIGH_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xD800)
149
2.57k
#define IS_LOW_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xDC00)
150
474
#define DECODE_SURROGATE_PAIR(hi, lo) ((((hi)&0x3FF) << 10) + ((lo)&0x3FF) + 0x10000)
151
static unsigned char utf8_replacement_char[3] = {0xEF, 0xBF, 0xBD};
152
153
struct json_tokener *json_tokener_new_ex(int depth)
154
9.89k
{
155
9.89k
  struct json_tokener *tok;
156
157
9.89k
  if (depth < 1)
158
0
    return NULL;
159
160
9.89k
  tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
161
9.89k
  if (!tok)
162
0
    return NULL;
163
9.89k
  tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
164
9.89k
  if (!tok->stack)
165
0
  {
166
0
    free(tok);
167
0
    return NULL;
168
0
  }
169
9.89k
  tok->pb = printbuf_new();
170
9.89k
  if (!tok->pb)
171
0
  {
172
0
    free(tok->stack);
173
0
    free(tok);
174
0
    return NULL;
175
0
  }
176
9.89k
  tok->max_depth = depth;
177
9.89k
  json_tokener_reset(tok);
178
9.89k
  return tok;
179
9.89k
}
180
181
struct json_tokener *json_tokener_new(void)
182
9.89k
{
183
9.89k
  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
184
9.89k
}
185
186
void json_tokener_free(struct json_tokener *tok)
187
9.89k
{
188
9.89k
  if (!tok)
189
0
    return;
190
9.89k
  json_tokener_reset(tok);
191
9.89k
  if (tok->pb)
192
9.89k
    printbuf_free(tok->pb);
193
9.89k
  free(tok->stack);
194
9.89k
  free(tok);
195
9.89k
}
196
197
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
198
617k
{
199
617k
  tok->stack[depth].state = json_tokener_state_eatws;
200
617k
  tok->stack[depth].saved_state = json_tokener_state_start;
201
617k
  json_object_put(tok->stack[depth].current);
202
617k
  tok->stack[depth].current = NULL;
203
617k
  free(tok->stack[depth].obj_field_name);
204
617k
  tok->stack[depth].obj_field_name = NULL;
205
617k
}
206
207
void json_tokener_reset(struct json_tokener *tok)
208
19.7k
{
209
19.7k
  int i;
210
19.7k
  if (!tok)
211
0
    return;
212
213
43.4k
  for (i = tok->depth; i >= 0; i--)
214
23.6k
    json_tokener_reset_level(tok, i);
215
19.7k
  tok->depth = 0;
216
19.7k
  tok->err = json_tokener_success;
217
19.7k
}
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.13M
#define state tok->stack[tok->depth].state
262
2.69M
#define saved_state tok->stack[tok->depth].saved_state
263
1.19M
#define current tok->stack[tok->depth].current
264
600k
#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.73M
  (((tok)->char_offset == len)                                         \
286
5.73M
       ? (((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.73M
       : (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) &&                \
291
5.73M
           (!json_tokener_validate_utf8(*str, nBytesp)))               \
292
5.73M
              ? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
293
5.73M
              : (((dest) = *str), 1)))
294
295
/* ADVANCE_CHAR() macro:
296
 *   Increments str & tok->char_offset.
297
 *   For convenience of existing conditionals, returns the old value of c (0 on eof).
298
 *   Implicit inputs:  c var
299
 */
300
10.2M
#define ADVANCE_CHAR(str, tok) (++(str), ((tok)->char_offset)++, c)
301
302
/* printbuf_memappend_checked(p, s, l) macro:
303
 *   Add string s of length l to printbuffer p.
304
 *   If operation fails abort parse operation with memory error.
305
 */
306
#define printbuf_memappend_checked(p, s, l)                   \
307
526k
  do {                                                  \
308
526k
    if (printbuf_memappend((p), (s), (l)) < 0)    \
309
526k
    {                                             \
310
0
      tok->err = json_tokener_error_memory; \
311
0
      goto out;                             \
312
0
    }                                             \
313
526k
  } while (0)
314
315
/* End optimization macro defs */
316
317
struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *str, int len)
318
9.89k
{
319
9.89k
  struct json_object *obj = NULL;
320
9.89k
  char c = '\1';
321
9.89k
  unsigned int nBytes = 0;
322
9.89k
  unsigned int *nBytesp = &nBytes;
323
324
9.89k
#ifdef HAVE_USELOCALE
325
9.89k
  locale_t oldlocale = uselocale(NULL);
326
9.89k
  locale_t newloc;
327
#elif defined(HAVE_SETLOCALE)
328
  char *oldlocale = NULL;
329
#endif
330
331
9.89k
  tok->char_offset = 0;
332
9.89k
  tok->err = json_tokener_success;
333
334
  /* this interface is presently not 64-bit clean due to the int len argument
335
   * and the internal printbuf interface that takes 32-bit int len arguments
336
   * so the function limits the maximum string size to INT32_MAX (2GB).
337
   * If the function is called with len == -1 then strlen is called to check
338
   * the string length is less than INT32_MAX (2GB)
339
   */
340
9.89k
  if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX))
341
0
  {
342
0
    tok->err = json_tokener_error_size;
343
0
    return NULL;
344
0
  }
345
346
9.89k
#ifdef HAVE_USELOCALE
347
9.89k
  {
348
9.89k
#ifdef HAVE_DUPLOCALE
349
9.89k
    locale_t duploc = duplocale(oldlocale);
350
9.89k
    if (duploc == NULL && errno == ENOMEM)
351
0
    {
352
0
      tok->err = json_tokener_error_memory;
353
0
      return NULL;
354
0
    }
355
9.89k
    newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
356
#else
357
    newloc = newlocale(LC_NUMERIC_MASK, "C", oldlocale);
358
#endif
359
9.89k
    if (newloc == NULL)
360
0
    {
361
0
      tok->err = json_tokener_error_memory;
362
0
#ifdef HAVE_DUPLOCALE
363
0
      freelocale(duploc);
364
0
#endif
365
0
      return NULL;
366
0
    }
367
#ifdef NEWLOCALE_NEEDS_FREELOCALE
368
#ifdef HAVE_DUPLOCALE
369
    // Older versions of FreeBSD (<12.4) don't free the locale
370
    // passed to newlocale(), so do it here
371
    freelocale(duploc);
372
#endif
373
#endif
374
9.89k
    uselocale(newloc);
375
9.89k
  }
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.07M
  while (PEEK_CHAR(c, tok)) // Note: c might be '\0' !
394
1.07M
  {
395
396
3.73M
  redo_char:
397
3.73M
    switch (state)
398
3.73M
    {
399
400
1.45M
    case json_tokener_state_eatws:
401
      /* Advance until we change state */
402
1.60M
      while (is_ws_char(c))
403
151k
      {
404
151k
        if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
405
0
          goto out;
406
151k
      }
407
1.45M
      if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
408
2.47k
      {
409
2.47k
        printbuf_reset(tok->pb);
410
2.47k
        printbuf_memappend_checked(tok->pb, &c, 1);
411
2.47k
        state = json_tokener_state_comment_start;
412
2.47k
      }
413
1.45M
      else
414
1.45M
      {
415
1.45M
        state = saved_state;
416
1.45M
        goto redo_char;
417
1.45M
      }
418
2.47k
      break;
419
420
304k
    case json_tokener_state_start:
421
304k
      switch (c)
422
304k
      {
423
54.4k
      case '{':
424
54.4k
        state = json_tokener_state_eatws;
425
54.4k
        saved_state = json_tokener_state_object_field_start;
426
54.4k
        current = json_object_new_object();
427
54.4k
        if (current == NULL)
428
0
        {
429
0
          tok->err = json_tokener_error_memory;
430
0
          goto out;
431
0
        }
432
54.4k
        break;
433
54.4k
      case '[':
434
14.4k
        state = json_tokener_state_eatws;
435
14.4k
        saved_state = json_tokener_state_array;
436
14.4k
        current = json_object_new_array();
437
14.4k
        if (current == NULL)
438
0
        {
439
0
          tok->err = json_tokener_error_memory;
440
0
          goto out;
441
0
        }
442
14.4k
        break;
443
14.4k
      case 'I':
444
502
      case 'i':
445
502
        state = json_tokener_state_inf;
446
502
        printbuf_reset(tok->pb);
447
502
        tok->st_pos = 0;
448
502
        goto redo_char;
449
1.00k
      case 'N':
450
14.4k
      case 'n':
451
14.4k
        state = json_tokener_state_null; // or NaN
452
14.4k
        printbuf_reset(tok->pb);
453
14.4k
        tok->st_pos = 0;
454
14.4k
        goto redo_char;
455
516
      case '\'':
456
516
        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
70.2k
      case '"':
464
70.2k
        state = json_tokener_state_string;
465
70.2k
        printbuf_reset(tok->pb);
466
70.2k
        tok->quote_char = c;
467
70.2k
        break;
468
690
      case 'T':
469
1.19k
      case 't':
470
1.33k
      case 'F':
471
1.75k
      case 'f':
472
1.75k
        state = json_tokener_state_boolean;
473
1.75k
        printbuf_reset(tok->pb);
474
1.75k
        tok->st_pos = 0;
475
1.75k
        goto redo_char;
476
23.2k
      case '0':
477
30.7k
      case '1':
478
34.6k
      case '2':
479
36.1k
      case '3':
480
38.4k
      case '4':
481
141k
      case '5':
482
142k
      case '6':
483
143k
      case '7':
484
144k
      case '8':
485
145k
      case '9':
486
148k
      case '-':
487
148k
        state = json_tokener_state_number;
488
148k
        printbuf_reset(tok->pb);
489
148k
        tok->is_double = 0;
490
148k
        goto redo_char;
491
140
      default: tok->err = json_tokener_error_parse_unexpected; goto out;
492
304k
      }
493
139k
      break;
494
495
298k
    case json_tokener_state_finish:
496
298k
      if (tok->depth == 0)
497
7.53k
        goto out;
498
291k
      obj = json_object_get(current);
499
291k
      json_tokener_reset_level(tok, tok->depth);
500
291k
      tok->depth--;
501
291k
      goto redo_char;
502
503
1.00k
    case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
504
1.00k
    {
505
      /* If we were guaranteed to have len set, then we could (usually) handle
506
       * the entire "Infinity" check in a single strncmp (strncasecmp), but
507
       * since len might be -1 (i.e. "read until \0"), we need to check it
508
       * a character at a time.
509
       * Trying to handle it both ways would make this code considerably more
510
       * complicated with likely little performance benefit.
511
       */
512
1.00k
      int is_negative = 0;
513
514
      /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
515
8.41k
      while (tok->st_pos < (int)json_inf_str_len)
516
7.50k
      {
517
7.50k
        char inf_char = *str;
518
7.50k
        if (inf_char != json_inf_str[tok->st_pos] &&
519
3.27k
            ((tok->flags & JSON_TOKENER_STRICT) ||
520
3.27k
              inf_char != json_inf_str_invert[tok->st_pos])
521
7.50k
           )
522
98
        {
523
98
          tok->err = json_tokener_error_parse_unexpected;
524
98
          goto out;
525
98
        }
526
7.41k
        tok->st_pos++;
527
7.41k
        (void)ADVANCE_CHAR(str, tok);
528
7.41k
        if (!PEEK_CHAR(c, tok))
529
0
        {
530
          /* out of input chars, for now at least */
531
0
          goto out;
532
0
        }
533
7.41k
      }
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
903
      if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
539
474
      {
540
474
        is_negative = 1;
541
474
      }
542
903
      current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
543
903
      if (current == NULL)
544
0
      {
545
0
        tok->err = json_tokener_error_memory;
546
0
        goto out;
547
0
      }
548
903
      saved_state = json_tokener_state_finish;
549
903
      state = json_tokener_state_eatws;
550
903
      goto redo_char;
551
903
    }
552
0
    break;
553
71.6k
    case json_tokener_state_null: /* aka starts with 'n' */
554
71.6k
    {
555
71.6k
      int size;
556
71.6k
      int size_nan;
557
71.6k
      printbuf_memappend_checked(tok->pb, &c, 1);
558
71.6k
      size = json_min(tok->st_pos + 1, json_null_str_len);
559
71.6k
      size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
560
71.6k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
561
71.6k
           strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
562
1.48k
          (strncmp(json_null_str, tok->pb->buf, size) == 0))
563
70.1k
      {
564
70.1k
        if (tok->st_pos == json_null_str_len)
565
13.9k
        {
566
13.9k
          current = NULL;
567
13.9k
          saved_state = json_tokener_state_finish;
568
13.9k
          state = json_tokener_state_eatws;
569
13.9k
          goto redo_char;
570
13.9k
        }
571
70.1k
      }
572
1.48k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
573
1.48k
                strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
574
102
               (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
575
1.38k
      {
576
1.38k
        if (tok->st_pos == json_nan_str_len)
577
452
        {
578
452
          current = json_object_new_double(NAN);
579
452
          if (current == NULL)
580
0
          {
581
0
            tok->err = json_tokener_error_memory;
582
0
            goto out;
583
0
          }
584
452
          saved_state = json_tokener_state_finish;
585
452
          state = json_tokener_state_eatws;
586
452
          goto redo_char;
587
452
        }
588
1.38k
      }
589
102
      else
590
102
      {
591
102
        tok->err = json_tokener_error_parse_null;
592
102
        goto out;
593
102
      }
594
57.1k
      tok->st_pos++;
595
57.1k
    }
596
0
    break;
597
598
2.47k
    case json_tokener_state_comment_start:
599
2.47k
      if (c == '*')
600
692
      {
601
692
        state = json_tokener_state_comment;
602
692
      }
603
1.78k
      else if (c == '/')
604
1.71k
      {
605
1.71k
        state = json_tokener_state_comment_eol;
606
1.71k
      }
607
72
      else
608
72
      {
609
72
        tok->err = json_tokener_error_parse_comment;
610
72
        goto out;
611
72
      }
612
2.40k
      printbuf_memappend_checked(tok->pb, &c, 1);
613
2.40k
      break;
614
615
3.41k
    case json_tokener_state_comment:
616
3.41k
    {
617
      /* Advance until we change state */
618
3.41k
      const char *case_start = str;
619
567k
      while (c != '*')
620
563k
      {
621
563k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
622
170
        {
623
170
          printbuf_memappend_checked(tok->pb, case_start,
624
170
                                     str - case_start);
625
170
          goto out;
626
170
        }
627
563k
      }
628
3.24k
      printbuf_memappend_checked(tok->pb, case_start, 1 + str - case_start);
629
3.24k
      state = json_tokener_state_comment_end;
630
3.24k
    }
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
181k
      while (c != '\n')
638
179k
      {
639
179k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
640
129
        {
641
129
          printbuf_memappend_checked(tok->pb, case_start,
642
129
                                     str - case_start);
643
129
          goto out;
644
129
        }
645
179k
      }
646
1.58k
      printbuf_memappend_checked(tok->pb, case_start, str - case_start);
647
1.58k
      MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
648
1.58k
      state = json_tokener_state_eatws;
649
1.58k
    }
650
0
    break;
651
652
3.24k
    case json_tokener_state_comment_end:
653
3.24k
      printbuf_memappend_checked(tok->pb, &c, 1);
654
3.24k
      if (c == '/')
655
515
      {
656
515
        MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
657
515
        state = json_tokener_state_eatws;
658
515
      }
659
2.72k
      else
660
2.72k
      {
661
2.72k
        state = json_tokener_state_comment;
662
2.72k
      }
663
3.24k
      break;
664
665
105k
    case json_tokener_state_string:
666
105k
    {
667
      /* Advance until we change state */
668
105k
      const char *case_start = str;
669
1.84M
      while (1)
670
1.84M
      {
671
1.84M
        if (c == tok->quote_char)
672
69.9k
        {
673
69.9k
          printbuf_memappend_checked(tok->pb, case_start,
674
69.9k
                                     str - case_start);
675
69.9k
          current =
676
69.9k
              json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
677
69.9k
          if (current == NULL)
678
0
          {
679
0
            tok->err = json_tokener_error_memory;
680
0
            goto out;
681
0
          }
682
69.9k
          saved_state = json_tokener_state_finish;
683
69.9k
          state = json_tokener_state_eatws;
684
69.9k
          break;
685
69.9k
        }
686
1.77M
        else if (c == '\\')
687
35.5k
        {
688
35.5k
          printbuf_memappend_checked(tok->pb, case_start,
689
35.5k
                                     str - case_start);
690
35.5k
          saved_state = json_tokener_state_string;
691
35.5k
          state = json_tokener_state_string_escape;
692
35.5k
          break;
693
35.5k
        }
694
1.73M
        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.73M
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
701
262
        {
702
262
          printbuf_memappend_checked(tok->pb, case_start,
703
262
                                     str - case_start);
704
262
          goto out;
705
262
        }
706
1.73M
      }
707
105k
    }
708
105k
    break;
709
710
105k
    case json_tokener_state_string_escape:
711
45.9k
      switch (c)
712
45.9k
      {
713
7.67k
      case '"':
714
26.0k
      case '\\':
715
26.3k
      case '/':
716
26.3k
        printbuf_memappend_checked(tok->pb, &c, 1);
717
26.3k
        state = saved_state;
718
26.3k
        break;
719
804
      case 'b':
720
13.9k
      case 'n':
721
14.4k
      case 'r':
722
15.3k
      case 't':
723
15.8k
      case 'f':
724
15.8k
        if (c == 'b')
725
804
          printbuf_memappend_checked(tok->pb, "\b", 1);
726
15.0k
        else if (c == 'n')
727
13.1k
          printbuf_memappend_checked(tok->pb, "\n", 1);
728
1.98k
        else if (c == 'r')
729
546
          printbuf_memappend_checked(tok->pb, "\r", 1);
730
1.43k
        else if (c == 't')
731
921
          printbuf_memappend_checked(tok->pb, "\t", 1);
732
513
        else if (c == 'f')
733
513
          printbuf_memappend_checked(tok->pb, "\f", 1);
734
15.8k
        state = saved_state;
735
15.8k
        break;
736
3.65k
      case 'u':
737
3.65k
        tok->ucs_char = 0;
738
3.65k
        tok->st_pos = 0;
739
3.65k
        state = json_tokener_state_escape_unicode;
740
3.65k
        break;
741
47
      default: tok->err = json_tokener_error_parse_string; goto out;
742
45.9k
      }
743
45.8k
      break;
744
745
      // ===================================================
746
747
45.8k
    case json_tokener_state_escape_unicode:
748
4.75k
    {
749
      /* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */
750
18.9k
      while (1)
751
18.9k
      {
752
18.9k
        if (!c || !is_hex_char(c))
753
74
        {
754
74
          tok->err = json_tokener_error_parse_string;
755
74
          goto out;
756
74
        }
757
18.8k
        tok->ucs_char |=
758
18.8k
            ((unsigned int)jt_hexdigit(c) << ((3 - tok->st_pos) * 4));
759
18.8k
        tok->st_pos++;
760
18.8k
        if (tok->st_pos >= 4)
761
4.68k
          break;
762
763
14.1k
        (void)ADVANCE_CHAR(str, tok);
764
14.1k
        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.1k
      }
775
4.68k
      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.68k
      if (tok->high_surrogate)
781
1.10k
      {
782
1.10k
        if (IS_LOW_SURROGATE(tok->ucs_char))
783
474
        {
784
          /* Recalculate the ucs_char, then fall thru to process normally */
785
474
          tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate,
786
474
                                                tok->ucs_char);
787
474
        }
788
626
        else
789
626
        {
790
          /* High surrogate was not followed by a low surrogate
791
           * Replace the high and process the rest normally
792
           */
793
626
          printbuf_memappend_checked(tok->pb,
794
626
                                     (char *)utf8_replacement_char, 3);
795
626
        }
796
1.10k
        tok->high_surrogate = 0;
797
1.10k
      }
798
799
4.68k
      if (tok->ucs_char < 0x80)
800
965
      {
801
965
        unsigned char unescaped_utf[1];
802
965
        unescaped_utf[0] = tok->ucs_char;
803
965
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 1);
804
965
      }
805
3.72k
      else if (tok->ucs_char < 0x800)
806
381
      {
807
381
        unsigned char unescaped_utf[2];
808
381
        unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
809
381
        unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
810
381
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 2);
811
381
      }
812
3.33k
      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.47k
      else if (IS_LOW_SURROGATE(tok->ucs_char))
834
426
      {
835
        /* Got a low surrogate not preceded by a high */
836
426
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
837
426
      }
838
1.04k
      else if (tok->ucs_char < 0x10000)
839
571
      {
840
571
        unsigned char unescaped_utf[3];
841
571
        unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
842
571
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
843
571
        unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
844
571
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 3);
845
571
      }
846
474
      else if (tok->ucs_char < 0x110000)
847
474
      {
848
474
        unsigned char unescaped_utf[4];
849
474
        unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
850
474
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
851
474
        unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
852
474
        unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
853
474
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 4);
854
474
      }
855
0
      else
856
0
      {
857
        /* Don't know what we got--insert the replacement char */
858
0
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
859
0
      }
860
2.81k
      state = saved_state; // i.e. _state_string or _state_object_field
861
2.81k
    }
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
437
      {
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
437
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
874
437
        tok->high_surrogate = 0;
875
437
        tok->ucs_char = 0;
876
437
        tok->st_pos = 0;
877
437
        state = saved_state;
878
437
        goto redo_char;
879
437
      }
880
1.43k
      state = json_tokener_state_escape_unicode_need_u;
881
1.43k
      break;
882
883
1.43k
    case json_tokener_state_escape_unicode_need_u:
884
      /* We already had a \ char, check that it's \u */
885
1.43k
      if (!c || c != 'u')
886
323
      {
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
323
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
893
323
        tok->high_surrogate = 0;
894
323
        tok->ucs_char = 0;
895
323
        tok->st_pos = 0;
896
323
        state = json_tokener_state_string_escape;
897
323
        goto redo_char;
898
323
      }
899
1.10k
      state = json_tokener_state_escape_unicode;
900
1.10k
      break;
901
902
      // ===================================================
903
904
8.92k
    case json_tokener_state_boolean:
905
8.92k
    {
906
8.92k
      int size1, size2;
907
8.92k
      printbuf_memappend_checked(tok->pb, &c, 1);
908
8.92k
      size1 = json_min(tok->st_pos + 1, json_true_str_len);
909
8.92k
      size2 = json_min(tok->st_pos + 1, json_false_str_len);
910
8.92k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
911
8.92k
           strncasecmp(json_true_str, tok->pb->buf, size1) == 0) ||
912
3.21k
          (strncmp(json_true_str, tok->pb->buf, size1) == 0))
913
5.70k
      {
914
5.70k
        if (tok->st_pos == json_true_str_len)
915
1.11k
        {
916
1.11k
          current = json_object_new_boolean(1);
917
1.11k
          if (current == NULL)
918
0
          {
919
0
            tok->err = json_tokener_error_memory;
920
0
            goto out;
921
0
          }
922
1.11k
          saved_state = json_tokener_state_finish;
923
1.11k
          state = json_tokener_state_eatws;
924
1.11k
          goto redo_char;
925
1.11k
        }
926
5.70k
      }
927
3.21k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
928
3.21k
                strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
929
149
               (strncmp(json_false_str, tok->pb->buf, size2) == 0))
930
3.06k
      {
931
3.06k
        if (tok->st_pos == json_false_str_len)
932
487
        {
933
487
          current = json_object_new_boolean(0);
934
487
          if (current == NULL)
935
0
          {
936
0
            tok->err = json_tokener_error_memory;
937
0
            goto out;
938
0
          }
939
487
          saved_state = json_tokener_state_finish;
940
487
          state = json_tokener_state_eatws;
941
487
          goto redo_char;
942
487
        }
943
3.06k
      }
944
149
      else
945
149
      {
946
149
        tok->err = json_tokener_error_parse_boolean;
947
149
        goto out;
948
149
      }
949
7.17k
      tok->st_pos++;
950
7.17k
    }
951
0
    break;
952
953
148k
    case json_tokener_state_number:
954
148k
    {
955
      /* Advance until we change state */
956
148k
      const char *case_start = str;
957
148k
      int case_len = 0;
958
148k
      int is_exponent = 0;
959
148k
      int neg_sign_ok = 1;
960
148k
      int pos_sign_ok = 0;
961
148k
      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
413k
      while (c && ((c >= '0' && c <= '9') ||
986
157k
                   (!is_exponent && (c == 'e' || c == 'E')) ||
987
154k
                   (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') ||
988
149k
                   (!tok->is_double && c == '.')))
989
264k
      {
990
264k
        pos_sign_ok = neg_sign_ok = 0;
991
264k
        ++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
264k
        switch (c)
1000
264k
        {
1001
768
        case '.':
1002
768
          tok->is_double = 1;
1003
768
          pos_sign_ok = 1;
1004
768
          neg_sign_ok = 1;
1005
768
          break;
1006
1.69k
        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
261k
        default: break;
1014
264k
        }
1015
1016
264k
        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
264k
      }
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
148k
      if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
1031
3.24k
          c != 'I' && c != 'i' && !is_ws_char(c))
1032
262
      {
1033
262
        tok->err = json_tokener_error_parse_number;
1034
262
        goto out;
1035
262
      }
1036
148k
      if (case_len > 0)
1037
148k
        printbuf_memappend_checked(tok->pb, case_start, case_len);
1038
1039
      // Check for -Infinity
1040
148k
      if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
1041
499
      {
1042
499
        state = json_tokener_state_inf;
1043
499
        tok->st_pos = 0;
1044
499
        goto redo_char;
1045
499
      }
1046
148k
      if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
1047
3.10k
      {
1048
        /* Trim some chars off the end, to allow things
1049
           like "123e+" to parse ok. */
1050
7.09k
        while (printbuf_length(tok->pb) > 1)
1051
5.55k
        {
1052
5.55k
          char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1];
1053
5.55k
          if (last_char != 'e' && last_char != 'E' &&
1054
3.38k
              last_char != '-' && last_char != '+')
1055
1.56k
          {
1056
1.56k
            break;
1057
1.56k
          }
1058
3.98k
          tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0';
1059
3.98k
          printbuf_length(tok->pb)--;
1060
3.98k
        }
1061
3.10k
      }
1062
148k
    }
1063
0
      {
1064
148k
        int64_t num64;
1065
148k
        uint64_t numuint64;
1066
148k
        double numd;
1067
148k
        if (!tok->is_double && tok->pb->buf[0] == '-' &&
1068
2.24k
            json_parse_int64(tok->pb->buf, &num64) == 0)
1069
2.22k
        {
1070
2.22k
          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.22k
          current = json_object_new_int64(num64);
1076
2.22k
          if (current == NULL)
1077
0
          {
1078
0
            tok->err = json_tokener_error_memory;
1079
0
            goto out;
1080
0
          }
1081
2.22k
        }
1082
145k
        else if (!tok->is_double && tok->pb->buf[0] != '-' &&
1083
142k
                 json_parse_uint64(tok->pb->buf, &numuint64) == 0)
1084
142k
        {
1085
142k
          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
142k
          if (numuint64 && tok->pb->buf[0] == '0' &&
1091
2.62k
              (tok->flags & JSON_TOKENER_STRICT))
1092
0
          {
1093
0
            tok->err = json_tokener_error_parse_number;
1094
0
            goto out;
1095
0
          }
1096
142k
          if (numuint64 <= INT64_MAX)
1097
142k
          {
1098
142k
            num64 = (uint64_t)numuint64;
1099
142k
            current = json_object_new_int64(num64);
1100
142k
            if (current == NULL)
1101
0
            {
1102
0
              tok->err = json_tokener_error_memory;
1103
0
              goto out;
1104
0
            }
1105
142k
          }
1106
655
          else
1107
655
          {
1108
655
            current = json_object_new_uint64(numuint64);
1109
655
            if (current == NULL)
1110
0
            {
1111
0
              tok->err = json_tokener_error_memory;
1112
0
              goto out;
1113
0
            }
1114
655
          }
1115
142k
        }
1116
3.12k
        else if (tok->is_double &&
1117
3.10k
                 json_tokener_parse_double(
1118
3.10k
                     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
36
        else
1128
36
        {
1129
36
          tok->err = json_tokener_error_parse_number;
1130
36
          goto out;
1131
36
        }
1132
148k
        saved_state = json_tokener_state_finish;
1133
148k
        state = json_tokener_state_eatws;
1134
148k
        goto redo_char;
1135
148k
      }
1136
0
      break;
1137
1138
161k
    case json_tokener_state_array_after_sep:
1139
176k
    case json_tokener_state_array:
1140
176k
      if (c == ']')
1141
2.08k
      {
1142
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1143
2.08k
        json_object_array_shrink(current, 0);
1144
1145
2.08k
        if (state == json_tokener_state_array_after_sep &&
1146
680
            (tok->flags & JSON_TOKENER_STRICT))
1147
0
        {
1148
0
          tok->err = json_tokener_error_parse_unexpected;
1149
0
          goto out;
1150
0
        }
1151
2.08k
        saved_state = json_tokener_state_finish;
1152
2.08k
        state = json_tokener_state_eatws;
1153
2.08k
      }
1154
174k
      else
1155
174k
      {
1156
174k
        if (tok->depth >= tok->max_depth - 1)
1157
8
        {
1158
8
          tok->err = json_tokener_error_depth;
1159
8
          goto out;
1160
8
        }
1161
174k
        state = json_tokener_state_array_add;
1162
174k
        tok->depth++;
1163
174k
        json_tokener_reset_level(tok, tok->depth);
1164
174k
        goto redo_char;
1165
174k
      }
1166
2.08k
      break;
1167
1168
171k
    case json_tokener_state_array_add:
1169
171k
      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
171k
      saved_state = json_tokener_state_array_sep;
1175
171k
      state = json_tokener_state_eatws;
1176
171k
      goto redo_char;
1177
1178
171k
    case json_tokener_state_array_sep:
1179
171k
      if (c == ']')
1180
10.0k
      {
1181
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1182
10.0k
        json_object_array_shrink(current, 0);
1183
1184
10.0k
        saved_state = json_tokener_state_finish;
1185
10.0k
        state = json_tokener_state_eatws;
1186
10.0k
      }
1187
161k
      else if (c == ',')
1188
161k
      {
1189
161k
        saved_state = json_tokener_state_array_after_sep;
1190
161k
        state = json_tokener_state_eatws;
1191
161k
      }
1192
146
      else
1193
146
      {
1194
146
        tok->err = json_tokener_error_parse_array;
1195
146
        goto out;
1196
146
      }
1197
171k
      break;
1198
1199
171k
    case json_tokener_state_object_field_start:
1200
141k
    case json_tokener_state_object_field_start_after_sep:
1201
141k
      if (c == '}')
1202
19.9k
      {
1203
19.9k
        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
19.9k
        saved_state = json_tokener_state_finish;
1210
19.9k
        state = json_tokener_state_eatws;
1211
19.9k
      }
1212
121k
      else if (c == '"' || c == '\'')
1213
121k
      {
1214
121k
        tok->quote_char = c;
1215
121k
        printbuf_reset(tok->pb);
1216
121k
        state = json_tokener_state_object_field;
1217
121k
      }
1218
74
      else
1219
74
      {
1220
74
        tok->err = json_tokener_error_parse_object_key_name;
1221
74
        goto out;
1222
74
      }
1223
141k
      break;
1224
1225
141k
    case json_tokener_state_object_field:
1226
131k
    {
1227
      /* Advance until we change state */
1228
131k
      const char *case_start = str;
1229
1.87M
      while (1)
1230
1.87M
      {
1231
1.87M
        if (c == tok->quote_char)
1232
121k
        {
1233
121k
          printbuf_memappend_checked(tok->pb, case_start,
1234
121k
                                     str - case_start);
1235
121k
          obj_field_name = strdup(tok->pb->buf);
1236
121k
          if (obj_field_name == NULL)
1237
0
          {
1238
0
            tok->err = json_tokener_error_memory;
1239
0
            goto out;
1240
0
          }
1241
121k
          saved_state = json_tokener_state_object_field_end;
1242
121k
          state = json_tokener_state_eatws;
1243
121k
          break;
1244
121k
        }
1245
1.75M
        else if (c == '\\')
1246
10.0k
        {
1247
10.0k
          printbuf_memappend_checked(tok->pb, case_start,
1248
10.0k
                                     str - case_start);
1249
10.0k
          saved_state = json_tokener_state_object_field;
1250
10.0k
          state = json_tokener_state_string_escape;
1251
10.0k
          break;
1252
10.0k
        }
1253
1.74M
        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.74M
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
1260
186
        {
1261
186
          printbuf_memappend_checked(tok->pb, case_start,
1262
186
                                     str - case_start);
1263
186
          goto out;
1264
186
        }
1265
1.74M
      }
1266
131k
    }
1267
131k
    break;
1268
1269
131k
    case json_tokener_state_object_field_end:
1270
121k
      if (c == ':')
1271
121k
      {
1272
121k
        saved_state = json_tokener_state_object_value;
1273
121k
        state = json_tokener_state_eatws;
1274
121k
      }
1275
133
      else
1276
133
      {
1277
133
        tok->err = json_tokener_error_parse_object_key_sep;
1278
133
        goto out;
1279
133
      }
1280
121k
      break;
1281
1282
121k
    case json_tokener_state_object_value:
1283
121k
      if (tok->depth >= tok->max_depth - 1)
1284
3
      {
1285
3
        tok->err = json_tokener_error_depth;
1286
3
        goto out;
1287
3
      }
1288
121k
      state = json_tokener_state_object_value_add;
1289
121k
      tok->depth++;
1290
121k
      json_tokener_reset_level(tok, tok->depth);
1291
121k
      goto redo_char;
1292
1293
119k
    case json_tokener_state_object_value_add:
1294
119k
      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
119k
      free(obj_field_name);
1300
119k
      obj_field_name = NULL;
1301
119k
      saved_state = json_tokener_state_object_sep;
1302
119k
      state = json_tokener_state_eatws;
1303
119k
      goto redo_char;
1304
1305
119k
    case json_tokener_state_object_sep:
1306
      /* { */
1307
119k
      if (c == '}')
1308
31.7k
      {
1309
31.7k
        saved_state = json_tokener_state_finish;
1310
31.7k
        state = json_tokener_state_eatws;
1311
31.7k
      }
1312
87.5k
      else if (c == ',')
1313
87.2k
      {
1314
87.2k
        saved_state = json_tokener_state_object_field_start_after_sep;
1315
87.2k
        state = json_tokener_state_eatws;
1316
87.2k
      }
1317
263
      else
1318
263
      {
1319
263
        tok->err = json_tokener_error_parse_object_value_sep;
1320
263
        goto out;
1321
263
      }
1322
118k
      break;
1323
3.73M
    }
1324
1.06M
    (void)ADVANCE_CHAR(str, tok);
1325
1.06M
    if (!c) // This is the char *before* advancing
1326
7
      break;
1327
1.06M
  } /* while(PEEK_CHAR) */
1328
1329
9.89k
out:
1330
9.89k
  if ((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && (nBytes != 0))
1331
0
  {
1332
0
    tok->err = json_tokener_error_parse_utf8_string;
1333
0
  }
1334
9.89k
  if (c && (state == json_tokener_state_finish) && (tok->depth == 0) &&
1335
114
      (tok->flags & (JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS)) ==
1336
114
          JSON_TOKENER_STRICT)
1337
0
  {
1338
    /* unexpected char after JSON data */
1339
0
    tok->err = json_tokener_error_parse_unexpected;
1340
0
  }
1341
9.89k
  if (!c)
1342
8.30k
  {
1343
    /* We hit an eof char (0) */
1344
8.30k
    if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
1345
795
      tok->err = json_tokener_error_parse_eof;
1346
8.30k
  }
1347
1348
9.89k
#ifdef HAVE_USELOCALE
1349
9.89k
  uselocale(oldlocale);
1350
9.89k
  freelocale(newloc);
1351
#elif defined(HAVE_SETLOCALE)
1352
  setlocale(LC_NUMERIC, oldlocale);
1353
  free(oldlocale);
1354
#endif
1355
1356
9.89k
  if (tok->err == json_tokener_success)
1357
7.61k
  {
1358
7.61k
    json_object *ret = json_object_get(current);
1359
7.61k
    int ii;
1360
1361
    /* Partially reset, so we parse additional objects on subsequent calls. */
1362
15.6k
    for (ii = tok->depth; ii >= 0; ii--)
1363
7.98k
      json_tokener_reset_level(tok, ii);
1364
7.61k
    return ret;
1365
7.61k
  }
1366
1367
2.28k
  MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
1368
2.28k
           tok->char_offset);
1369
2.28k
  return NULL;
1370
9.89k
}
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.10k
{
1411
3.10k
  char *end;
1412
3.10k
  *retval = strtod(buf, &end);
1413
3.10k
  if (buf + len == end)
1414
3.09k
    return 0; // It worked
1415
14
  return 1;
1416
3.10k
}