Coverage Report

Created: 2026-06-08 06:07

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
861k
{
71
861k
  return c == ' '
72
706k
      || c == '\t'
73
685k
      || c == '\n'
74
682k
      || c == '\r';
75
861k
}
76
77
static inline int is_hex_char(char c)
78
10.9k
{
79
10.9k
  return (c >= '0' && c <= '9')
80
3.61k
      || (c >= 'A' && c <= 'F')
81
229
      || (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
382
{
134
382
  int jerr_int = (int)jerr;
135
382
  if (jerr_int < 0 ||
136
382
      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
382
  return json_tokener_errors[jerr];
140
382
}
141
142
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok)
143
764
{
144
764
  return tok->err;
145
764
}
146
147
/* Stuff for decoding unicode sequences */
148
1.86k
#define IS_HIGH_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xD800)
149
1.60k
#define IS_LOW_SURROGATE(uc) (((uc)&0xFFFFFC00) == 0xDC00)
150
278
#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
5.46k
{
155
5.46k
  struct json_tokener *tok;
156
157
5.46k
  if (depth < 1)
158
0
    return NULL;
159
160
5.46k
  tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
161
5.46k
  if (!tok)
162
0
    return NULL;
163
5.46k
  tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
164
5.46k
  if (!tok->stack)
165
0
  {
166
0
    free(tok);
167
0
    return NULL;
168
0
  }
169
5.46k
  tok->pb = printbuf_new();
170
5.46k
  if (!tok->pb)
171
0
  {
172
0
    free(tok->stack);
173
0
    free(tok);
174
0
    return NULL;
175
0
  }
176
5.46k
  tok->max_depth = depth;
177
5.46k
  json_tokener_reset(tok);
178
5.46k
  return tok;
179
5.46k
}
180
181
struct json_tokener *json_tokener_new(void)
182
5.46k
{
183
5.46k
  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
184
5.46k
}
185
186
void json_tokener_free(struct json_tokener *tok)
187
5.46k
{
188
5.46k
  if (!tok)
189
0
    return;
190
5.46k
  json_tokener_reset(tok);
191
5.46k
  if (tok->pb)
192
5.46k
    printbuf_free(tok->pb);
193
5.46k
  free(tok->stack);
194
5.46k
  free(tok);
195
5.46k
}
196
197
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
198
253k
{
199
253k
  tok->stack[depth].state = json_tokener_state_eatws;
200
253k
  tok->stack[depth].saved_state = json_tokener_state_start;
201
253k
  json_object_put(tok->stack[depth].current);
202
253k
  tok->stack[depth].current = NULL;
203
253k
  free(tok->stack[depth].obj_field_name);
204
253k
  tok->stack[depth].obj_field_name = NULL;
205
253k
}
206
207
void json_tokener_reset(struct json_tokener *tok)
208
10.9k
{
209
10.9k
  int i;
210
10.9k
  if (!tok)
211
0
    return;
212
213
22.7k
  for (i = tok->depth; i >= 0; i--)
214
11.8k
    json_tokener_reset_level(tok, i);
215
10.9k
  tok->depth = 0;
216
10.9k
  tok->err = json_tokener_success;
217
10.9k
}
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.41M
#define state tok->stack[tok->depth].state
262
1.34M
#define saved_state tok->stack[tok->depth].saved_state
263
495k
#define current tok->stack[tok->depth].current
264
454k
#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.24M
  (((tok)->char_offset == len)                                         \
286
3.24M
       ? (((tok)->depth == 0 && state == json_tokener_state_eatws &&   \
287
0
           saved_state == json_tokener_state_finish)                   \
288
0
              ? (((tok)->err = json_tokener_success), 0)               \
289
0
              : (((tok)->err = json_tokener_continue), 0))             \
290
3.24M
       : (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) &&                \
291
3.24M
           (!json_tokener_validate_utf8(*str, nBytesp)))               \
292
3.24M
              ? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
293
3.24M
              : (((dest) = *str), 1)))
294
295
/* ADVANCE_CHAR() macro:
296
 *   Increments str & tok->char_offset.
297
 *   For convenience of existing conditionals, returns the old value of c (0 on eof).
298
 *   Implicit inputs:  c var
299
 */
300
5.58M
#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
277k
  do {                                                  \
308
277k
    if (printbuf_memappend((p), (s), (l)) < 0)    \
309
277k
    {                                             \
310
0
      tok->err = json_tokener_error_memory; \
311
0
      goto out;                             \
312
0
    }                                             \
313
277k
  } 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
5.46k
{
319
5.46k
  struct json_object *obj = NULL;
320
5.46k
  char c = '\1';
321
5.46k
  unsigned int nBytes = 0;
322
5.46k
  unsigned int *nBytesp = &nBytes;
323
324
5.46k
#ifdef HAVE_USELOCALE
325
5.46k
  locale_t oldlocale = uselocale(NULL);
326
5.46k
  locale_t newloc;
327
#elif defined(HAVE_SETLOCALE)
328
  char *oldlocale = NULL;
329
#endif
330
331
5.46k
  tok->char_offset = 0;
332
5.46k
  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
5.46k
  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
5.46k
#ifdef HAVE_USELOCALE
347
5.46k
  {
348
5.46k
#ifdef HAVE_DUPLOCALE
349
5.46k
    locale_t duploc = duplocale(oldlocale);
350
5.46k
    if (duploc == NULL && errno == ENOMEM)
351
0
    {
352
0
      tok->err = json_tokener_error_memory;
353
0
      return NULL;
354
0
    }
355
5.46k
    newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
356
#else
357
    newloc = newlocale(LC_NUMERIC_MASK, "C", oldlocale);
358
#endif
359
5.46k
    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
5.46k
    uselocale(newloc);
375
5.46k
  }
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
702k
  while (PEEK_CHAR(c, tok)) // Note: c might be '\0' !
394
702k
  {
395
396
1.76M
  redo_char:
397
1.76M
    switch (state)
398
1.76M
    {
399
400
681k
    case json_tokener_state_eatws:
401
      /* Advance until we change state */
402
860k
      while (is_ws_char(c))
403
179k
      {
404
179k
        if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
405
0
          goto out;
406
179k
      }
407
681k
      if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
408
1.06k
      {
409
1.06k
        printbuf_reset(tok->pb);
410
1.06k
        printbuf_memappend_checked(tok->pb, &c, 1);
411
1.06k
        state = json_tokener_state_comment_start;
412
1.06k
      }
413
680k
      else
414
680k
      {
415
680k
        state = saved_state;
416
680k
        goto redo_char;
417
680k
      }
418
1.06k
      break;
419
420
123k
    case json_tokener_state_start:
421
123k
      switch (c)
422
123k
      {
423
40.2k
      case '{':
424
40.2k
        state = json_tokener_state_eatws;
425
40.2k
        saved_state = json_tokener_state_object_field_start;
426
40.2k
        current = json_object_new_object();
427
40.2k
        if (current == NULL)
428
0
        {
429
0
          tok->err = json_tokener_error_memory;
430
0
          goto out;
431
0
        }
432
40.2k
        break;
433
40.2k
      case '[':
434
8.47k
        state = json_tokener_state_eatws;
435
8.47k
        saved_state = json_tokener_state_array;
436
8.47k
        current = json_object_new_array();
437
8.47k
        if (current == NULL)
438
0
        {
439
0
          tok->err = json_tokener_error_memory;
440
0
          goto out;
441
0
        }
442
8.47k
        break;
443
8.47k
      case 'I':
444
13
      case 'i':
445
13
        state = json_tokener_state_inf;
446
13
        printbuf_reset(tok->pb);
447
13
        tok->st_pos = 0;
448
13
        goto redo_char;
449
129
      case 'N':
450
375
      case 'n':
451
375
        state = json_tokener_state_null; // or NaN
452
375
        printbuf_reset(tok->pb);
453
375
        tok->st_pos = 0;
454
375
        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
63.5k
      case '"':
464
63.5k
        state = json_tokener_state_string;
465
63.5k
        printbuf_reset(tok->pb);
466
63.5k
        tok->quote_char = c;
467
63.5k
        break;
468
24
      case 'T':
469
66
      case 't':
470
195
      case 'F':
471
303
      case 'f':
472
303
        state = json_tokener_state_boolean;
473
303
        printbuf_reset(tok->pb);
474
303
        tok->st_pos = 0;
475
303
        goto redo_char;
476
2.42k
      case '0':
477
4.98k
      case '1':
478
5.92k
      case '2':
479
6.31k
      case '3':
480
7.66k
      case '4':
481
8.28k
      case '5':
482
8.41k
      case '6':
483
8.55k
      case '7':
484
8.62k
      case '8':
485
9.05k
      case '9':
486
10.9k
      case '-':
487
10.9k
        state = json_tokener_state_number;
488
10.9k
        printbuf_reset(tok->pb);
489
10.9k
        tok->is_double = 0;
490
10.9k
        goto redo_char;
491
77
      default: tok->err = json_tokener_error_parse_unexpected; goto out;
492
123k
      }
493
112k
      break;
494
495
122k
    case json_tokener_state_finish:
496
122k
      if (tok->depth == 0)
497
5.05k
        goto out;
498
117k
      obj = json_object_get(current);
499
117k
      json_tokener_reset_level(tok, tok->depth);
500
117k
      tok->depth--;
501
117k
      goto redo_char;
502
503
14
    case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
504
14
    {
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
14
      int is_negative = 0;
513
514
      /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
515
35
      while (tok->st_pos < (int)json_inf_str_len)
516
35
      {
517
35
        char inf_char = *str;
518
35
        if (inf_char != json_inf_str[tok->st_pos] &&
519
28
            ((tok->flags & JSON_TOKENER_STRICT) ||
520
28
              inf_char != json_inf_str_invert[tok->st_pos])
521
35
           )
522
14
        {
523
14
          tok->err = json_tokener_error_parse_unexpected;
524
14
          goto out;
525
14
        }
526
21
        tok->st_pos++;
527
21
        (void)ADVANCE_CHAR(str, tok);
528
21
        if (!PEEK_CHAR(c, tok))
529
0
        {
530
          /* out of input chars, for now at least */
531
0
          goto out;
532
0
        }
533
21
      }
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.69k
    case json_tokener_state_null: /* aka starts with 'n' */
554
1.69k
    {
555
1.69k
      int size;
556
1.69k
      int size_nan;
557
1.69k
      printbuf_memappend_checked(tok->pb, &c, 1);
558
1.69k
      size = json_min(tok->st_pos + 1, json_null_str_len);
559
1.69k
      size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
560
1.69k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
561
1.69k
           strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
562
396
          (strncmp(json_null_str, tok->pb->buf, size) == 0))
563
1.29k
      {
564
1.29k
        if (tok->st_pos == json_null_str_len)
565
228
        {
566
228
          current = NULL;
567
228
          saved_state = json_tokener_state_finish;
568
228
          state = json_tokener_state_eatws;
569
228
          goto redo_char;
570
228
        }
571
1.29k
      }
572
396
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
573
396
                strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
574
24
               (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
575
372
      {
576
372
        if (tok->st_pos == json_nan_str_len)
577
123
        {
578
123
          current = json_object_new_double(NAN);
579
123
          if (current == NULL)
580
0
          {
581
0
            tok->err = json_tokener_error_memory;
582
0
            goto out;
583
0
          }
584
123
          saved_state = json_tokener_state_finish;
585
123
          state = json_tokener_state_eatws;
586
123
          goto redo_char;
587
123
        }
588
372
      }
589
24
      else
590
24
      {
591
24
        tok->err = json_tokener_error_parse_null;
592
24
        goto out;
593
24
      }
594
1.31k
      tok->st_pos++;
595
1.31k
    }
596
0
    break;
597
598
1.06k
    case json_tokener_state_comment_start:
599
1.06k
      if (c == '*')
600
276
      {
601
276
        state = json_tokener_state_comment;
602
276
      }
603
787
      else if (c == '/')
604
772
      {
605
772
        state = json_tokener_state_comment_eol;
606
772
      }
607
15
      else
608
15
      {
609
15
        tok->err = json_tokener_error_parse_comment;
610
15
        goto out;
611
15
      }
612
1.04k
      printbuf_memappend_checked(tok->pb, &c, 1);
613
1.04k
      break;
614
615
1.38k
    case json_tokener_state_comment:
616
1.38k
    {
617
      /* Advance until we change state */
618
1.38k
      const char *case_start = str;
619
27.6k
      while (c != '*')
620
26.2k
      {
621
26.2k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
622
27
        {
623
27
          printbuf_memappend_checked(tok->pb, case_start,
624
27
                                     str - case_start);
625
27
          goto out;
626
27
        }
627
26.2k
      }
628
1.36k
      printbuf_memappend_checked(tok->pb, case_start, 1 + str - case_start);
629
1.36k
      state = json_tokener_state_comment_end;
630
1.36k
    }
631
0
    break;
632
633
772
    case json_tokener_state_comment_eol:
634
772
    {
635
      /* Advance until we change state */
636
772
      const char *case_start = str;
637
58.2k
      while (c != '\n')
638
57.5k
      {
639
57.5k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
640
38
        {
641
38
          printbuf_memappend_checked(tok->pb, case_start,
642
38
                                     str - case_start);
643
38
          goto out;
644
38
        }
645
57.5k
      }
646
734
      printbuf_memappend_checked(tok->pb, case_start, str - case_start);
647
734
      MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
648
734
      state = json_tokener_state_eatws;
649
734
    }
650
0
    break;
651
652
1.36k
    case json_tokener_state_comment_end:
653
1.36k
      printbuf_memappend_checked(tok->pb, &c, 1);
654
1.36k
      if (c == '/')
655
245
      {
656
245
        MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
657
245
        state = json_tokener_state_eatws;
658
245
      }
659
1.11k
      else
660
1.11k
      {
661
1.11k
        state = json_tokener_state_comment;
662
1.11k
      }
663
1.36k
      break;
664
665
107k
    case json_tokener_state_string:
666
107k
    {
667
      /* Advance until we change state */
668
107k
      const char *case_start = str;
669
1.60M
      while (1)
670
1.60M
      {
671
1.60M
        if (c == tok->quote_char)
672
63.5k
        {
673
63.5k
          printbuf_memappend_checked(tok->pb, case_start,
674
63.5k
                                     str - case_start);
675
63.5k
          current =
676
63.5k
              json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
677
63.5k
          if (current == NULL)
678
0
          {
679
0
            tok->err = json_tokener_error_memory;
680
0
            goto out;
681
0
          }
682
63.5k
          saved_state = json_tokener_state_finish;
683
63.5k
          state = json_tokener_state_eatws;
684
63.5k
          break;
685
63.5k
        }
686
1.53M
        else if (c == '\\')
687
43.7k
        {
688
43.7k
          printbuf_memappend_checked(tok->pb, case_start,
689
43.7k
                                     str - case_start);
690
43.7k
          saved_state = json_tokener_state_string;
691
43.7k
          state = json_tokener_state_string_escape;
692
43.7k
          break;
693
43.7k
        }
694
1.49M
        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.49M
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
701
37
        {
702
37
          printbuf_memappend_checked(tok->pb, case_start,
703
37
                                     str - case_start);
704
37
          goto out;
705
37
        }
706
1.49M
      }
707
107k
    }
708
107k
    break;
709
710
107k
    case json_tokener_state_string_escape:
711
51.2k
      switch (c)
712
51.2k
      {
713
9.85k
      case '"':
714
30.0k
      case '\\':
715
30.2k
      case '/':
716
30.2k
        printbuf_memappend_checked(tok->pb, &c, 1);
717
30.2k
        state = saved_state;
718
30.2k
        break;
719
762
      case 'b':
720
17.5k
      case 'n':
721
17.8k
      case 'r':
722
18.4k
      case 't':
723
18.7k
      case 'f':
724
18.7k
        if (c == 'b')
725
762
          printbuf_memappend_checked(tok->pb, "\b", 1);
726
17.9k
        else if (c == 'n')
727
16.7k
          printbuf_memappend_checked(tok->pb, "\n", 1);
728
1.21k
        else if (c == 'r')
729
288
          printbuf_memappend_checked(tok->pb, "\r", 1);
730
925
        else if (c == 't')
731
597
          printbuf_memappend_checked(tok->pb, "\t", 1);
732
328
        else if (c == 'f')
733
328
          printbuf_memappend_checked(tok->pb, "\f", 1);
734
18.7k
        state = saved_state;
735
18.7k
        break;
736
2.33k
      case 'u':
737
2.33k
        tok->ucs_char = 0;
738
2.33k
        tok->st_pos = 0;
739
2.33k
        state = json_tokener_state_escape_unicode;
740
2.33k
        break;
741
11
      default: tok->err = json_tokener_error_parse_string; goto out;
742
51.2k
      }
743
51.2k
      break;
744
745
      // ===================================================
746
747
51.2k
    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
13
        {
754
13
          tok->err = json_tokener_error_parse_string;
755
13
          goto out;
756
13
        }
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
417
      {
782
417
        if (IS_LOW_SURROGATE(tok->ucs_char))
783
278
        {
784
          /* Recalculate the ucs_char, then fall thru to process normally */
785
278
          tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate,
786
278
                                                tok->ucs_char);
787
278
        }
788
139
        else
789
139
        {
790
          /* High surrogate was not followed by a low surrogate
791
           * Replace the high and process the rest normally
792
           */
793
139
          printbuf_memappend_checked(tok->pb,
794
139
                                     (char *)utf8_replacement_char, 3);
795
139
        }
796
417
        tok->high_surrogate = 0;
797
417
      }
798
799
2.73k
      if (tok->ucs_char < 0x80)
800
833
      {
801
833
        unsigned char unescaped_utf[1];
802
833
        unescaped_utf[0] = tok->ucs_char;
803
833
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 1);
804
833
      }
805
1.90k
      else if (tok->ucs_char < 0x800)
806
40
      {
807
40
        unsigned char unescaped_utf[2];
808
40
        unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
809
40
        unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
810
40
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 2);
811
40
      }
812
1.86k
      else if (IS_HIGH_SURROGATE(tok->ucs_char))
813
674
      {
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
674
        tok->high_surrogate = tok->ucs_char;
829
674
        tok->ucs_char = 0;
830
674
        state = json_tokener_state_escape_unicode_need_escape;
831
674
        break;
832
674
      }
833
1.19k
      else if (IS_LOW_SURROGATE(tok->ucs_char))
834
420
      {
835
        /* Got a low surrogate not preceded by a high */
836
420
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
837
420
      }
838
772
      else if (tok->ucs_char < 0x10000)
839
494
      {
840
494
        unsigned char unescaped_utf[3];
841
494
        unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
842
494
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
843
494
        unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
844
494
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 3);
845
494
      }
846
278
      else if (tok->ucs_char < 0x110000)
847
278
      {
848
278
        unsigned char unescaped_utf[4];
849
278
        unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
850
278
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
851
278
        unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
852
278
        unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
853
278
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 4);
854
278
      }
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.06k
      state = saved_state; // i.e. _state_string or _state_object_field
861
2.06k
    }
862
0
    break;
863
864
674
    case json_tokener_state_escape_unicode_need_escape:
865
      // We get here after processing a high_surrogate
866
      // require a '\\' char
867
674
      if (!c || c != '\\')
868
152
      {
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
152
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
874
152
        tok->high_surrogate = 0;
875
152
        tok->ucs_char = 0;
876
152
        tok->st_pos = 0;
877
152
        state = saved_state;
878
152
        goto redo_char;
879
152
      }
880
522
      state = json_tokener_state_escape_unicode_need_u;
881
522
      break;
882
883
522
    case json_tokener_state_escape_unicode_need_u:
884
      /* We already had a \ char, check that it's \u */
885
522
      if (!c || c != 'u')
886
103
      {
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
103
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
893
103
        tok->high_surrogate = 0;
894
103
        tok->ucs_char = 0;
895
103
        tok->st_pos = 0;
896
103
        state = json_tokener_state_string_escape;
897
103
        goto redo_char;
898
103
      }
899
419
      state = json_tokener_state_escape_unicode;
900
419
      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.40k
          (strncmp(json_true_str, tok->pb->buf, size1) == 0))
913
278
      {
914
278
        if (tok->st_pos == json_true_str_len)
915
52
        {
916
52
          current = json_object_new_boolean(1);
917
52
          if (current == NULL)
918
0
          {
919
0
            tok->err = json_tokener_error_memory;
920
0
            goto out;
921
0
          }
922
52
          saved_state = json_tokener_state_finish;
923
52
          state = json_tokener_state_eatws;
924
52
          goto redo_char;
925
52
        }
926
278
      }
927
1.40k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
928
1.40k
                strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
929
25
               (strncmp(json_false_str, tok->pb->buf, size2) == 0))
930
1.37k
      {
931
1.37k
        if (tok->st_pos == json_false_str_len)
932
226
        {
933
226
          current = json_object_new_boolean(0);
934
226
          if (current == NULL)
935
0
          {
936
0
            tok->err = json_tokener_error_memory;
937
0
            goto out;
938
0
          }
939
226
          saved_state = json_tokener_state_finish;
940
226
          state = json_tokener_state_eatws;
941
226
          goto redo_char;
942
226
        }
943
1.37k
      }
944
25
      else
945
25
      {
946
25
        tok->err = json_tokener_error_parse_boolean;
947
25
        goto out;
948
25
      }
949
1.37k
      tok->st_pos++;
950
1.37k
    }
951
0
    break;
952
953
10.9k
    case json_tokener_state_number:
954
10.9k
    {
955
      /* Advance until we change state */
956
10.9k
      const char *case_start = str;
957
10.9k
      int case_len = 0;
958
10.9k
      int is_exponent = 0;
959
10.9k
      int neg_sign_ok = 1;
960
10.9k
      int pos_sign_ok = 0;
961
10.9k
      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
78.8k
      while (c && ((c >= '0' && c <= '9') ||
986
13.9k
                   (!is_exponent && (c == 'e' || c == 'E')) ||
987
13.5k
                   (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') ||
988
11.3k
                   (!tok->is_double && c == '.')))
989
67.8k
      {
990
67.8k
        pos_sign_ok = neg_sign_ok = 0;
991
67.8k
        ++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
67.8k
        switch (c)
1000
67.8k
        {
1001
393
        case '.':
1002
393
          tok->is_double = 1;
1003
393
          pos_sign_ok = 1;
1004
393
          neg_sign_ok = 1;
1005
393
          break;
1006
369
        case 'e': /* FALLTHRU */
1007
402
        case 'E':
1008
402
          is_exponent = 1;
1009
402
          tok->is_double = 1;
1010
          /* the exponent part can begin with a negative sign */
1011
402
          pos_sign_ok = neg_sign_ok = 1;
1012
402
          break;
1013
67.0k
        default: break;
1014
67.8k
        }
1015
1016
67.8k
        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
67.8k
      }
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.9k
      if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
1031
802
          c != 'I' && c != 'i' && !is_ws_char(c))
1032
34
      {
1033
34
        tok->err = json_tokener_error_parse_number;
1034
34
        goto out;
1035
34
      }
1036
10.9k
      if (case_len > 0)
1037
10.9k
        printbuf_memappend_checked(tok->pb, case_start, case_len);
1038
1039
      // Check for -Infinity
1040
10.9k
      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.9k
      if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
1047
467
      {
1048
        /* Trim some chars off the end, to allow things
1049
           like "123e+" to parse ok. */
1050
1.02k
        while (printbuf_length(tok->pb) > 1)
1051
1.00k
        {
1052
1.00k
          char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1];
1053
1.00k
          if (last_char != 'e' && last_char != 'E' &&
1054
702
              last_char != '-' && last_char != '+')
1055
445
          {
1056
445
            break;
1057
445
          }
1058
559
          tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0';
1059
559
          printbuf_length(tok->pb)--;
1060
559
        }
1061
467
      }
1062
10.9k
    }
1063
0
      {
1064
10.9k
        int64_t num64;
1065
10.9k
        uint64_t numuint64;
1066
10.9k
        double numd;
1067
10.9k
        if (!tok->is_double && tok->pb->buf[0] == '-' &&
1068
1.50k
            json_parse_int64(tok->pb->buf, &num64) == 0)
1069
1.50k
        {
1070
1.50k
          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.50k
          current = json_object_new_int64(num64);
1076
1.50k
          if (current == NULL)
1077
0
          {
1078
0
            tok->err = json_tokener_error_memory;
1079
0
            goto out;
1080
0
          }
1081
1.50k
        }
1082
9.40k
        else if (!tok->is_double && tok->pb->buf[0] != '-' &&
1083
8.93k
                 json_parse_uint64(tok->pb->buf, &numuint64) == 0)
1084
8.93k
        {
1085
8.93k
          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.93k
          if (numuint64 && tok->pb->buf[0] == '0' &&
1091
1.68k
              (tok->flags & JSON_TOKENER_STRICT))
1092
0
          {
1093
0
            tok->err = json_tokener_error_parse_number;
1094
0
            goto out;
1095
0
          }
1096
8.93k
          if (numuint64 <= INT64_MAX)
1097
8.44k
          {
1098
8.44k
            num64 = (uint64_t)numuint64;
1099
8.44k
            current = json_object_new_int64(num64);
1100
8.44k
            if (current == NULL)
1101
0
            {
1102
0
              tok->err = json_tokener_error_memory;
1103
0
              goto out;
1104
0
            }
1105
8.44k
          }
1106
483
          else
1107
483
          {
1108
483
            current = json_object_new_uint64(numuint64);
1109
483
            if (current == NULL)
1110
0
            {
1111
0
              tok->err = json_tokener_error_memory;
1112
0
              goto out;
1113
0
            }
1114
483
          }
1115
8.93k
        }
1116
471
        else if (tok->is_double &&
1117
467
                 json_tokener_parse_double(
1118
467
                     tok->pb->buf, printbuf_length(tok->pb), &numd) == 0)
1119
466
        {
1120
466
          current = json_object_new_double_s(numd, tok->pb->buf);
1121
466
          if (current == NULL)
1122
0
          {
1123
0
            tok->err = json_tokener_error_memory;
1124
0
            goto out;
1125
0
          }
1126
466
        }
1127
5
        else
1128
5
        {
1129
5
          tok->err = json_tokener_error_parse_number;
1130
5
          goto out;
1131
5
        }
1132
10.9k
        saved_state = json_tokener_state_finish;
1133
10.9k
        state = json_tokener_state_eatws;
1134
10.9k
        goto redo_char;
1135
10.9k
      }
1136
0
      break;
1137
1138
19.1k
    case json_tokener_state_array_after_sep:
1139
27.5k
    case json_tokener_state_array:
1140
27.5k
      if (c == ']')
1141
256
      {
1142
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1143
256
        json_object_array_shrink(current, 0);
1144
1145
256
        if (state == json_tokener_state_array_after_sep &&
1146
19
            (tok->flags & JSON_TOKENER_STRICT))
1147
0
        {
1148
0
          tok->err = json_tokener_error_parse_unexpected;
1149
0
          goto out;
1150
0
        }
1151
256
        saved_state = json_tokener_state_finish;
1152
256
        state = json_tokener_state_eatws;
1153
256
      }
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
256
      break;
1167
1168
26.9k
    case json_tokener_state_array_add:
1169
26.9k
      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
26.9k
      saved_state = json_tokener_state_array_sep;
1175
26.9k
      state = json_tokener_state_eatws;
1176
26.9k
      goto redo_char;
1177
1178
26.9k
    case json_tokener_state_array_sep:
1179
26.9k
      if (c == ']')
1180
7.85k
      {
1181
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1182
7.85k
        json_object_array_shrink(current, 0);
1183
1184
7.85k
        saved_state = json_tokener_state_finish;
1185
7.85k
        state = json_tokener_state_eatws;
1186
7.85k
      }
1187
19.1k
      else if (c == ',')
1188
19.1k
      {
1189
19.1k
        saved_state = json_tokener_state_array_after_sep;
1190
19.1k
        state = json_tokener_state_eatws;
1191
19.1k
      }
1192
17
      else
1193
17
      {
1194
17
        tok->err = json_tokener_error_parse_array;
1195
17
        goto out;
1196
17
      }
1197
26.9k
      break;
1198
1199
40.2k
    case json_tokener_state_object_field_start:
1200
106k
    case json_tokener_state_object_field_start_after_sep:
1201
106k
      if (c == '}')
1202
15.1k
      {
1203
15.1k
        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
15.1k
        saved_state = json_tokener_state_finish;
1210
15.1k
        state = json_tokener_state_eatws;
1211
15.1k
      }
1212
91.2k
      else if (c == '"' || c == '\'')
1213
91.2k
      {
1214
91.2k
        tok->quote_char = c;
1215
91.2k
        printbuf_reset(tok->pb);
1216
91.2k
        state = json_tokener_state_object_field;
1217
91.2k
      }
1218
18
      else
1219
18
      {
1220
18
        tok->err = json_tokener_error_parse_object_key_name;
1221
18
        goto out;
1222
18
      }
1223
106k
      break;
1224
1225
106k
    case json_tokener_state_object_field:
1226
98.7k
    {
1227
      /* Advance until we change state */
1228
98.7k
      const char *case_start = str;
1229
805k
      while (1)
1230
805k
      {
1231
805k
        if (c == tok->quote_char)
1232
91.2k
        {
1233
91.2k
          printbuf_memappend_checked(tok->pb, case_start,
1234
91.2k
                                     str - case_start);
1235
91.2k
          obj_field_name = strdup(tok->pb->buf);
1236
91.2k
          if (obj_field_name == NULL)
1237
0
          {
1238
0
            tok->err = json_tokener_error_memory;
1239
0
            goto out;
1240
0
          }
1241
91.2k
          saved_state = json_tokener_state_object_field_end;
1242
91.2k
          state = json_tokener_state_eatws;
1243
91.2k
          break;
1244
91.2k
        }
1245
714k
        else if (c == '\\')
1246
7.45k
        {
1247
7.45k
          printbuf_memappend_checked(tok->pb, case_start,
1248
7.45k
                                     str - case_start);
1249
7.45k
          saved_state = json_tokener_state_object_field;
1250
7.45k
          state = json_tokener_state_string_escape;
1251
7.45k
          break;
1252
7.45k
        }
1253
706k
        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
706k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
1260
19
        {
1261
19
          printbuf_memappend_checked(tok->pb, case_start,
1262
19
                                     str - case_start);
1263
19
          goto out;
1264
19
        }
1265
706k
      }
1266
98.7k
    }
1267
98.6k
    break;
1268
1269
98.6k
    case json_tokener_state_object_field_end:
1270
91.2k
      if (c == ':')
1271
91.2k
      {
1272
91.2k
        saved_state = json_tokener_state_object_value;
1273
91.2k
        state = json_tokener_state_eatws;
1274
91.2k
      }
1275
20
      else
1276
20
      {
1277
20
        tok->err = json_tokener_error_parse_object_key_sep;
1278
20
        goto out;
1279
20
      }
1280
91.2k
      break;
1281
1282
91.2k
    case json_tokener_state_object_value:
1283
91.2k
      if (tok->depth >= tok->max_depth - 1)
1284
0
      {
1285
0
        tok->err = json_tokener_error_depth;
1286
0
        goto out;
1287
0
      }
1288
91.2k
      state = json_tokener_state_object_value_add;
1289
91.2k
      tok->depth++;
1290
91.2k
      json_tokener_reset_level(tok, tok->depth);
1291
91.2k
      goto redo_char;
1292
1293
90.6k
    case json_tokener_state_object_value_add:
1294
90.6k
      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
90.6k
      free(obj_field_name);
1300
90.6k
      obj_field_name = NULL;
1301
90.6k
      saved_state = json_tokener_state_object_sep;
1302
90.6k
      state = json_tokener_state_eatws;
1303
90.6k
      goto redo_char;
1304
1305
90.6k
    case json_tokener_state_object_sep:
1306
      /* { */
1307
90.6k
      if (c == '}')
1308
24.3k
      {
1309
24.3k
        saved_state = json_tokener_state_finish;
1310
24.3k
        state = json_tokener_state_eatws;
1311
24.3k
      }
1312
66.2k
      else if (c == ',')
1313
66.2k
      {
1314
66.2k
        saved_state = json_tokener_state_object_field_start_after_sep;
1315
66.2k
        state = json_tokener_state_eatws;
1316
66.2k
      }
1317
17
      else
1318
17
      {
1319
17
        tok->err = json_tokener_error_parse_object_value_sep;
1320
17
        goto out;
1321
17
      }
1322
90.6k
      break;
1323
1.76M
    }
1324
697k
    (void)ADVANCE_CHAR(str, tok);
1325
697k
    if (!c) // This is the char *before* advancing
1326
4
      break;
1327
697k
  } /* while(PEEK_CHAR) */
1328
1329
5.46k
out:
1330
5.46k
  if ((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && (nBytes != 0))
1331
0
  {
1332
0
    tok->err = json_tokener_error_parse_utf8_string;
1333
0
  }
1334
5.46k
  if (c && (state == json_tokener_state_finish) && (tok->depth == 0) &&
1335
53
      (tok->flags & (JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS)) ==
1336
53
          JSON_TOKENER_STRICT)
1337
0
  {
1338
    /* unexpected char after JSON data */
1339
0
    tok->err = json_tokener_error_parse_unexpected;
1340
0
  }
1341
5.46k
  if (!c)
1342
5.19k
  {
1343
    /* We hit an eof char (0) */
1344
5.19k
    if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
1345
165
      tok->err = json_tokener_error_parse_eof;
1346
5.19k
  }
1347
1348
5.46k
#ifdef HAVE_USELOCALE
1349
5.46k
  uselocale(oldlocale);
1350
5.46k
  freelocale(newloc);
1351
#elif defined(HAVE_SETLOCALE)
1352
  setlocale(LC_NUMERIC, oldlocale);
1353
  free(oldlocale);
1354
#endif
1355
1356
5.46k
  if (tok->err == json_tokener_success)
1357
5.08k
  {
1358
5.08k
    json_object *ret = json_object_get(current);
1359
5.08k
    int ii;
1360
1361
    /* Partially reset, so we parse additional objects on subsequent calls. */
1362
10.2k
    for (ii = tok->depth; ii >= 0; ii--)
1363
5.13k
      json_tokener_reset_level(tok, ii);
1364
5.08k
    return ret;
1365
5.08k
  }
1366
1367
381
  MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
1368
381
           tok->char_offset);
1369
381
  return NULL;
1370
5.46k
}
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
467
{
1411
467
  char *end;
1412
467
  *retval = strtod(buf, &end);
1413
467
  if (buf + len == end)
1414
466
    return 0; // It worked
1415
1
  return 1;
1416
467
}