Coverage Report

Created: 2025-12-10 06:24

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.5k
#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.46M
      || c == '\r';
75
1.61M
}
76
77
static inline int is_hex_char(char c)
78
18.5k
{
79
18.5k
  return (c >= '0' && c <= '9')
80
7.85k
      || (c >= 'A' && c <= 'F')
81
1.69k
      || (c >= 'a' && c <= 'f');
82
18.5k
}
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.26k
{
134
2.26k
  int jerr_int = (int)jerr;
135
2.26k
  if (jerr_int < 0 ||
136
2.26k
      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.26k
  return json_tokener_errors[jerr];
140
2.26k
}
141
142
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok)
143
4.53k
{
144
4.53k
  return tok->err;
145
4.53k
}
146
147
/* Stuff for decoding unicode sequences */
148
3.26k
#define IS_HIGH_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xD800)
149
2.51k
#define IS_LOW_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xDC00)
150
466
#define DECODE_SURROGATE_PAIR(hi, lo) ((((hi)&0x3FF) << 10) + ((lo)&0x3FF) + 0x10000)
151
static unsigned char utf8_replacement_char[3] = {0xEF, 0xBF, 0xBD};
152
153
struct json_tokener *json_tokener_new_ex(int depth)
154
10.0k
{
155
10.0k
  struct json_tokener *tok;
156
157
10.0k
  if (depth < 1)
158
0
    return NULL;
159
160
10.0k
  tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
161
10.0k
  if (!tok)
162
0
    return NULL;
163
10.0k
  tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
164
10.0k
  if (!tok->stack)
165
0
  {
166
0
    free(tok);
167
0
    return NULL;
168
0
  }
169
10.0k
  tok->pb = printbuf_new();
170
10.0k
  if (!tok->pb)
171
0
  {
172
0
    free(tok->stack);
173
0
    free(tok);
174
0
    return NULL;
175
0
  }
176
10.0k
  tok->max_depth = depth;
177
10.0k
  json_tokener_reset(tok);
178
10.0k
  return tok;
179
10.0k
}
180
181
struct json_tokener *json_tokener_new(void)
182
10.0k
{
183
10.0k
  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
184
10.0k
}
185
186
void json_tokener_free(struct json_tokener *tok)
187
10.0k
{
188
10.0k
  if (!tok)
189
0
    return;
190
10.0k
  json_tokener_reset(tok);
191
10.0k
  if (tok->pb)
192
10.0k
    printbuf_free(tok->pb);
193
10.0k
  free(tok->stack);
194
10.0k
  free(tok);
195
10.0k
}
196
197
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
198
618k
{
199
618k
  tok->stack[depth].state = json_tokener_state_eatws;
200
618k
  tok->stack[depth].saved_state = json_tokener_state_start;
201
618k
  json_object_put(tok->stack[depth].current);
202
618k
  tok->stack[depth].current = NULL;
203
618k
  free(tok->stack[depth].obj_field_name);
204
618k
  tok->stack[depth].obj_field_name = NULL;
205
618k
}
206
207
void json_tokener_reset(struct json_tokener *tok)
208
20.1k
{
209
20.1k
  int i;
210
20.1k
  if (!tok)
211
0
    return;
212
213
44.1k
  for (i = tok->depth; i >= 0; i--)
214
24.0k
    json_tokener_reset_level(tok, i);
215
20.1k
  tok->depth = 0;
216
20.1k
  tok->err = json_tokener_success;
217
20.1k
}
218
219
struct json_object *json_tokener_parse(const char *str)
220
0
{
221
0
  enum json_tokener_error jerr_ignored;
222
0
  struct json_object *obj;
223
0
  obj = json_tokener_parse_verbose(str, &jerr_ignored);
224
0
  return obj;
225
0
}
226
227
struct json_object *json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
228
0
{
229
0
  struct json_tokener *tok;
230
0
  struct json_object *obj;
231
232
0
  tok = json_tokener_new();
233
0
  if (!tok)
234
0
  {
235
0
    *error = json_tokener_error_memory;
236
0
    return NULL;
237
0
  }
238
0
  obj = json_tokener_parse_ex(tok, str, -1);
239
0
  *error = tok->err;
240
0
  if (tok->err != json_tokener_success
241
#if 0
242
    /* This would be a more sensible default, and cause parsing
243
     * things like "null123" to fail when the caller can't know
244
     * where the parsing left off, but starting to fail would
245
     * be a notable behaviour change.  Save for a 1.0 release.
246
     */
247
      || json_tokener_get_parse_end(tok) != strlen(str)
248
#endif
249
0
  )
250
251
0
  {
252
0
    if (obj != NULL)
253
0
      json_object_put(obj);
254
0
    obj = NULL;
255
0
  }
256
257
0
  json_tokener_free(tok);
258
0
  return obj;
259
0
}
260
261
7.14M
#define state tok->stack[tok->depth].state
262
2.70M
#define saved_state tok->stack[tok->depth].saved_state
263
1.19M
#define current tok->stack[tok->depth].current
264
607k
#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.78M
  (((tok)->char_offset == len)                                         \
286
5.78M
       ? (((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.78M
       : (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) &&                \
291
5.78M
           (!json_tokener_validate_utf8(*str, nBytesp)))               \
292
5.78M
              ? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
293
5.78M
              : (((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.3M
#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
518k
  do {                                                  \
308
518k
    if (printbuf_memappend((p), (s), (l)) < 0)    \
309
518k
    {                                             \
310
0
      tok->err = json_tokener_error_memory; \
311
0
      goto out;                             \
312
0
    }                                             \
313
518k
  } while (0)
314
315
/* End optimization macro defs */
316
317
struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *str, int len)
318
10.0k
{
319
10.0k
  struct json_object *obj = NULL;
320
10.0k
  char c = '\1';
321
10.0k
  unsigned int nBytes = 0;
322
10.0k
  unsigned int *nBytesp = &nBytes;
323
324
10.0k
#ifdef HAVE_USELOCALE
325
10.0k
  locale_t oldlocale = uselocale(NULL);
326
10.0k
  locale_t newloc;
327
#elif defined(HAVE_SETLOCALE)
328
  char *oldlocale = NULL;
329
#endif
330
331
10.0k
  tok->char_offset = 0;
332
10.0k
  tok->err = json_tokener_success;
333
334
  /* this interface is presently not 64-bit clean due to the int len argument
335
   * and the internal printbuf interface that takes 32-bit int len arguments
336
   * so the function limits the maximum string size to INT32_MAX (2GB).
337
   * If the function is called with len == -1 then strlen is called to check
338
   * the string length is less than INT32_MAX (2GB)
339
   */
340
10.0k
  if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX))
341
0
  {
342
0
    tok->err = json_tokener_error_size;
343
0
    return NULL;
344
0
  }
345
346
10.0k
#ifdef HAVE_USELOCALE
347
10.0k
  {
348
10.0k
#ifdef HAVE_DUPLOCALE
349
10.0k
    locale_t duploc = duplocale(oldlocale);
350
10.0k
    if (duploc == NULL && errno == ENOMEM)
351
0
    {
352
0
      tok->err = json_tokener_error_memory;
353
0
      return NULL;
354
0
    }
355
10.0k
    newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
356
#else
357
    newloc = newlocale(LC_NUMERIC_MASK, "C", oldlocale);
358
#endif
359
10.0k
    if (newloc == NULL)
360
0
    {
361
0
      tok->err = json_tokener_error_memory;
362
0
#ifdef HAVE_DUPLOCALE
363
0
      freelocale(duploc);
364
0
#endif
365
0
      return NULL;
366
0
    }
367
#ifdef NEWLOCALE_NEEDS_FREELOCALE
368
#ifdef HAVE_DUPLOCALE
369
    // Older versions of FreeBSD (<12.4) don't free the locale
370
    // passed to newlocale(), so do it here
371
    freelocale(duploc);
372
#endif
373
#endif
374
10.0k
    uselocale(newloc);
375
10.0k
  }
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.46M
    case json_tokener_state_eatws:
401
      /* Advance until we change state */
402
1.61M
      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.46M
      if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
408
2.50k
      {
409
2.50k
        printbuf_reset(tok->pb);
410
2.50k
        printbuf_memappend_checked(tok->pb, &c, 1);
411
2.50k
        state = json_tokener_state_comment_start;
412
2.50k
      }
413
1.45M
      else
414
1.45M
      {
415
1.45M
        state = saved_state;
416
1.45M
        goto redo_char;
417
1.45M
      }
418
2.50k
      break;
419
420
305k
    case json_tokener_state_start:
421
305k
      switch (c)
422
305k
      {
423
55.7k
      case '{':
424
55.7k
        state = json_tokener_state_eatws;
425
55.7k
        saved_state = json_tokener_state_object_field_start;
426
55.7k
        current = json_object_new_object();
427
55.7k
        if (current == NULL)
428
0
        {
429
0
          tok->err = json_tokener_error_memory;
430
0
          goto out;
431
0
        }
432
55.7k
        break;
433
55.7k
      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
767
      case 'i':
445
767
        state = json_tokener_state_inf;
446
767
        printbuf_reset(tok->pb);
447
767
        tok->st_pos = 0;
448
767
        goto redo_char;
449
1.00k
      case 'N':
450
13.6k
      case 'n':
451
13.6k
        state = json_tokener_state_null; // or NaN
452
13.6k
        printbuf_reset(tok->pb);
453
13.6k
        tok->st_pos = 0;
454
13.6k
        goto redo_char;
455
507
      case '\'':
456
507
        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
71.1k
      case '"':
464
71.1k
        state = json_tokener_state_string;
465
71.1k
        printbuf_reset(tok->pb);
466
71.1k
        tok->quote_char = c;
467
71.1k
        break;
468
692
      case 'T':
469
1.20k
      case 't':
470
1.34k
      case 'F':
471
1.76k
      case 'f':
472
1.76k
        state = json_tokener_state_boolean;
473
1.76k
        printbuf_reset(tok->pb);
474
1.76k
        tok->st_pos = 0;
475
1.76k
        goto redo_char;
476
22.2k
      case '0':
477
29.6k
      case '1':
478
33.1k
      case '2':
479
34.7k
      case '3':
480
37.3k
      case '4':
481
140k
      case '5':
482
141k
      case '6':
483
142k
      case '7':
484
142k
      case '8':
485
144k
      case '9':
486
147k
      case '-':
487
147k
        state = json_tokener_state_number;
488
147k
        printbuf_reset(tok->pb);
489
147k
        tok->is_double = 0;
490
147k
        goto redo_char;
491
140
      default: tok->err = json_tokener_error_parse_unexpected; goto out;
492
305k
      }
493
141k
      break;
494
495
298k
    case json_tokener_state_finish:
496
298k
      if (tok->depth == 0)
497
7.72k
        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.20k
    case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
504
1.20k
    {
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.20k
      int is_negative = 0;
513
514
      /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
515
10.2k
      while (tok->st_pos < (int)json_inf_str_len)
516
9.11k
      {
517
9.11k
        char inf_char = *str;
518
9.11k
        if (inf_char != json_inf_str[tok->st_pos] &&
519
4.10k
            ((tok->flags & JSON_TOKENER_STRICT) ||
520
4.10k
              inf_char != json_inf_str_invert[tok->st_pos])
521
9.11k
           )
522
97
        {
523
97
          tok->err = json_tokener_error_parse_unexpected;
524
97
          goto out;
525
97
        }
526
9.01k
        tok->st_pos++;
527
9.01k
        (void)ADVANCE_CHAR(str, tok);
528
9.01k
        if (!PEEK_CHAR(c, tok))
529
0
        {
530
          /* out of input chars, for now at least */
531
0
          goto out;
532
0
        }
533
9.01k
      }
534
      /* We checked the full length of "Infinity", so create the object.
535
       * When handling -Infinity, the number parsing code will have dropped
536
       * the "-" into tok->pb for us, so check it now.
537
       */
538
1.10k
      if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
539
407
      {
540
407
        is_negative = 1;
541
407
      }
542
1.10k
      current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
543
1.10k
      if (current == NULL)
544
0
      {
545
0
        tok->err = json_tokener_error_memory;
546
0
        goto out;
547
0
      }
548
1.10k
      saved_state = json_tokener_state_finish;
549
1.10k
      state = json_tokener_state_eatws;
550
1.10k
      goto redo_char;
551
1.10k
    }
552
0
    break;
553
67.3k
    case json_tokener_state_null: /* aka starts with 'n' */
554
67.3k
    {
555
67.3k
      int size;
556
67.3k
      int size_nan;
557
67.3k
      printbuf_memappend_checked(tok->pb, &c, 1);
558
67.3k
      size = json_min(tok->st_pos + 1, json_null_str_len);
559
67.3k
      size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
560
67.3k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
561
67.3k
           strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
562
1.47k
          (strncmp(json_null_str, tok->pb->buf, size) == 0))
563
65.8k
      {
564
65.8k
        if (tok->st_pos == json_null_str_len)
565
13.0k
        {
566
13.0k
          current = NULL;
567
13.0k
          saved_state = json_tokener_state_finish;
568
13.0k
          state = json_tokener_state_eatws;
569
13.0k
          goto redo_char;
570
13.0k
        }
571
65.8k
      }
572
1.47k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
573
1.47k
                strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
574
100
               (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
575
1.37k
      {
576
1.37k
        if (tok->st_pos == json_nan_str_len)
577
451
        {
578
451
          current = json_object_new_double(NAN);
579
451
          if (current == NULL)
580
0
          {
581
0
            tok->err = json_tokener_error_memory;
582
0
            goto out;
583
0
          }
584
451
          saved_state = json_tokener_state_finish;
585
451
          state = json_tokener_state_eatws;
586
451
          goto redo_char;
587
451
        }
588
1.37k
      }
589
100
      else
590
100
      {
591
100
        tok->err = json_tokener_error_parse_null;
592
100
        goto out;
593
100
      }
594
53.7k
      tok->st_pos++;
595
53.7k
    }
596
0
    break;
597
598
2.50k
    case json_tokener_state_comment_start:
599
2.50k
      if (c == '*')
600
691
      {
601
691
        state = json_tokener_state_comment;
602
691
      }
603
1.80k
      else if (c == '/')
604
1.73k
      {
605
1.73k
        state = json_tokener_state_comment_eol;
606
1.73k
      }
607
72
      else
608
72
      {
609
72
        tok->err = json_tokener_error_parse_comment;
610
72
        goto out;
611
72
      }
612
2.42k
      printbuf_memappend_checked(tok->pb, &c, 1);
613
2.42k
      break;
614
615
3.33k
    case json_tokener_state_comment:
616
3.33k
    {
617
      /* Advance until we change state */
618
3.33k
      const char *case_start = str;
619
555k
      while (c != '*')
620
552k
      {
621
552k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
622
167
        {
623
167
          printbuf_memappend_checked(tok->pb, case_start,
624
167
                                     str - case_start);
625
167
          goto out;
626
167
        }
627
552k
      }
628
3.16k
      printbuf_memappend_checked(tok->pb, case_start, 1 + str - case_start);
629
3.16k
      state = json_tokener_state_comment_end;
630
3.16k
    }
631
0
    break;
632
633
1.73k
    case json_tokener_state_comment_eol:
634
1.73k
    {
635
      /* Advance until we change state */
636
1.73k
      const char *case_start = str;
637
242k
      while (c != '\n')
638
240k
      {
639
240k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
640
137
        {
641
137
          printbuf_memappend_checked(tok->pb, case_start,
642
137
                                     str - case_start);
643
137
          goto out;
644
137
        }
645
240k
      }
646
1.60k
      printbuf_memappend_checked(tok->pb, case_start, str - case_start);
647
1.60k
      MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
648
1.60k
      state = json_tokener_state_eatws;
649
1.60k
    }
650
0
    break;
651
652
3.16k
    case json_tokener_state_comment_end:
653
3.16k
      printbuf_memappend_checked(tok->pb, &c, 1);
654
3.16k
      if (c == '/')
655
517
      {
656
517
        MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
657
517
        state = json_tokener_state_eatws;
658
517
      }
659
2.65k
      else
660
2.65k
      {
661
2.65k
        state = json_tokener_state_comment;
662
2.65k
      }
663
3.16k
      break;
664
665
104k
    case json_tokener_state_string:
666
104k
    {
667
      /* Advance until we change state */
668
104k
      const char *case_start = str;
669
1.83M
      while (1)
670
1.83M
      {
671
1.83M
        if (c == tok->quote_char)
672
70.8k
        {
673
70.8k
          printbuf_memappend_checked(tok->pb, case_start,
674
70.8k
                                     str - case_start);
675
70.8k
          current =
676
70.8k
              json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
677
70.8k
          if (current == NULL)
678
0
          {
679
0
            tok->err = json_tokener_error_memory;
680
0
            goto out;
681
0
          }
682
70.8k
          saved_state = json_tokener_state_finish;
683
70.8k
          state = json_tokener_state_eatws;
684
70.8k
          break;
685
70.8k
        }
686
1.76M
        else if (c == '\\')
687
33.8k
        {
688
33.8k
          printbuf_memappend_checked(tok->pb, case_start,
689
33.8k
                                     str - case_start);
690
33.8k
          saved_state = json_tokener_state_string;
691
33.8k
          state = json_tokener_state_string_escape;
692
33.8k
          break;
693
33.8k
        }
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
250
        {
702
250
          printbuf_memappend_checked(tok->pb, case_start,
703
250
                                     str - case_start);
704
250
          goto out;
705
250
        }
706
1.73M
      }
707
104k
    }
708
104k
    break;
709
710
104k
    case json_tokener_state_string_escape:
711
43.9k
      switch (c)
712
43.9k
      {
713
7.30k
      case '"':
714
24.5k
      case '\\':
715
24.8k
      case '/':
716
24.8k
        printbuf_memappend_checked(tok->pb, &c, 1);
717
24.8k
        state = saved_state;
718
24.8k
        break;
719
797
      case 'b':
720
13.4k
      case 'n':
721
13.9k
      case 'r':
722
14.9k
      case 't':
723
15.3k
      case 'f':
724
15.3k
        if (c == 'b')
725
797
          printbuf_memappend_checked(tok->pb, "\b", 1);
726
14.5k
        else if (c == 'n')
727
12.6k
          printbuf_memappend_checked(tok->pb, "\n", 1);
728
1.93k
        else if (c == 'r')
729
547
          printbuf_memappend_checked(tok->pb, "\r", 1);
730
1.39k
        else if (c == 't')
731
921
          printbuf_memappend_checked(tok->pb, "\t", 1);
732
470
        else if (c == 'f')
733
470
          printbuf_memappend_checked(tok->pb, "\f", 1);
734
15.3k
        state = saved_state;
735
15.3k
        break;
736
3.66k
      case 'u':
737
3.66k
        tok->ucs_char = 0;
738
3.66k
        tok->st_pos = 0;
739
3.66k
        state = json_tokener_state_escape_unicode;
740
3.66k
        break;
741
46
      default: tok->err = json_tokener_error_parse_string; goto out;
742
43.9k
      }
743
43.8k
      break;
744
745
      // ===================================================
746
747
43.8k
    case json_tokener_state_escape_unicode:
748
4.67k
    {
749
      /* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */
750
18.5k
      while (1)
751
18.5k
      {
752
18.5k
        if (!c || !is_hex_char(c))
753
71
        {
754
71
          tok->err = json_tokener_error_parse_string;
755
71
          goto out;
756
71
        }
757
18.5k
        tok->ucs_char |=
758
18.5k
            ((unsigned int)jt_hexdigit(c) << ((3 - tok->st_pos) * 4));
759
18.5k
        tok->st_pos++;
760
18.5k
        if (tok->st_pos >= 4)
761
4.60k
          break;
762
763
13.8k
        (void)ADVANCE_CHAR(str, tok);
764
13.8k
        if (!PEEK_CHAR(c, tok))
765
0
        {
766
          /*
767
           * We're out of characters in the current call to
768
           * json_tokener_parse(), but a subsequent call might
769
           * provide us with more, so leave our current state
770
           * as-is (including tok->high_surrogate) and return.
771
           */
772
0
          goto out;
773
0
        }
774
13.8k
      }
775
4.60k
      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.60k
      if (tok->high_surrogate)
781
1.00k
      {
782
1.00k
        if (IS_LOW_SURROGATE(tok->ucs_char))
783
466
        {
784
          /* Recalculate the ucs_char, then fall thru to process normally */
785
466
          tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate,
786
466
                                                tok->ucs_char);
787
466
        }
788
540
        else
789
540
        {
790
          /* High surrogate was not followed by a low surrogate
791
           * Replace the high and process the rest normally
792
           */
793
540
          printbuf_memappend_checked(tok->pb,
794
540
                                     (char *)utf8_replacement_char, 3);
795
540
        }
796
1.00k
        tok->high_surrogate = 0;
797
1.00k
      }
798
799
4.60k
      if (tok->ucs_char < 0x80)
800
959
      {
801
959
        unsigned char unescaped_utf[1];
802
959
        unescaped_utf[0] = tok->ucs_char;
803
959
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 1);
804
959
      }
805
3.64k
      else if (tok->ucs_char < 0x800)
806
385
      {
807
385
        unsigned char unescaped_utf[2];
808
385
        unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
809
385
        unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
810
385
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 2);
811
385
      }
812
3.26k
      else if (IS_HIGH_SURROGATE(tok->ucs_char))
813
1.75k
      {
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.75k
        tok->high_surrogate = tok->ucs_char;
829
1.75k
        tok->ucs_char = 0;
830
1.75k
        state = json_tokener_state_escape_unicode_need_escape;
831
1.75k
        break;
832
1.75k
      }
833
1.50k
      else if (IS_LOW_SURROGATE(tok->ucs_char))
834
473
      {
835
        /* Got a low surrogate not preceded by a high */
836
473
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
837
473
      }
838
1.03k
      else if (tok->ucs_char < 0x10000)
839
568
      {
840
568
        unsigned char unescaped_utf[3];
841
568
        unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
842
568
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
843
568
        unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
844
568
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 3);
845
568
      }
846
466
      else if (tok->ucs_char < 0x110000)
847
466
      {
848
466
        unsigned char unescaped_utf[4];
849
466
        unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
850
466
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
851
466
        unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
852
466
        unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
853
466
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 4);
854
466
      }
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.85k
      state = saved_state; // i.e. _state_string or _state_object_field
861
2.85k
    }
862
0
    break;
863
864
1.75k
    case json_tokener_state_escape_unicode_need_escape:
865
      // We get here after processing a high_surrogate
866
      // require a '\\' char
867
1.75k
      if (!c || c != '\\')
868
427
      {
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
427
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
874
427
        tok->high_surrogate = 0;
875
427
        tok->ucs_char = 0;
876
427
        tok->st_pos = 0;
877
427
        state = saved_state;
878
427
        goto redo_char;
879
427
      }
880
1.32k
      state = json_tokener_state_escape_unicode_need_u;
881
1.32k
      break;
882
883
1.32k
    case json_tokener_state_escape_unicode_need_u:
884
      /* We already had a \ char, check that it's \u */
885
1.32k
      if (!c || c != 'u')
886
315
      {
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
315
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
893
315
        tok->high_surrogate = 0;
894
315
        tok->ucs_char = 0;
895
315
        tok->st_pos = 0;
896
315
        state = json_tokener_state_string_escape;
897
315
        goto redo_char;
898
315
      }
899
1.01k
      state = json_tokener_state_escape_unicode;
900
1.01k
      break;
901
902
      // ===================================================
903
904
8.96k
    case json_tokener_state_boolean:
905
8.96k
    {
906
8.96k
      int size1, size2;
907
8.96k
      printbuf_memappend_checked(tok->pb, &c, 1);
908
8.96k
      size1 = json_min(tok->st_pos + 1, json_true_str_len);
909
8.96k
      size2 = json_min(tok->st_pos + 1, json_false_str_len);
910
8.96k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
911
8.96k
           strncasecmp(json_true_str, tok->pb->buf, size1) == 0) ||
912
3.21k
          (strncmp(json_true_str, tok->pb->buf, size1) == 0))
913
5.74k
      {
914
5.74k
        if (tok->st_pos == json_true_str_len)
915
1.12k
        {
916
1.12k
          current = json_object_new_boolean(1);
917
1.12k
          if (current == NULL)
918
0
          {
919
0
            tok->err = json_tokener_error_memory;
920
0
            goto out;
921
0
          }
922
1.12k
          saved_state = json_tokener_state_finish;
923
1.12k
          state = json_tokener_state_eatws;
924
1.12k
          goto redo_char;
925
1.12k
        }
926
5.74k
      }
927
3.21k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
928
3.21k
                strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
929
153
               (strncmp(json_false_str, tok->pb->buf, size2) == 0))
930
3.06k
      {
931
3.06k
        if (tok->st_pos == json_false_str_len)
932
486
        {
933
486
          current = json_object_new_boolean(0);
934
486
          if (current == NULL)
935
0
          {
936
0
            tok->err = json_tokener_error_memory;
937
0
            goto out;
938
0
          }
939
486
          saved_state = json_tokener_state_finish;
940
486
          state = json_tokener_state_eatws;
941
486
          goto redo_char;
942
486
        }
943
3.06k
      }
944
153
      else
945
153
      {
946
153
        tok->err = json_tokener_error_parse_boolean;
947
153
        goto out;
948
153
      }
949
7.20k
      tok->st_pos++;
950
7.20k
    }
951
0
    break;
952
953
147k
    case json_tokener_state_number:
954
147k
    {
955
      /* Advance until we change state */
956
147k
      const char *case_start = str;
957
147k
      int case_len = 0;
958
147k
      int is_exponent = 0;
959
147k
      int neg_sign_ok = 1;
960
147k
      int pos_sign_ok = 0;
961
147k
      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
409k
      while (c && ((c >= '0' && c <= '9') ||
986
155k
                   (!is_exponent && (c == 'e' || c == 'E')) ||
987
153k
                   (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') ||
988
148k
                   (!tok->is_double && c == '.')))
989
261k
      {
990
261k
        pos_sign_ok = neg_sign_ok = 0;
991
261k
        ++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
261k
        switch (c)
1000
261k
        {
1001
778
        case '.':
1002
778
          tok->is_double = 1;
1003
778
          pos_sign_ok = 1;
1004
778
          neg_sign_ok = 1;
1005
778
          break;
1006
1.70k
        case 'e': /* FALLTHRU */
1007
2.79k
        case 'E':
1008
2.79k
          is_exponent = 1;
1009
2.79k
          tok->is_double = 1;
1010
          /* the exponent part can begin with a negative sign */
1011
2.79k
          pos_sign_ok = neg_sign_ok = 1;
1012
2.79k
          break;
1013
258k
        default: break;
1014
261k
        }
1015
1016
261k
        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
261k
      }
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
147k
      if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
1031
3.24k
          c != 'I' && c != 'i' && !is_ws_char(c))
1032
267
      {
1033
267
        tok->err = json_tokener_error_parse_number;
1034
267
        goto out;
1035
267
      }
1036
147k
      if (case_len > 0)
1037
147k
        printbuf_memappend_checked(tok->pb, case_start, case_len);
1038
1039
      // Check for -Infinity
1040
147k
      if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
1041
434
      {
1042
434
        state = json_tokener_state_inf;
1043
434
        tok->st_pos = 0;
1044
434
        goto redo_char;
1045
434
      }
1046
146k
      if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
1047
3.08k
      {
1048
        /* Trim some chars off the end, to allow things
1049
           like "123e+" to parse ok. */
1050
6.96k
        while (printbuf_length(tok->pb) > 1)
1051
5.43k
        {
1052
5.43k
          char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1];
1053
5.43k
          if (last_char != 'e' && last_char != 'E' &&
1054
3.28k
              last_char != '-' && last_char != '+')
1055
1.55k
          {
1056
1.55k
            break;
1057
1.55k
          }
1058
3.88k
          tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0';
1059
3.88k
          printbuf_length(tok->pb)--;
1060
3.88k
        }
1061
3.08k
      }
1062
146k
    }
1063
0
      {
1064
146k
        int64_t num64;
1065
146k
        uint64_t numuint64;
1066
146k
        double numd;
1067
146k
        if (!tok->is_double && tok->pb->buf[0] == '-' &&
1068
2.22k
            json_parse_int64(tok->pb->buf, &num64) == 0)
1069
2.20k
        {
1070
2.20k
          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.20k
          current = json_object_new_int64(num64);
1076
2.20k
          if (current == NULL)
1077
0
          {
1078
0
            tok->err = json_tokener_error_memory;
1079
0
            goto out;
1080
0
          }
1081
2.20k
        }
1082
144k
        else if (!tok->is_double && tok->pb->buf[0] != '-' &&
1083
141k
                 json_parse_uint64(tok->pb->buf, &numuint64) == 0)
1084
141k
        {
1085
141k
          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
141k
          if (numuint64 && tok->pb->buf[0] == '0' &&
1091
2.63k
              (tok->flags & JSON_TOKENER_STRICT))
1092
0
          {
1093
0
            tok->err = json_tokener_error_parse_number;
1094
0
            goto out;
1095
0
          }
1096
141k
          if (numuint64 <= INT64_MAX)
1097
140k
          {
1098
140k
            num64 = (uint64_t)numuint64;
1099
140k
            current = json_object_new_int64(num64);
1100
140k
            if (current == NULL)
1101
0
            {
1102
0
              tok->err = json_tokener_error_memory;
1103
0
              goto out;
1104
0
            }
1105
140k
          }
1106
654
          else
1107
654
          {
1108
654
            current = json_object_new_uint64(numuint64);
1109
654
            if (current == NULL)
1110
0
            {
1111
0
              tok->err = json_tokener_error_memory;
1112
0
              goto out;
1113
0
            }
1114
654
          }
1115
141k
        }
1116
3.10k
        else if (tok->is_double &&
1117
3.08k
                 json_tokener_parse_double(
1118
3.08k
                     tok->pb->buf, printbuf_length(tok->pb), &numd) == 0)
1119
3.07k
        {
1120
3.07k
          current = json_object_new_double_s(numd, tok->pb->buf);
1121
3.07k
          if (current == NULL)
1122
0
          {
1123
0
            tok->err = json_tokener_error_memory;
1124
0
            goto out;
1125
0
          }
1126
3.07k
        }
1127
37
        else
1128
37
        {
1129
37
          tok->err = json_tokener_error_parse_number;
1130
37
          goto out;
1131
37
        }
1132
146k
        saved_state = json_tokener_state_finish;
1133
146k
        state = json_tokener_state_eatws;
1134
146k
        goto redo_char;
1135
146k
      }
1136
0
      break;
1137
1138
160k
    case json_tokener_state_array_after_sep:
1139
174k
    case json_tokener_state_array:
1140
174k
      if (c == ']')
1141
2.05k
      {
1142
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1143
2.05k
        json_object_array_shrink(current, 0);
1144
1145
2.05k
        if (state == json_tokener_state_array_after_sep &&
1146
678
            (tok->flags & JSON_TOKENER_STRICT))
1147
0
        {
1148
0
          tok->err = json_tokener_error_parse_unexpected;
1149
0
          goto out;
1150
0
        }
1151
2.05k
        saved_state = json_tokener_state_finish;
1152
2.05k
        state = json_tokener_state_eatws;
1153
2.05k
      }
1154
172k
      else
1155
172k
      {
1156
172k
        if (tok->depth >= tok->max_depth - 1)
1157
8
        {
1158
8
          tok->err = json_tokener_error_depth;
1159
8
          goto out;
1160
8
        }
1161
172k
        state = json_tokener_state_array_add;
1162
172k
        tok->depth++;
1163
172k
        json_tokener_reset_level(tok, tok->depth);
1164
172k
        goto redo_char;
1165
172k
      }
1166
2.05k
      break;
1167
1168
170k
    case json_tokener_state_array_add:
1169
170k
      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
170k
      saved_state = json_tokener_state_array_sep;
1175
170k
      state = json_tokener_state_eatws;
1176
170k
      goto redo_char;
1177
1178
170k
    case json_tokener_state_array_sep:
1179
170k
      if (c == ']')
1180
10.1k
      {
1181
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1182
10.1k
        json_object_array_shrink(current, 0);
1183
1184
10.1k
        saved_state = json_tokener_state_finish;
1185
10.1k
        state = json_tokener_state_eatws;
1186
10.1k
      }
1187
160k
      else if (c == ',')
1188
160k
      {
1189
160k
        saved_state = json_tokener_state_array_after_sep;
1190
160k
        state = json_tokener_state_eatws;
1191
160k
      }
1192
145
      else
1193
145
      {
1194
145
        tok->err = json_tokener_error_parse_array;
1195
145
        goto out;
1196
145
      }
1197
170k
      break;
1198
1199
170k
    case json_tokener_state_object_field_start:
1200
143k
    case json_tokener_state_object_field_start_after_sep:
1201
143k
      if (c == '}')
1202
20.5k
      {
1203
20.5k
        if (state == json_tokener_state_object_field_start_after_sep &&
1204
199
            (tok->flags & JSON_TOKENER_STRICT))
1205
0
        {
1206
0
          tok->err = json_tokener_error_parse_unexpected;
1207
0
          goto out;
1208
0
        }
1209
20.5k
        saved_state = json_tokener_state_finish;
1210
20.5k
        state = json_tokener_state_eatws;
1211
20.5k
      }
1212
123k
      else if (c == '"' || c == '\'')
1213
123k
      {
1214
123k
        tok->quote_char = c;
1215
123k
        printbuf_reset(tok->pb);
1216
123k
        state = json_tokener_state_object_field;
1217
123k
      }
1218
69
      else
1219
69
      {
1220
69
        tok->err = json_tokener_error_parse_object_key_name;
1221
69
        goto out;
1222
69
      }
1223
143k
      break;
1224
1225
143k
    case json_tokener_state_object_field:
1226
132k
    {
1227
      /* Advance until we change state */
1228
132k
      const char *case_start = str;
1229
1.87M
      while (1)
1230
1.87M
      {
1231
1.87M
        if (c == tok->quote_char)
1232
122k
        {
1233
122k
          printbuf_memappend_checked(tok->pb, case_start,
1234
122k
                                     str - case_start);
1235
122k
          obj_field_name = strdup(tok->pb->buf);
1236
122k
          if (obj_field_name == NULL)
1237
0
          {
1238
0
            tok->err = json_tokener_error_memory;
1239
0
            goto out;
1240
0
          }
1241
122k
          saved_state = json_tokener_state_object_field_end;
1242
122k
          state = json_tokener_state_eatws;
1243
122k
          break;
1244
122k
        }
1245
1.75M
        else if (c == '\\')
1246
9.72k
        {
1247
9.72k
          printbuf_memappend_checked(tok->pb, case_start,
1248
9.72k
                                     str - case_start);
1249
9.72k
          saved_state = json_tokener_state_object_field;
1250
9.72k
          state = json_tokener_state_string_escape;
1251
9.72k
          break;
1252
9.72k
        }
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
192
        {
1261
192
          printbuf_memappend_checked(tok->pb, case_start,
1262
192
                                     str - case_start);
1263
192
          goto out;
1264
192
        }
1265
1.74M
      }
1266
132k
    }
1267
132k
    break;
1268
1269
132k
    case json_tokener_state_object_field_end:
1270
122k
      if (c == ':')
1271
122k
      {
1272
122k
        saved_state = json_tokener_state_object_value;
1273
122k
        state = json_tokener_state_eatws;
1274
122k
      }
1275
134
      else
1276
134
      {
1277
134
        tok->err = json_tokener_error_parse_object_key_sep;
1278
134
        goto out;
1279
134
      }
1280
122k
      break;
1281
1282
122k
    case json_tokener_state_object_value:
1283
122k
      if (tok->depth >= tok->max_depth - 1)
1284
3
      {
1285
3
        tok->err = json_tokener_error_depth;
1286
3
        goto out;
1287
3
      }
1288
122k
      state = json_tokener_state_object_value_add;
1289
122k
      tok->depth++;
1290
122k
      json_tokener_reset_level(tok, tok->depth);
1291
122k
      goto redo_char;
1292
1293
120k
    case json_tokener_state_object_value_add:
1294
120k
      if (json_object_object_add(current, obj_field_name, obj) != 0)
1295
0
      {
1296
0
        tok->err = json_tokener_error_memory;
1297
0
        goto out;
1298
0
      }
1299
120k
      free(obj_field_name);
1300
120k
      obj_field_name = NULL;
1301
120k
      saved_state = json_tokener_state_object_sep;
1302
120k
      state = json_tokener_state_eatws;
1303
120k
      goto redo_char;
1304
1305
120k
    case json_tokener_state_object_sep:
1306
      /* { */
1307
120k
      if (c == '}')
1308
32.4k
      {
1309
32.4k
        saved_state = json_tokener_state_finish;
1310
32.4k
        state = json_tokener_state_eatws;
1311
32.4k
      }
1312
88.2k
      else if (c == ',')
1313
88.0k
      {
1314
88.0k
        saved_state = json_tokener_state_object_field_start_after_sep;
1315
88.0k
        state = json_tokener_state_eatws;
1316
88.0k
      }
1317
258
      else
1318
258
      {
1319
258
        tok->err = json_tokener_error_parse_object_value_sep;
1320
258
        goto out;
1321
258
      }
1322
120k
      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
10.0k
out:
1330
10.0k
  if ((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && (nBytes != 0))
1331
0
  {
1332
0
    tok->err = json_tokener_error_parse_utf8_string;
1333
0
  }
1334
10.0k
  if (c && (state == json_tokener_state_finish) && (tok->depth == 0) &&
1335
117
      (tok->flags & (JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS)) ==
1336
117
          JSON_TOKENER_STRICT)
1337
0
  {
1338
    /* unexpected char after JSON data */
1339
0
    tok->err = json_tokener_error_parse_unexpected;
1340
0
  }
1341
10.0k
  if (!c)
1342
8.48k
  {
1343
    /* We hit an eof char (0) */
1344
8.48k
    if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
1345
792
      tok->err = json_tokener_error_parse_eof;
1346
8.48k
  }
1347
1348
10.0k
#ifdef HAVE_USELOCALE
1349
10.0k
  uselocale(oldlocale);
1350
10.0k
  freelocale(newloc);
1351
#elif defined(HAVE_SETLOCALE)
1352
  setlocale(LC_NUMERIC, oldlocale);
1353
  free(oldlocale);
1354
#endif
1355
1356
10.0k
  if (tok->err == json_tokener_success)
1357
7.81k
  {
1358
7.81k
    json_object *ret = json_object_get(current);
1359
7.81k
    int ii;
1360
1361
    /* Partially reset, so we parse additional objects on subsequent calls. */
1362
16.0k
    for (ii = tok->depth; ii >= 0; ii--)
1363
8.19k
      json_tokener_reset_level(tok, ii);
1364
7.81k
    return ret;
1365
7.81k
  }
1366
1367
2.26k
  MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
1368
2.26k
           tok->char_offset);
1369
2.26k
  return NULL;
1370
10.0k
}
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.08k
{
1411
3.08k
  char *end;
1412
3.08k
  *retval = strtod(buf, &end);
1413
3.08k
  if (buf + len == end)
1414
3.07k
    return 0; // It worked
1415
15
  return 1;
1416
3.08k
}