Coverage Report

Created: 2026-03-03 06:43

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
10.9k
#define jt_hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x)&7) + 9)
48
49
#if !HAVE_STRNCASECMP && defined(_WIN32)
50
/* MSC has the version as _strnicmp */
51
#define strncasecmp _strnicmp
52
#elif !HAVE_STRNCASECMP
53
#error You do not have strncasecmp on your system.
54
#endif /* HAVE_STRNCASECMP */
55
56
#if defined(_MSC_VER) && (_MSC_VER <= 1800)
57
/* VS2013 doesn't know about "inline" */
58
#define inline __inline
59
#elif defined(AIX_CC)
60
#define inline
61
#endif
62
63
/* The following helper functions are used to speed up parsing. They
64
 * are faster than their ctype counterparts because they assume that
65
 * the input is in ASCII and that the locale is set to "C". The
66
 * compiler will also inline these functions, providing an additional
67
 * speedup by saving on function calls.
68
 */
69
static inline int is_ws_char(char c)
70
885k
{
71
885k
  return c == ' '
72
742k
      || c == '\t'
73
722k
      || c == '\n'
74
719k
      || c == '\r';
75
885k
}
76
77
static inline int is_hex_char(char c)
78
10.9k
{
79
10.9k
  return (c >= '0' && c <= '9')
80
3.62k
      || (c >= 'A' && c <= 'F')
81
286
      || (c >= 'a' && c <= 'f');
82
10.9k
}
83
84
/* Use C99 NAN by default; if not available, nan("") should work too. */
85
#ifndef NAN
86
#define NAN nan("")
87
#endif /* !NAN */
88
89
static const char json_null_str[] = "null";
90
static const int json_null_str_len = sizeof(json_null_str) - 1;
91
static const char json_inf_str[] = "Infinity";
92
/* Swapped case "Infinity" to avoid need to call tolower() on input chars: */
93
static const char json_inf_str_invert[] = "iNFINITY";
94
static const unsigned int json_inf_str_len = sizeof(json_inf_str) - 1;
95
static const char json_nan_str[] = "NaN";
96
static const int json_nan_str_len = sizeof(json_nan_str) - 1;
97
static const char json_true_str[] = "true";
98
static const int json_true_str_len = sizeof(json_true_str) - 1;
99
static const char json_false_str[] = "false";
100
static const int json_false_str_len = sizeof(json_false_str) - 1;
101
102
/* clang-format off */
103
static const char *json_tokener_errors[] = {
104
  "success",
105
  "continue",
106
  "nesting too deep",
107
  "unexpected end of data",
108
  "unexpected character",
109
  "null expected",
110
  "boolean expected",
111
  "number expected",
112
  "array value separator ',' expected",
113
  "quoted object property name expected",
114
  "object property name separator ':' expected",
115
  "object value separator ',' expected",
116
  "invalid string sequence",
117
  "expected comment",
118
  "invalid utf-8 string",
119
  "buffer size overflow",
120
  "out of memory"
121
};
122
/* clang-format on */
123
124
/**
125
 * validete the utf-8 string in strict model.
126
 * if not utf-8 format, return err.
127
 */
128
static json_bool json_tokener_validate_utf8(const char c, unsigned int *nBytes);
129
130
static int json_tokener_parse_double(const char *buf, int len, double *retval);
131
132
const char *json_tokener_error_desc(enum json_tokener_error jerr)
133
375
{
134
375
  int jerr_int = (int)jerr;
135
375
  if (jerr_int < 0 ||
136
375
      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
375
  return json_tokener_errors[jerr];
140
375
}
141
142
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok)
143
750
{
144
750
  return tok->err;
145
750
}
146
147
/* Stuff for decoding unicode sequences */
148
1.83k
#define IS_HIGH_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xD800)
149
1.58k
#define IS_LOW_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xDC00)
150
275
#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
6.00k
{
155
6.00k
  struct json_tokener *tok;
156
157
6.00k
  if (depth < 1)
158
0
    return NULL;
159
160
6.00k
  tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
161
6.00k
  if (!tok)
162
0
    return NULL;
163
6.00k
  tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
164
6.00k
  if (!tok->stack)
165
0
  {
166
0
    free(tok);
167
0
    return NULL;
168
0
  }
169
6.00k
  tok->pb = printbuf_new();
170
6.00k
  if (!tok->pb)
171
0
  {
172
0
    free(tok->stack);
173
0
    free(tok);
174
0
    return NULL;
175
0
  }
176
6.00k
  tok->max_depth = depth;
177
6.00k
  json_tokener_reset(tok);
178
6.00k
  return tok;
179
6.00k
}
180
181
struct json_tokener *json_tokener_new(void)
182
6.00k
{
183
6.00k
  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
184
6.00k
}
185
186
void json_tokener_free(struct json_tokener *tok)
187
6.00k
{
188
6.00k
  if (!tok)
189
0
    return;
190
6.00k
  json_tokener_reset(tok);
191
6.00k
  if (tok->pb)
192
6.00k
    printbuf_free(tok->pb);
193
6.00k
  free(tok->stack);
194
6.00k
  free(tok);
195
6.00k
}
196
197
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
198
266k
{
199
266k
  tok->stack[depth].state = json_tokener_state_eatws;
200
266k
  tok->stack[depth].saved_state = json_tokener_state_start;
201
266k
  json_object_put(tok->stack[depth].current);
202
266k
  tok->stack[depth].current = NULL;
203
266k
  free(tok->stack[depth].obj_field_name);
204
266k
  tok->stack[depth].obj_field_name = NULL;
205
266k
}
206
207
void json_tokener_reset(struct json_tokener *tok)
208
12.0k
{
209
12.0k
  int i;
210
12.0k
  if (!tok)
211
0
    return;
212
213
24.8k
  for (i = tok->depth; i >= 0; i--)
214
12.8k
    json_tokener_reset_level(tok, i);
215
12.0k
  tok->depth = 0;
216
12.0k
  tok->err = json_tokener_success;
217
12.0k
}
218
219
struct json_object *json_tokener_parse(const char *str)
220
0
{
221
0
  enum json_tokener_error jerr_ignored;
222
0
  struct json_object *obj;
223
0
  obj = json_tokener_parse_verbose(str, &jerr_ignored);
224
0
  return obj;
225
0
}
226
227
struct json_object *json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
228
0
{
229
0
  struct json_tokener *tok;
230
0
  struct json_object *obj;
231
232
0
  tok = json_tokener_new();
233
0
  if (!tok)
234
0
  {
235
0
    *error = json_tokener_error_memory;
236
0
    return NULL;
237
0
  }
238
0
  obj = json_tokener_parse_ex(tok, str, -1);
239
0
  *error = tok->err;
240
0
  if (tok->err != json_tokener_success
241
#if 0
242
    /* This would be a more sensible default, and cause parsing
243
     * things like "null123" to fail when the caller can't know
244
     * where the parsing left off, but starting to fail would
245
     * be a notable behaviour change.  Save for a 1.0 release.
246
     */
247
      || json_tokener_get_parse_end(tok) != strlen(str)
248
#endif
249
0
  )
250
251
0
  {
252
0
    if (obj != NULL)
253
0
      json_object_put(obj);
254
0
    obj = NULL;
255
0
  }
256
257
0
  json_tokener_free(tok);
258
0
  return obj;
259
0
}
260
261
3.58M
#define state tok->stack[tok->depth].state
262
1.40M
#define saved_state tok->stack[tok->depth].saved_state
263
521k
#define current tok->stack[tok->depth].current
264
483k
#define obj_field_name tok->stack[tok->depth].obj_field_name
265
266
/* Optimization:
267
 * json_tokener_parse_ex() consumed a lot of CPU in its main loop,
268
 * iterating character-by character.  A large performance boost is
269
 * achieved by using tighter loops to locally handle units such as
270
 * comments and strings.  Loops that handle an entire token within
271
 * their scope also gather entire strings and pass them to
272
 * printbuf_memappend() in a single call, rather than calling
273
 * printbuf_memappend() one char at a time.
274
 *
275
 * PEEK_CHAR() and ADVANCE_CHAR() macros are used for code that is
276
 * common to both the main loop and the tighter loops.
277
 */
278
279
/* PEEK_CHAR(dest, tok) macro:
280
 *   Peeks at the current char and stores it in dest.
281
 *   Returns 1 on success, sets tok->err and returns 0 if no more chars.
282
 *   Implicit inputs:  str, len, nBytesp vars
283
 */
284
#define PEEK_CHAR(dest, tok)                                                 \
285
3.23M
  (((tok)->char_offset == len)                                         \
286
3.23M
       ? (((tok)->depth == 0 && state == json_tokener_state_eatws &&   \
287
0
           saved_state == json_tokener_state_finish)                   \
288
0
              ? (((tok)->err = json_tokener_success), 0)               \
289
0
              : (((tok)->err = json_tokener_continue), 0))             \
290
3.23M
       : (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) &&                \
291
3.23M
           (!json_tokener_validate_utf8(*str, nBytesp)))               \
292
3.23M
              ? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
293
3.23M
              : (((dest) = *str), 1)))
294
295
/* ADVANCE_CHAR() macro:
296
 *   Increments str & tok->char_offset.
297
 *   For convenience of existing conditionals, returns the old value of c (0 on eof).
298
 *   Implicit inputs:  c var
299
 */
300
5.55M
#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
281k
  do {                                                  \
308
281k
    if (printbuf_memappend((p), (s), (l)) < 0)    \
309
281k
    {                                             \
310
0
      tok->err = json_tokener_error_memory; \
311
0
      goto out;                             \
312
0
    }                                             \
313
281k
  } 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
6.00k
{
319
6.00k
  struct json_object *obj = NULL;
320
6.00k
  char c = '\1';
321
6.00k
  unsigned int nBytes = 0;
322
6.00k
  unsigned int *nBytesp = &nBytes;
323
324
6.00k
#ifdef HAVE_USELOCALE
325
6.00k
  locale_t oldlocale = uselocale(NULL);
326
6.00k
  locale_t newloc;
327
#elif defined(HAVE_SETLOCALE)
328
  char *oldlocale = NULL;
329
#endif
330
331
6.00k
  tok->char_offset = 0;
332
6.00k
  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
6.00k
  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
6.00k
#ifdef HAVE_USELOCALE
347
6.00k
  {
348
6.00k
#ifdef HAVE_DUPLOCALE
349
6.00k
    locale_t duploc = duplocale(oldlocale);
350
6.00k
    if (duploc == NULL && errno == ENOMEM)
351
0
    {
352
0
      tok->err = json_tokener_error_memory;
353
0
      return NULL;
354
0
    }
355
6.00k
    newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
356
#else
357
    newloc = newlocale(LC_NUMERIC_MASK, "C", oldlocale);
358
#endif
359
6.00k
    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
6.00k
    uselocale(newloc);
375
6.00k
  }
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
733k
  while (PEEK_CHAR(c, tok)) // Note: c might be '\0' !
394
733k
  {
395
396
1.84M
  redo_char:
397
1.84M
    switch (state)
398
1.84M
    {
399
400
719k
    case json_tokener_state_eatws:
401
      /* Advance until we change state */
402
884k
      while (is_ws_char(c))
403
165k
      {
404
165k
        if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
405
0
          goto out;
406
165k
      }
407
719k
      if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
408
1.00k
      {
409
1.00k
        printbuf_reset(tok->pb);
410
1.00k
        printbuf_memappend_checked(tok->pb, &c, 1);
411
1.00k
        state = json_tokener_state_comment_start;
412
1.00k
      }
413
718k
      else
414
718k
      {
415
718k
        state = saved_state;
416
718k
        goto redo_char;
417
718k
      }
418
1.00k
      break;
419
420
130k
    case json_tokener_state_start:
421
130k
      switch (c)
422
130k
      {
423
43.8k
      case '{':
424
43.8k
        state = json_tokener_state_eatws;
425
43.8k
        saved_state = json_tokener_state_object_field_start;
426
43.8k
        current = json_object_new_object();
427
43.8k
        if (current == NULL)
428
0
        {
429
0
          tok->err = json_tokener_error_memory;
430
0
          goto out;
431
0
        }
432
43.8k
        break;
433
43.8k
      case '[':
434
8.82k
        state = json_tokener_state_eatws;
435
8.82k
        saved_state = json_tokener_state_array;
436
8.82k
        current = json_object_new_array();
437
8.82k
        if (current == NULL)
438
0
        {
439
0
          tok->err = json_tokener_error_memory;
440
0
          goto out;
441
0
        }
442
8.82k
        break;
443
8.82k
      case 'I':
444
14
      case 'i':
445
14
        state = json_tokener_state_inf;
446
14
        printbuf_reset(tok->pb);
447
14
        tok->st_pos = 0;
448
14
        goto redo_char;
449
137
      case 'N':
450
328
      case 'n':
451
328
        state = json_tokener_state_null; // or NaN
452
328
        printbuf_reset(tok->pb);
453
328
        tok->st_pos = 0;
454
328
        goto redo_char;
455
87
      case '\'':
456
87
        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
66.4k
      case '"':
464
66.4k
        state = json_tokener_state_string;
465
66.4k
        printbuf_reset(tok->pb);
466
66.4k
        tok->quote_char = c;
467
66.4k
        break;
468
23
      case 'T':
469
69
      case 't':
470
195
      case 'F':
471
304
      case 'f':
472
304
        state = json_tokener_state_boolean;
473
304
        printbuf_reset(tok->pb);
474
304
        tok->st_pos = 0;
475
304
        goto redo_char;
476
2.40k
      case '0':
477
4.80k
      case '1':
478
5.66k
      case '2':
479
6.04k
      case '3':
480
7.36k
      case '4':
481
8.00k
      case '5':
482
8.12k
      case '6':
483
8.26k
      case '7':
484
8.33k
      case '8':
485
8.63k
      case '9':
486
10.5k
      case '-':
487
10.5k
        state = json_tokener_state_number;
488
10.5k
        printbuf_reset(tok->pb);
489
10.5k
        tok->is_double = 0;
490
10.5k
        goto redo_char;
491
75
      default: tok->err = json_tokener_error_parse_unexpected; goto out;
492
130k
      }
493
119k
      break;
494
495
129k
    case json_tokener_state_finish:
496
129k
      if (tok->depth == 0)
497
5.59k
        goto out;
498
123k
      obj = json_object_get(current);
499
123k
      json_tokener_reset_level(tok, tok->depth);
500
123k
      tok->depth--;
501
123k
      goto redo_char;
502
503
15
    case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
504
15
    {
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
15
      int is_negative = 0;
513
514
      /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
515
37
      while (tok->st_pos < (int)json_inf_str_len)
516
37
      {
517
37
        char inf_char = *str;
518
37
        if (inf_char != json_inf_str[tok->st_pos] &&
519
30
            ((tok->flags & JSON_TOKENER_STRICT) ||
520
30
              inf_char != json_inf_str_invert[tok->st_pos])
521
37
           )
522
15
        {
523
15
          tok->err = json_tokener_error_parse_unexpected;
524
15
          goto out;
525
15
        }
526
22
        tok->st_pos++;
527
22
        (void)ADVANCE_CHAR(str, tok);
528
22
        if (!PEEK_CHAR(c, tok))
529
0
        {
530
          /* out of input chars, for now at least */
531
0
          goto out;
532
0
        }
533
22
      }
534
      /* We checked the full length of "Infinity", so create the object.
535
       * When handling -Infinity, the number parsing code will have dropped
536
       * the "-" into tok->pb for us, so check it now.
537
       */
538
0
      if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
539
0
      {
540
0
        is_negative = 1;
541
0
      }
542
0
      current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
543
0
      if (current == NULL)
544
0
      {
545
0
        tok->err = json_tokener_error_memory;
546
0
        goto out;
547
0
      }
548
0
      saved_state = json_tokener_state_finish;
549
0
      state = json_tokener_state_eatws;
550
0
      goto redo_char;
551
0
    }
552
0
    break;
553
1.46k
    case json_tokener_state_null: /* aka starts with 'n' */
554
1.46k
    {
555
1.46k
      int size;
556
1.46k
      int size_nan;
557
1.46k
      printbuf_memappend_checked(tok->pb, &c, 1);
558
1.46k
      size = json_min(tok->st_pos + 1, json_null_str_len);
559
1.46k
      size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
560
1.46k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
561
1.46k
           strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
562
417
          (strncmp(json_null_str, tok->pb->buf, size) == 0))
563
1.04k
      {
564
1.04k
        if (tok->st_pos == json_null_str_len)
565
178
        {
566
178
          current = NULL;
567
178
          saved_state = json_tokener_state_finish;
568
178
          state = json_tokener_state_eatws;
569
178
          goto redo_char;
570
178
        }
571
1.04k
      }
572
417
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
573
417
                strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
574
18
               (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
575
399
      {
576
399
        if (tok->st_pos == json_nan_str_len)
577
132
        {
578
132
          current = json_object_new_double(NAN);
579
132
          if (current == NULL)
580
0
          {
581
0
            tok->err = json_tokener_error_memory;
582
0
            goto out;
583
0
          }
584
132
          saved_state = json_tokener_state_finish;
585
132
          state = json_tokener_state_eatws;
586
132
          goto redo_char;
587
132
        }
588
399
      }
589
18
      else
590
18
      {
591
18
        tok->err = json_tokener_error_parse_null;
592
18
        goto out;
593
18
      }
594
1.13k
      tok->st_pos++;
595
1.13k
    }
596
0
    break;
597
598
1.00k
    case json_tokener_state_comment_start:
599
1.00k
      if (c == '*')
600
295
      {
601
295
        state = json_tokener_state_comment;
602
295
      }
603
714
      else if (c == '/')
604
701
      {
605
701
        state = json_tokener_state_comment_eol;
606
701
      }
607
13
      else
608
13
      {
609
13
        tok->err = json_tokener_error_parse_comment;
610
13
        goto out;
611
13
      }
612
996
      printbuf_memappend_checked(tok->pb, &c, 1);
613
996
      break;
614
615
1.64k
    case json_tokener_state_comment:
616
1.64k
    {
617
      /* Advance until we change state */
618
1.64k
      const char *case_start = str;
619
22.9k
      while (c != '*')
620
21.3k
      {
621
21.3k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
622
26
        {
623
26
          printbuf_memappend_checked(tok->pb, case_start,
624
26
                                     str - case_start);
625
26
          goto out;
626
26
        }
627
21.3k
      }
628
1.61k
      printbuf_memappend_checked(tok->pb, case_start, 1 + str - case_start);
629
1.61k
      state = json_tokener_state_comment_end;
630
1.61k
    }
631
0
    break;
632
633
701
    case json_tokener_state_comment_eol:
634
701
    {
635
      /* Advance until we change state */
636
701
      const char *case_start = str;
637
53.2k
      while (c != '\n')
638
52.5k
      {
639
52.5k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
640
40
        {
641
40
          printbuf_memappend_checked(tok->pb, case_start,
642
40
                                     str - case_start);
643
40
          goto out;
644
40
        }
645
52.5k
      }
646
661
      printbuf_memappend_checked(tok->pb, case_start, str - case_start);
647
661
      MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
648
661
      state = json_tokener_state_eatws;
649
661
    }
650
0
    break;
651
652
1.61k
    case json_tokener_state_comment_end:
653
1.61k
      printbuf_memappend_checked(tok->pb, &c, 1);
654
1.61k
      if (c == '/')
655
265
      {
656
265
        MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
657
265
        state = json_tokener_state_eatws;
658
265
      }
659
1.35k
      else
660
1.35k
      {
661
1.35k
        state = json_tokener_state_comment;
662
1.35k
      }
663
1.61k
      break;
664
665
108k
    case json_tokener_state_string:
666
108k
    {
667
      /* Advance until we change state */
668
108k
      const char *case_start = str;
669
1.55M
      while (1)
670
1.55M
      {
671
1.55M
        if (c == tok->quote_char)
672
66.4k
        {
673
66.4k
          printbuf_memappend_checked(tok->pb, case_start,
674
66.4k
                                     str - case_start);
675
66.4k
          current =
676
66.4k
              json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
677
66.4k
          if (current == NULL)
678
0
          {
679
0
            tok->err = json_tokener_error_memory;
680
0
            goto out;
681
0
          }
682
66.4k
          saved_state = json_tokener_state_finish;
683
66.4k
          state = json_tokener_state_eatws;
684
66.4k
          break;
685
66.4k
        }
686
1.48M
        else if (c == '\\')
687
41.9k
        {
688
41.9k
          printbuf_memappend_checked(tok->pb, case_start,
689
41.9k
                                     str - case_start);
690
41.9k
          saved_state = json_tokener_state_string;
691
41.9k
          state = json_tokener_state_string_escape;
692
41.9k
          break;
693
41.9k
        }
694
1.44M
        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.44M
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
701
36
        {
702
36
          printbuf_memappend_checked(tok->pb, case_start,
703
36
                                     str - case_start);
704
36
          goto out;
705
36
        }
706
1.44M
      }
707
108k
    }
708
108k
    break;
709
710
108k
    case json_tokener_state_string_escape:
711
49.4k
      switch (c)
712
49.4k
      {
713
9.52k
      case '"':
714
29.0k
      case '\\':
715
29.1k
      case '/':
716
29.1k
        printbuf_memappend_checked(tok->pb, &c, 1);
717
29.1k
        state = saved_state;
718
29.1k
        break;
719
753
      case 'b':
720
16.8k
      case 'n':
721
17.1k
      case 'r':
722
17.6k
      case 't':
723
17.9k
      case 'f':
724
17.9k
        if (c == 'b')
725
753
          printbuf_memappend_checked(tok->pb, "\b", 1);
726
17.1k
        else if (c == 'n')
727
16.1k
          printbuf_memappend_checked(tok->pb, "\n", 1);
728
1.05k
        else if (c == 'r')
729
279
          printbuf_memappend_checked(tok->pb, "\r", 1);
730
779
        else if (c == 't')
731
543
          printbuf_memappend_checked(tok->pb, "\t", 1);
732
236
        else if (c == 'f')
733
236
          printbuf_memappend_checked(tok->pb, "\f", 1);
734
17.9k
        state = saved_state;
735
17.9k
        break;
736
2.34k
      case 'u':
737
2.34k
        tok->ucs_char = 0;
738
2.34k
        tok->st_pos = 0;
739
2.34k
        state = json_tokener_state_escape_unicode;
740
2.34k
        break;
741
10
      default: tok->err = json_tokener_error_parse_string; goto out;
742
49.4k
      }
743
49.4k
      break;
744
745
      // ===================================================
746
747
49.4k
    case json_tokener_state_escape_unicode:
748
2.75k
    {
749
      /* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */
750
10.9k
      while (1)
751
10.9k
      {
752
10.9k
        if (!c || !is_hex_char(c))
753
14
        {
754
14
          tok->err = json_tokener_error_parse_string;
755
14
          goto out;
756
14
        }
757
10.9k
        tok->ucs_char |=
758
10.9k
            ((unsigned int)jt_hexdigit(c) << ((3 - tok->st_pos) * 4));
759
10.9k
        tok->st_pos++;
760
10.9k
        if (tok->st_pos >= 4)
761
2.73k
          break;
762
763
8.23k
        (void)ADVANCE_CHAR(str, tok);
764
8.23k
        if (!PEEK_CHAR(c, tok))
765
0
        {
766
          /*
767
           * We're out of characters in the current call to
768
           * json_tokener_parse(), but a subsequent call might
769
           * provide us with more, so leave our current state
770
           * as-is (including tok->high_surrogate) and return.
771
           */
772
0
          goto out;
773
0
        }
774
8.23k
      }
775
2.73k
      tok->st_pos = 0;
776
777
      /* Now, we have a full \uNNNN sequence in tok->ucs_char */
778
779
      /* If the *previous* sequence was a high surrogate ... */
780
2.73k
      if (tok->high_surrogate)
781
404
      {
782
404
        if (IS_LOW_SURROGATE(tok->ucs_char))
783
275
        {
784
          /* Recalculate the ucs_char, then fall thru to process normally */
785
275
          tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate,
786
275
                                                tok->ucs_char);
787
275
        }
788
129
        else
789
129
        {
790
          /* High surrogate was not followed by a low surrogate
791
           * Replace the high and process the rest normally
792
           */
793
129
          printbuf_memappend_checked(tok->pb,
794
129
                                     (char *)utf8_replacement_char, 3);
795
129
        }
796
404
        tok->high_surrogate = 0;
797
404
      }
798
799
2.73k
      if (tok->ucs_char < 0x80)
800
861
      {
801
861
        unsigned char unescaped_utf[1];
802
861
        unescaped_utf[0] = tok->ucs_char;
803
861
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 1);
804
861
      }
805
1.87k
      else if (tok->ucs_char < 0x800)
806
44
      {
807
44
        unsigned char unescaped_utf[2];
808
44
        unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
809
44
        unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
810
44
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 2);
811
44
      }
812
1.83k
      else if (IS_HIGH_SURROGATE(tok->ucs_char))
813
656
      {
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
656
        tok->high_surrogate = tok->ucs_char;
829
656
        tok->ucs_char = 0;
830
656
        state = json_tokener_state_escape_unicode_need_escape;
831
656
        break;
832
656
      }
833
1.17k
      else if (IS_LOW_SURROGATE(tok->ucs_char))
834
416
      {
835
        /* Got a low surrogate not preceded by a high */
836
416
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
837
416
      }
838
760
      else if (tok->ucs_char < 0x10000)
839
485
      {
840
485
        unsigned char unescaped_utf[3];
841
485
        unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
842
485
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
843
485
        unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
844
485
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 3);
845
485
      }
846
275
      else if (tok->ucs_char < 0x110000)
847
275
      {
848
275
        unsigned char unescaped_utf[4];
849
275
        unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
850
275
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
851
275
        unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
852
275
        unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
853
275
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 4);
854
275
      }
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.08k
      state = saved_state; // i.e. _state_string or _state_object_field
861
2.08k
    }
862
0
    break;
863
864
656
    case json_tokener_state_escape_unicode_need_escape:
865
      // We get here after processing a high_surrogate
866
      // require a '\\' char
867
656
      if (!c || c != '\\')
868
155
      {
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
155
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
874
155
        tok->high_surrogate = 0;
875
155
        tok->ucs_char = 0;
876
155
        tok->st_pos = 0;
877
155
        state = saved_state;
878
155
        goto redo_char;
879
155
      }
880
501
      state = json_tokener_state_escape_unicode_need_u;
881
501
      break;
882
883
501
    case json_tokener_state_escape_unicode_need_u:
884
      /* We already had a \ char, check that it's \u */
885
501
      if (!c || c != 'u')
886
95
      {
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
95
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
893
95
        tok->high_surrogate = 0;
894
95
        tok->ucs_char = 0;
895
95
        tok->st_pos = 0;
896
95
        state = json_tokener_state_string_escape;
897
95
        goto redo_char;
898
95
      }
899
406
      state = json_tokener_state_escape_unicode;
900
406
      break;
901
902
      // ===================================================
903
904
1.68k
    case json_tokener_state_boolean:
905
1.68k
    {
906
1.68k
      int size1, size2;
907
1.68k
      printbuf_memappend_checked(tok->pb, &c, 1);
908
1.68k
      size1 = json_min(tok->st_pos + 1, json_true_str_len);
909
1.68k
      size2 = json_min(tok->st_pos + 1, json_false_str_len);
910
1.68k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
911
1.68k
           strncasecmp(json_true_str, tok->pb->buf, size1) == 0) ||
912
1.39k
          (strncmp(json_true_str, tok->pb->buf, size1) == 0))
913
289
      {
914
289
        if (tok->st_pos == json_true_str_len)
915
54
        {
916
54
          current = json_object_new_boolean(1);
917
54
          if (current == NULL)
918
0
          {
919
0
            tok->err = json_tokener_error_memory;
920
0
            goto out;
921
0
          }
922
54
          saved_state = json_tokener_state_finish;
923
54
          state = json_tokener_state_eatws;
924
54
          goto redo_char;
925
54
        }
926
289
      }
927
1.39k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
928
1.39k
                strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
929
26
               (strncmp(json_false_str, tok->pb->buf, size2) == 0))
930
1.36k
      {
931
1.36k
        if (tok->st_pos == json_false_str_len)
932
224
        {
933
224
          current = json_object_new_boolean(0);
934
224
          if (current == NULL)
935
0
          {
936
0
            tok->err = json_tokener_error_memory;
937
0
            goto out;
938
0
          }
939
224
          saved_state = json_tokener_state_finish;
940
224
          state = json_tokener_state_eatws;
941
224
          goto redo_char;
942
224
        }
943
1.36k
      }
944
26
      else
945
26
      {
946
26
        tok->err = json_tokener_error_parse_boolean;
947
26
        goto out;
948
26
      }
949
1.37k
      tok->st_pos++;
950
1.37k
    }
951
0
    break;
952
953
10.5k
    case json_tokener_state_number:
954
10.5k
    {
955
      /* Advance until we change state */
956
10.5k
      const char *case_start = str;
957
10.5k
      int case_len = 0;
958
10.5k
      int is_exponent = 0;
959
10.5k
      int neg_sign_ok = 1;
960
10.5k
      int pos_sign_ok = 0;
961
10.5k
      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
72.8k
      while (c && ((c >= '0' && c <= '9') ||
986
13.4k
                   (!is_exponent && (c == 'e' || c == 'E')) ||
987
13.0k
                   (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') ||
988
10.8k
                   (!tok->is_double && c == '.')))
989
62.3k
      {
990
62.3k
        pos_sign_ok = neg_sign_ok = 0;
991
62.3k
        ++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
62.3k
        switch (c)
1000
62.3k
        {
1001
392
        case '.':
1002
392
          tok->is_double = 1;
1003
392
          pos_sign_ok = 1;
1004
392
          neg_sign_ok = 1;
1005
392
          break;
1006
376
        case 'e': /* FALLTHRU */
1007
408
        case 'E':
1008
408
          is_exponent = 1;
1009
408
          tok->is_double = 1;
1010
          /* the exponent part can begin with a negative sign */
1011
408
          pos_sign_ok = neg_sign_ok = 1;
1012
408
          break;
1013
61.5k
        default: break;
1014
62.3k
        }
1015
1016
62.3k
        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
62.3k
      }
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
10.5k
      if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
1031
809
          c != 'I' && c != 'i' && !is_ws_char(c))
1032
37
      {
1033
37
        tok->err = json_tokener_error_parse_number;
1034
37
        goto out;
1035
37
      }
1036
10.4k
      if (case_len > 0)
1037
10.4k
        printbuf_memappend_checked(tok->pb, case_start, case_len);
1038
1039
      // Check for -Infinity
1040
10.4k
      if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
1041
1
      {
1042
1
        state = json_tokener_state_inf;
1043
1
        tok->st_pos = 0;
1044
1
        goto redo_char;
1045
1
      }
1046
10.4k
      if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
1047
462
      {
1048
        /* Trim some chars off the end, to allow things
1049
           like "123e+" to parse ok. */
1050
1.09k
        while (printbuf_length(tok->pb) > 1)
1051
1.07k
        {
1052
1.07k
          char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1];
1053
1.07k
          if (last_char != 'e' && last_char != 'E' &&
1054
734
              last_char != '-' && last_char != '+')
1055
440
          {
1056
440
            break;
1057
440
          }
1058
633
          tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0';
1059
633
          printbuf_length(tok->pb)--;
1060
633
        }
1061
462
      }
1062
10.4k
    }
1063
0
      {
1064
10.4k
        int64_t num64;
1065
10.4k
        uint64_t numuint64;
1066
10.4k
        double numd;
1067
10.4k
        if (!tok->is_double && tok->pb->buf[0] == '-' &&
1068
1.48k
            json_parse_int64(tok->pb->buf, &num64) == 0)
1069
1.48k
        {
1070
1.48k
          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
1.48k
          current = json_object_new_int64(num64);
1076
1.48k
          if (current == NULL)
1077
0
          {
1078
0
            tok->err = json_tokener_error_memory;
1079
0
            goto out;
1080
0
          }
1081
1.48k
        }
1082
8.97k
        else if (!tok->is_double && tok->pb->buf[0] != '-' &&
1083
8.51k
                 json_parse_uint64(tok->pb->buf, &numuint64) == 0)
1084
8.51k
        {
1085
8.51k
          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
8.51k
          if (numuint64 && tok->pb->buf[0] == '0' &&
1091
1.64k
              (tok->flags & JSON_TOKENER_STRICT))
1092
0
          {
1093
0
            tok->err = json_tokener_error_parse_number;
1094
0
            goto out;
1095
0
          }
1096
8.51k
          if (numuint64 <= INT64_MAX)
1097
8.16k
          {
1098
8.16k
            num64 = (uint64_t)numuint64;
1099
8.16k
            current = json_object_new_int64(num64);
1100
8.16k
            if (current == NULL)
1101
0
            {
1102
0
              tok->err = json_tokener_error_memory;
1103
0
              goto out;
1104
0
            }
1105
8.16k
          }
1106
348
          else
1107
348
          {
1108
348
            current = json_object_new_uint64(numuint64);
1109
348
            if (current == NULL)
1110
0
            {
1111
0
              tok->err = json_tokener_error_memory;
1112
0
              goto out;
1113
0
            }
1114
348
          }
1115
8.51k
        }
1116
465
        else if (tok->is_double &&
1117
462
                 json_tokener_parse_double(
1118
462
                     tok->pb->buf, printbuf_length(tok->pb), &numd) == 0)
1119
461
        {
1120
461
          current = json_object_new_double_s(numd, tok->pb->buf);
1121
461
          if (current == NULL)
1122
0
          {
1123
0
            tok->err = json_tokener_error_memory;
1124
0
            goto out;
1125
0
          }
1126
461
        }
1127
4
        else
1128
4
        {
1129
4
          tok->err = json_tokener_error_parse_number;
1130
4
          goto out;
1131
4
        }
1132
10.4k
        saved_state = json_tokener_state_finish;
1133
10.4k
        state = json_tokener_state_eatws;
1134
10.4k
        goto redo_char;
1135
10.4k
      }
1136
0
      break;
1137
1138
18.7k
    case json_tokener_state_array_after_sep:
1139
27.5k
    case json_tokener_state_array:
1140
27.5k
      if (c == ']')
1141
189
      {
1142
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1143
189
        json_object_array_shrink(current, 0);
1144
1145
189
        if (state == json_tokener_state_array_after_sep &&
1146
18
            (tok->flags & JSON_TOKENER_STRICT))
1147
0
        {
1148
0
          tok->err = json_tokener_error_parse_unexpected;
1149
0
          goto out;
1150
0
        }
1151
189
        saved_state = json_tokener_state_finish;
1152
189
        state = json_tokener_state_eatws;
1153
189
      }
1154
27.3k
      else
1155
27.3k
      {
1156
27.3k
        if (tok->depth >= tok->max_depth - 1)
1157
1
        {
1158
1
          tok->err = json_tokener_error_depth;
1159
1
          goto out;
1160
1
        }
1161
27.3k
        state = json_tokener_state_array_add;
1162
27.3k
        tok->depth++;
1163
27.3k
        json_tokener_reset_level(tok, tok->depth);
1164
27.3k
        goto redo_char;
1165
27.3k
      }
1166
189
      break;
1167
1168
27.0k
    case json_tokener_state_array_add:
1169
27.0k
      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
27.0k
      saved_state = json_tokener_state_array_sep;
1175
27.0k
      state = json_tokener_state_eatws;
1176
27.0k
      goto redo_char;
1177
1178
27.0k
    case json_tokener_state_array_sep:
1179
27.0k
      if (c == ']')
1180
8.27k
      {
1181
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1182
8.27k
        json_object_array_shrink(current, 0);
1183
1184
8.27k
        saved_state = json_tokener_state_finish;
1185
8.27k
        state = json_tokener_state_eatws;
1186
8.27k
      }
1187
18.7k
      else if (c == ',')
1188
18.7k
      {
1189
18.7k
        saved_state = json_tokener_state_array_after_sep;
1190
18.7k
        state = json_tokener_state_eatws;
1191
18.7k
      }
1192
20
      else
1193
20
      {
1194
20
        tok->err = json_tokener_error_parse_array;
1195
20
        goto out;
1196
20
      }
1197
26.9k
      break;
1198
1199
43.8k
    case json_tokener_state_object_field_start:
1200
113k
    case json_tokener_state_object_field_start_after_sep:
1201
113k
      if (c == '}')
1202
16.7k
      {
1203
16.7k
        if (state == json_tokener_state_object_field_start_after_sep &&
1204
4
            (tok->flags & JSON_TOKENER_STRICT))
1205
0
        {
1206
0
          tok->err = json_tokener_error_parse_unexpected;
1207
0
          goto out;
1208
0
        }
1209
16.7k
        saved_state = json_tokener_state_finish;
1210
16.7k
        state = json_tokener_state_eatws;
1211
16.7k
      }
1212
97.1k
      else if (c == '"' || c == '\'')
1213
97.0k
      {
1214
97.0k
        tok->quote_char = c;
1215
97.0k
        printbuf_reset(tok->pb);
1216
97.0k
        state = json_tokener_state_object_field;
1217
97.0k
      }
1218
16
      else
1219
16
      {
1220
16
        tok->err = json_tokener_error_parse_object_key_name;
1221
16
        goto out;
1222
16
      }
1223
113k
      break;
1224
1225
113k
    case json_tokener_state_object_field:
1226
104k
    {
1227
      /* Advance until we change state */
1228
104k
      const char *case_start = str;
1229
848k
      while (1)
1230
848k
      {
1231
848k
        if (c == tok->quote_char)
1232
97.0k
        {
1233
97.0k
          printbuf_memappend_checked(tok->pb, case_start,
1234
97.0k
                                     str - case_start);
1235
97.0k
          obj_field_name = strdup(tok->pb->buf);
1236
97.0k
          if (obj_field_name == NULL)
1237
0
          {
1238
0
            tok->err = json_tokener_error_memory;
1239
0
            goto out;
1240
0
          }
1241
97.0k
          saved_state = json_tokener_state_object_field_end;
1242
97.0k
          state = json_tokener_state_eatws;
1243
97.0k
          break;
1244
97.0k
        }
1245
750k
        else if (c == '\\')
1246
7.35k
        {
1247
7.35k
          printbuf_memappend_checked(tok->pb, case_start,
1248
7.35k
                                     str - case_start);
1249
7.35k
          saved_state = json_tokener_state_object_field;
1250
7.35k
          state = json_tokener_state_string_escape;
1251
7.35k
          break;
1252
7.35k
        }
1253
743k
        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
743k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
1260
18
        {
1261
18
          printbuf_memappend_checked(tok->pb, case_start,
1262
18
                                     str - case_start);
1263
18
          goto out;
1264
18
        }
1265
743k
      }
1266
104k
    }
1267
104k
    break;
1268
1269
104k
    case json_tokener_state_object_field_end:
1270
97.0k
      if (c == ':')
1271
97.0k
      {
1272
97.0k
        saved_state = json_tokener_state_object_value;
1273
97.0k
        state = json_tokener_state_eatws;
1274
97.0k
      }
1275
19
      else
1276
19
      {
1277
19
        tok->err = json_tokener_error_parse_object_key_sep;
1278
19
        goto out;
1279
19
      }
1280
97.0k
      break;
1281
1282
97.0k
    case json_tokener_state_object_value:
1283
97.0k
      if (tok->depth >= tok->max_depth - 1)
1284
0
      {
1285
0
        tok->err = json_tokener_error_depth;
1286
0
        goto out;
1287
0
      }
1288
97.0k
      state = json_tokener_state_object_value_add;
1289
97.0k
      tok->depth++;
1290
97.0k
      json_tokener_reset_level(tok, tok->depth);
1291
97.0k
      goto redo_char;
1292
1293
96.5k
    case json_tokener_state_object_value_add:
1294
96.5k
      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
96.5k
      free(obj_field_name);
1300
96.5k
      obj_field_name = NULL;
1301
96.5k
      saved_state = json_tokener_state_object_sep;
1302
96.5k
      state = json_tokener_state_eatws;
1303
96.5k
      goto redo_char;
1304
1305
96.5k
    case json_tokener_state_object_sep:
1306
      /* { */
1307
96.5k
      if (c == '}')
1308
26.4k
      {
1309
26.4k
        saved_state = json_tokener_state_finish;
1310
26.4k
        state = json_tokener_state_eatws;
1311
26.4k
      }
1312
70.0k
      else if (c == ',')
1313
70.0k
      {
1314
70.0k
        saved_state = json_tokener_state_object_field_start_after_sep;
1315
70.0k
        state = json_tokener_state_eatws;
1316
70.0k
      }
1317
15
      else
1318
15
      {
1319
15
        tok->err = json_tokener_error_parse_object_value_sep;
1320
15
        goto out;
1321
15
      }
1322
96.4k
      break;
1323
1.84M
    }
1324
727k
    (void)ADVANCE_CHAR(str, tok);
1325
727k
    if (!c) // This is the char *before* advancing
1326
4
      break;
1327
727k
  } /* while(PEEK_CHAR) */
1328
1329
6.00k
out:
1330
6.00k
  if ((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && (nBytes != 0))
1331
0
  {
1332
0
    tok->err = json_tokener_error_parse_utf8_string;
1333
0
  }
1334
6.00k
  if (c && (state == json_tokener_state_finish) && (tok->depth == 0) &&
1335
58
      (tok->flags & (JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS)) ==
1336
58
          JSON_TOKENER_STRICT)
1337
0
  {
1338
    /* unexpected char after JSON data */
1339
0
    tok->err = json_tokener_error_parse_unexpected;
1340
0
  }
1341
6.00k
  if (!c)
1342
5.73k
  {
1343
    /* We hit an eof char (0) */
1344
5.73k
    if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
1345
167
      tok->err = json_tokener_error_parse_eof;
1346
5.73k
  }
1347
1348
6.00k
#ifdef HAVE_USELOCALE
1349
6.00k
  uselocale(oldlocale);
1350
6.00k
  freelocale(newloc);
1351
#elif defined(HAVE_SETLOCALE)
1352
  setlocale(LC_NUMERIC, oldlocale);
1353
  free(oldlocale);
1354
#endif
1355
1356
6.00k
  if (tok->err == json_tokener_success)
1357
5.62k
  {
1358
5.62k
    json_object *ret = json_object_get(current);
1359
5.62k
    int ii;
1360
1361
    /* Partially reset, so we parse additional objects on subsequent calls. */
1362
11.3k
    for (ii = tok->depth; ii >= 0; ii--)
1363
5.67k
      json_tokener_reset_level(tok, ii);
1364
5.62k
    return ret;
1365
5.62k
  }
1366
1367
374
  MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
1368
374
           tok->char_offset);
1369
374
  return NULL;
1370
6.00k
}
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
462
{
1411
462
  char *end;
1412
462
  *retval = strtod(buf, &end);
1413
462
  if (buf + len == end)
1414
461
    return 0; // It worked
1415
1
  return 1;
1416
462
}