Coverage Report

Created: 2026-08-08 07:10

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
11.2k
#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
193k
{
71
193k
  return c == ' '
72
193k
      || c == '\t'
73
192k
      || c == '\n'
74
191k
      || c == '\r';
75
193k
}
76
77
static inline int is_hex_char(char c)
78
11.2k
{
79
11.2k
  return (c >= '0' && c <= '9')
80
8.26k
      || (c >= 'A' && c <= 'F')
81
5.45k
      || (c >= 'a' && c <= 'f');
82
11.2k
}
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
0
{
134
0
  int jerr_int = (int)jerr;
135
0
  if (jerr_int < 0 ||
136
0
      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
0
  return json_tokener_errors[jerr];
140
0
}
141
142
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok)
143
0
{
144
0
  return tok->err;
145
0
}
146
147
/* Stuff for decoding unicode sequences */
148
2.32k
#define IS_HIGH_SURROGATE(uc) (((uc)&0xFC00) == 0xD800)
149
1.76k
#define IS_LOW_SURROGATE(uc) (((uc)&0xFC00) == 0xDC00)
150
422
#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
2.46k
{
155
2.46k
  struct json_tokener *tok;
156
157
2.46k
  tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
158
2.46k
  if (!tok)
159
0
    return NULL;
160
2.46k
  tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
161
2.46k
  if (!tok->stack)
162
0
  {
163
0
    free(tok);
164
0
    return NULL;
165
0
  }
166
2.46k
  tok->pb = printbuf_new();
167
2.46k
  if (!tok->pb)
168
0
  {
169
0
    free(tok->stack);
170
0
    free(tok);
171
0
    return NULL;
172
0
  }
173
2.46k
  tok->max_depth = depth;
174
2.46k
  json_tokener_reset(tok);
175
2.46k
  return tok;
176
2.46k
}
177
178
struct json_tokener *json_tokener_new(void)
179
2.46k
{
180
2.46k
  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
181
2.46k
}
182
183
void json_tokener_free(struct json_tokener *tok)
184
2.46k
{
185
2.46k
  json_tokener_reset(tok);
186
2.46k
  if (tok->pb)
187
2.46k
    printbuf_free(tok->pb);
188
2.46k
  free(tok->stack);
189
2.46k
  free(tok);
190
2.46k
}
191
192
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
193
86.1k
{
194
86.1k
  tok->stack[depth].state = json_tokener_state_eatws;
195
86.1k
  tok->stack[depth].saved_state = json_tokener_state_start;
196
86.1k
  json_object_put(tok->stack[depth].current);
197
86.1k
  tok->stack[depth].current = NULL;
198
86.1k
  free(tok->stack[depth].obj_field_name);
199
86.1k
  tok->stack[depth].obj_field_name = NULL;
200
86.1k
}
201
202
void json_tokener_reset(struct json_tokener *tok)
203
4.92k
{
204
4.92k
  int i;
205
4.92k
  if (!tok)
206
0
    return;
207
208
11.4k
  for (i = tok->depth; i >= 0; i--)
209
6.55k
    json_tokener_reset_level(tok, i);
210
4.92k
  tok->depth = 0;
211
4.92k
  tok->err = json_tokener_success;
212
4.92k
}
213
214
struct json_object *json_tokener_parse(const char *str)
215
2.46k
{
216
2.46k
  enum json_tokener_error jerr_ignored;
217
2.46k
  struct json_object *obj;
218
2.46k
  obj = json_tokener_parse_verbose(str, &jerr_ignored);
219
2.46k
  return obj;
220
2.46k
}
221
222
struct json_object *json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
223
2.46k
{
224
2.46k
  struct json_tokener *tok;
225
2.46k
  struct json_object *obj;
226
227
2.46k
  tok = json_tokener_new();
228
2.46k
  if (!tok)
229
0
  {
230
0
    *error = json_tokener_error_memory;
231
0
    return NULL;
232
0
  }
233
2.46k
  obj = json_tokener_parse_ex(tok, str, -1);
234
2.46k
  *error = tok->err;
235
2.46k
  if (tok->err != json_tokener_success
236
#if 0
237
    /* This would be a more sensible default, and cause parsing
238
     * things like "null123" to fail when the caller can't know
239
     * where the parsing left off, but starting to fail would
240
     * be a notable behaviour change.  Save for a 1.0 release.
241
     */
242
      || json_tokener_get_parse_end(tok) != strlen(str)
243
#endif
244
2.46k
  )
245
246
2.03k
  {
247
2.03k
    if (obj != NULL)
248
0
      json_object_put(obj);
249
2.03k
    obj = NULL;
250
2.03k
  }
251
252
2.46k
  json_tokener_free(tok);
253
2.46k
  return obj;
254
2.46k
}
255
256
950k
#define state tok->stack[tok->depth].state
257
345k
#define saved_state tok->stack[tok->depth].saved_state
258
164k
#define current tok->stack[tok->depth].current
259
59.3k
#define obj_field_name tok->stack[tok->depth].obj_field_name
260
261
/* Optimization:
262
 * json_tokener_parse_ex() consumed a lot of CPU in its main loop,
263
 * iterating character-by character.  A large performance boost is
264
 * achieved by using tighter loops to locally handle units such as
265
 * comments and strings.  Loops that handle an entire token within
266
 * their scope also gather entire strings and pass them to
267
 * printbuf_memappend() in a single call, rather than calling
268
 * printbuf_memappend() one char at a time.
269
 *
270
 * PEEK_CHAR() and ADVANCE_CHAR() macros are used for code that is
271
 * common to both the main loop and the tighter loops.
272
 */
273
274
/* PEEK_CHAR(dest, tok) macro:
275
 *   Peeks at the current char and stores it in dest.
276
 *   Returns 1 on success, sets tok->err and returns 0 if no more chars.
277
 *   Implicit inputs:  str, len, nBytesp vars
278
 */
279
#define PEEK_CHAR(dest, tok)                                                 \
280
502k
  (((tok)->char_offset == len)                                         \
281
502k
       ? (((tok)->depth == 0 && state == json_tokener_state_eatws &&   \
282
0
           saved_state == json_tokener_state_finish)                   \
283
0
              ? (((tok)->err = json_tokener_success), 0)               \
284
0
              : (((tok)->err = json_tokener_continue), 0))             \
285
502k
       : (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) &&                \
286
502k
           (!json_tokener_validate_utf8(*str, nBytesp)))               \
287
502k
              ? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
288
502k
              : (((dest) = *str), 1)))
289
290
/* ADVANCE_CHAR() macro:
291
 *   Increments str & tok->char_offset.
292
 *   For convenience of existing conditionals, returns the old value of c (0 on eof).
293
 *   Implicit inputs:  c var
294
 */
295
858k
#define ADVANCE_CHAR(str, tok) (++(str), ((tok)->char_offset)++, c)
296
297
/* printbuf_memappend_checked(p, s, l) macro:
298
 *   Add string s of length l to printbuffer p.
299
 *   If operation fails abort parse operation with memory error.
300
 */
301
#define printbuf_memappend_checked(p, s, l)                   \
302
74.5k
  do {                                                  \
303
74.5k
    if (printbuf_memappend((p), (s), (l)) < 0)    \
304
74.5k
    {                                             \
305
0
      tok->err = json_tokener_error_memory; \
306
0
      goto out;                             \
307
0
    }                                             \
308
74.5k
  } while (0)
309
310
/* End optimization macro defs */
311
312
struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *str, int len)
313
2.46k
{
314
2.46k
  struct json_object *obj = NULL;
315
2.46k
  char c = '\1';
316
2.46k
  unsigned int nBytes = 0;
317
2.46k
  unsigned int *nBytesp = &nBytes;
318
319
2.46k
#ifdef HAVE_USELOCALE
320
2.46k
  locale_t oldlocale = uselocale(NULL);
321
2.46k
  locale_t newloc;
322
#elif defined(HAVE_SETLOCALE)
323
  char *oldlocale = NULL;
324
#endif
325
326
2.46k
  tok->char_offset = 0;
327
2.46k
  tok->err = json_tokener_success;
328
329
  /* this interface is presently not 64-bit clean due to the int len argument
330
   * and the internal printbuf interface that takes 32-bit int len arguments
331
   * so the function limits the maximum string size to INT32_MAX (2GB).
332
   * If the function is called with len == -1 then strlen is called to check
333
   * the string length is less than INT32_MAX (2GB)
334
   */
335
2.46k
  if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX))
336
0
  {
337
0
    tok->err = json_tokener_error_size;
338
0
    return NULL;
339
0
  }
340
341
2.46k
#ifdef HAVE_USELOCALE
342
2.46k
  {
343
2.46k
    locale_t duploc = duplocale(oldlocale);
344
2.46k
    if (duploc == NULL && errno == ENOMEM)
345
0
    {
346
0
      tok->err = json_tokener_error_memory;
347
0
      return NULL;
348
0
    }
349
2.46k
    newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
350
2.46k
    if (newloc == NULL)
351
0
    {
352
0
      tok->err = json_tokener_error_memory;
353
0
      freelocale(duploc);
354
0
      return NULL;
355
0
    }
356
#ifdef NEWLOCALE_NEEDS_FREELOCALE
357
    // Older versions of FreeBSD (<12.4) don't free the locale
358
    // passed to newlocale(), so do it here
359
    freelocale(duploc);
360
#endif
361
2.46k
    uselocale(newloc);
362
2.46k
  }
363
#elif defined(HAVE_SETLOCALE)
364
  {
365
    char *tmplocale;
366
    tmplocale = setlocale(LC_NUMERIC, NULL);
367
    if (tmplocale)
368
    {
369
      oldlocale = strdup(tmplocale);
370
      if (oldlocale == NULL)
371
      {
372
        tok->err = json_tokener_error_memory;
373
        return NULL;
374
      }
375
    }
376
    setlocale(LC_NUMERIC, "C");
377
  }
378
#endif
379
380
125k
  while (PEEK_CHAR(c, tok)) // Note: c might be '\0' !
381
125k
  {
382
383
498k
  redo_char:
384
498k
    switch (state)
385
498k
    {
386
387
190k
    case json_tokener_state_eatws:
388
      /* Advance until we change state */
389
192k
      while (is_ws_char(c))
390
2.10k
      {
391
2.10k
        if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
392
0
          goto out;
393
2.10k
      }
394
190k
      if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
395
1.33k
      {
396
1.33k
        printbuf_reset(tok->pb);
397
1.33k
        printbuf_memappend_checked(tok->pb, &c, 1);
398
1.33k
        state = json_tokener_state_comment_start;
399
1.33k
      }
400
189k
      else
401
189k
      {
402
189k
        state = saved_state;
403
189k
        goto redo_char;
404
189k
      }
405
1.33k
      break;
406
407
42.5k
    case json_tokener_state_start:
408
42.5k
      switch (c)
409
42.5k
      {
410
2.61k
      case '{':
411
2.61k
        state = json_tokener_state_eatws;
412
2.61k
        saved_state = json_tokener_state_object_field_start;
413
2.61k
        current = json_object_new_object();
414
2.61k
        if (current == NULL)
415
0
        {
416
0
          tok->err = json_tokener_error_memory;
417
0
          goto out;
418
0
        }
419
2.61k
        break;
420
5.34k
      case '[':
421
5.34k
        state = json_tokener_state_eatws;
422
5.34k
        saved_state = json_tokener_state_array;
423
5.34k
        current = json_object_new_array();
424
5.34k
        if (current == NULL)
425
0
        {
426
0
          tok->err = json_tokener_error_memory;
427
0
          goto out;
428
0
        }
429
5.34k
        break;
430
5.34k
      case 'I':
431
669
      case 'i':
432
669
        state = json_tokener_state_inf;
433
669
        printbuf_reset(tok->pb);
434
669
        tok->st_pos = 0;
435
669
        goto redo_char;
436
571
      case 'N':
437
1.33k
      case 'n':
438
1.33k
        state = json_tokener_state_null; // or NaN
439
1.33k
        printbuf_reset(tok->pb);
440
1.33k
        tok->st_pos = 0;
441
1.33k
        goto redo_char;
442
775
      case '\'':
443
775
        if (tok->flags & JSON_TOKENER_STRICT)
444
0
        {
445
          /* in STRICT mode only double-quote are allowed */
446
0
          tok->err = json_tokener_error_parse_unexpected;
447
0
          goto out;
448
0
        }
449
        /* FALLTHRU */
450
1.47k
      case '"':
451
1.47k
        state = json_tokener_state_string;
452
1.47k
        printbuf_reset(tok->pb);
453
1.47k
        tok->quote_char = c;
454
1.47k
        break;
455
229
      case 'T':
456
721
      case 't':
457
1.18k
      case 'F':
458
1.49k
      case 'f':
459
1.49k
        state = json_tokener_state_boolean;
460
1.49k
        printbuf_reset(tok->pb);
461
1.49k
        tok->st_pos = 0;
462
1.49k
        goto redo_char;
463
8.31k
      case '0':
464
9.84k
      case '1':
465
11.2k
      case '2':
466
11.8k
      case '3':
467
12.5k
      case '4':
468
13.5k
      case '5':
469
16.0k
      case '6':
470
17.2k
      case '7':
471
19.4k
      case '8':
472
27.6k
      case '9':
473
29.3k
      case '-':
474
29.3k
        state = json_tokener_state_number;
475
29.3k
        printbuf_reset(tok->pb);
476
29.3k
        tok->is_double = 0;
477
29.3k
        goto redo_char;
478
224
      default: tok->err = json_tokener_error_parse_unexpected; goto out;
479
42.5k
      }
480
9.43k
      break;
481
482
39.0k
    case json_tokener_state_finish:
483
39.0k
      if (tok->depth == 0)
484
392
        goto out;
485
38.6k
      obj = json_object_get(current);
486
38.6k
      json_tokener_reset_level(tok, tok->depth);
487
38.6k
      tok->depth--;
488
38.6k
      goto redo_char;
489
490
1.25k
    case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
491
1.25k
    {
492
      /* If we were guaranteed to have len set, then we could (usually) handle
493
       * the entire "Infinity" check in a single strncmp (strncasecmp), but
494
       * since len might be -1 (i.e. "read until \0"), we need to check it
495
       * a character at a time.
496
       * Trying to handle it both ways would make this code considerably more
497
       * complicated with likely little performance benefit.
498
       */
499
1.25k
      int is_negative = 0;
500
501
      /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
502
10.8k
      while (tok->st_pos < (int)json_inf_str_len)
503
9.63k
      {
504
9.63k
        char inf_char = *str;
505
9.63k
        if (inf_char != json_inf_str[tok->st_pos] &&
506
4.88k
            ((tok->flags & JSON_TOKENER_STRICT) ||
507
4.88k
              inf_char != json_inf_str_invert[tok->st_pos])
508
9.63k
           )
509
68
        {
510
68
          tok->err = json_tokener_error_parse_unexpected;
511
68
          goto out;
512
68
        }
513
9.56k
        tok->st_pos++;
514
9.56k
        (void)ADVANCE_CHAR(str, tok);
515
9.56k
        if (!PEEK_CHAR(c, tok))
516
0
        {
517
          /* out of input chars, for now at least */
518
0
          goto out;
519
0
        }
520
9.56k
      }
521
      /* We checked the full length of "Infinity", so create the object.
522
       * When handling -Infinity, the number parsing code will have dropped
523
       * the "-" into tok->pb for us, so check it now.
524
       */
525
1.18k
      if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
526
566
      {
527
566
        is_negative = 1;
528
566
      }
529
1.18k
      current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
530
1.18k
      if (current == NULL)
531
0
      {
532
0
        tok->err = json_tokener_error_memory;
533
0
        goto out;
534
0
      }
535
1.18k
      saved_state = json_tokener_state_finish;
536
1.18k
      state = json_tokener_state_eatws;
537
1.18k
      goto redo_char;
538
1.18k
    }
539
0
    break;
540
5.70k
    case json_tokener_state_null: /* aka starts with 'n' */
541
5.70k
    {
542
5.70k
      int size;
543
5.70k
      int size_nan;
544
5.70k
      printbuf_memappend_checked(tok->pb, &c, 1);
545
5.70k
      size = json_min(tok->st_pos + 1, json_null_str_len);
546
5.70k
      size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
547
5.70k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
548
5.70k
           strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
549
2.36k
          (strncmp(json_null_str, tok->pb->buf, size) == 0))
550
3.34k
      {
551
3.34k
        if (tok->st_pos == json_null_str_len)
552
494
        {
553
494
          current = NULL;
554
494
          saved_state = json_tokener_state_finish;
555
494
          state = json_tokener_state_eatws;
556
494
          goto redo_char;
557
494
        }
558
3.34k
      }
559
2.36k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
560
2.36k
                strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
561
82
               (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
562
2.28k
      {
563
2.28k
        if (tok->st_pos == json_nan_str_len)
564
757
        {
565
757
          current = json_object_new_double(NAN);
566
757
          if (current == NULL)
567
0
          {
568
0
            tok->err = json_tokener_error_memory;
569
0
            goto out;
570
0
          }
571
757
          saved_state = json_tokener_state_finish;
572
757
          state = json_tokener_state_eatws;
573
757
          goto redo_char;
574
757
        }
575
2.28k
      }
576
82
      else
577
82
      {
578
82
        tok->err = json_tokener_error_parse_null;
579
82
        goto out;
580
82
      }
581
4.37k
      tok->st_pos++;
582
4.37k
    }
583
0
    break;
584
585
1.33k
    case json_tokener_state_comment_start:
586
1.33k
      if (c == '*')
587
434
      {
588
434
        state = json_tokener_state_comment;
589
434
      }
590
901
      else if (c == '/')
591
860
      {
592
860
        state = json_tokener_state_comment_eol;
593
860
      }
594
41
      else
595
41
      {
596
41
        tok->err = json_tokener_error_parse_comment;
597
41
        goto out;
598
41
      }
599
1.29k
      printbuf_memappend_checked(tok->pb, &c, 1);
600
1.29k
      break;
601
602
2.76k
    case json_tokener_state_comment:
603
2.76k
    {
604
      /* Advance until we change state */
605
2.76k
      const char *case_start = str;
606
120k
      while (c != '*')
607
117k
      {
608
117k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
609
119
        {
610
119
          printbuf_memappend_checked(tok->pb, case_start,
611
119
                                     str - case_start);
612
119
          goto out;
613
119
        }
614
117k
      }
615
2.64k
      printbuf_memappend_checked(tok->pb, case_start, 1 + str - case_start);
616
2.64k
      state = json_tokener_state_comment_end;
617
2.64k
    }
618
0
    break;
619
620
860
    case json_tokener_state_comment_eol:
621
860
    {
622
      /* Advance until we change state */
623
860
      const char *case_start = str;
624
31.1k
      while (c != '\n')
625
30.3k
      {
626
30.3k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
627
71
        {
628
71
          printbuf_memappend_checked(tok->pb, case_start,
629
71
                                     str - case_start);
630
71
          goto out;
631
71
        }
632
30.3k
      }
633
789
      printbuf_memappend_checked(tok->pb, case_start, str - case_start);
634
789
      MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
635
789
      state = json_tokener_state_eatws;
636
789
    }
637
0
    break;
638
639
2.64k
    case json_tokener_state_comment_end:
640
2.64k
      printbuf_memappend_checked(tok->pb, &c, 1);
641
2.64k
      if (c == '/')
642
272
      {
643
272
        MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
644
272
        state = json_tokener_state_eatws;
645
272
      }
646
2.37k
      else
647
2.37k
      {
648
2.37k
        state = json_tokener_state_comment;
649
2.37k
      }
650
2.64k
      break;
651
652
4.67k
    case json_tokener_state_string:
653
4.67k
    {
654
      /* Advance until we change state */
655
4.67k
      const char *case_start = str;
656
42.4k
      while (1)
657
42.4k
      {
658
42.4k
        if (c == tok->quote_char)
659
1.08k
        {
660
1.08k
          printbuf_memappend_checked(tok->pb, case_start,
661
1.08k
                                     str - case_start);
662
1.08k
          current =
663
1.08k
              json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
664
1.08k
          if (current == NULL)
665
0
          {
666
0
            tok->err = json_tokener_error_memory;
667
0
            goto out;
668
0
          }
669
1.08k
          saved_state = json_tokener_state_finish;
670
1.08k
          state = json_tokener_state_eatws;
671
1.08k
          break;
672
1.08k
        }
673
41.3k
        else if (c == '\\')
674
3.30k
        {
675
3.30k
          printbuf_memappend_checked(tok->pb, case_start,
676
3.30k
                                     str - case_start);
677
3.30k
          saved_state = json_tokener_state_string;
678
3.30k
          state = json_tokener_state_string_escape;
679
3.30k
          break;
680
3.30k
        }
681
38.0k
        else if ((tok->flags & JSON_TOKENER_STRICT) && c <= 0x1f)
682
0
        {
683
          // Disallow control characters in strict mode
684
0
          tok->err = json_tokener_error_parse_string;
685
0
          goto out;
686
0
        }
687
38.0k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
688
286
        {
689
286
          printbuf_memappend_checked(tok->pb, case_start,
690
286
                                     str - case_start);
691
286
          goto out;
692
286
        }
693
38.0k
      }
694
4.67k
    }
695
4.38k
    break;
696
697
4.46k
    case json_tokener_state_string_escape:
698
4.46k
      switch (c)
699
4.46k
      {
700
261
      case '"':
701
895
      case '\\':
702
1.12k
      case '/':
703
1.12k
        printbuf_memappend_checked(tok->pb, &c, 1);
704
1.12k
        state = saved_state;
705
1.12k
        break;
706
284
      case 'b':
707
525
      case 'n':
708
754
      case 'r':
709
1.10k
      case 't':
710
1.41k
      case 'f':
711
1.41k
        if (c == 'b')
712
284
          printbuf_memappend_checked(tok->pb, "\b", 1);
713
1.12k
        else if (c == 'n')
714
241
          printbuf_memappend_checked(tok->pb, "\n", 1);
715
888
        else if (c == 'r')
716
229
          printbuf_memappend_checked(tok->pb, "\r", 1);
717
659
        else if (c == 't')
718
350
          printbuf_memappend_checked(tok->pb, "\t", 1);
719
309
        else if (c == 'f')
720
309
          printbuf_memappend_checked(tok->pb, "\f", 1);
721
1.41k
        state = saved_state;
722
1.41k
        break;
723
1.86k
      case 'u':
724
1.86k
        tok->ucs_char = 0;
725
1.86k
        tok->st_pos = 0;
726
1.86k
        state = json_tokener_state_escape_unicode;
727
1.86k
        break;
728
62
      default: tok->err = json_tokener_error_parse_string; goto out;
729
4.46k
      }
730
4.40k
      break;
731
732
      // ===================================================
733
734
4.40k
    case json_tokener_state_escape_unicode:
735
2.86k
    {
736
      /* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */
737
11.2k
      while (1)
738
11.2k
      {
739
11.2k
        if (!c || !is_hex_char(c))
740
75
        {
741
75
          tok->err = json_tokener_error_parse_string;
742
75
          goto out;
743
75
        }
744
11.2k
        tok->ucs_char |=
745
11.2k
            ((unsigned int)jt_hexdigit(c) << ((3 - tok->st_pos) * 4));
746
11.2k
        tok->st_pos++;
747
11.2k
        if (tok->st_pos >= 4)
748
2.78k
          break;
749
750
8.42k
        (void)ADVANCE_CHAR(str, tok);
751
8.42k
        if (!PEEK_CHAR(c, tok))
752
0
        {
753
          /*
754
           * We're out of characters in the current call to
755
           * json_tokener_parse(), but a subsequent call might
756
           * provide us with more, so leave our current state
757
           * as-is (including tok->high_surrogate) and return.
758
           */
759
0
          goto out;
760
0
        }
761
8.42k
      }
762
2.78k
      tok->st_pos = 0;
763
764
      /* Now, we have a full \uNNNN sequence in tok->ucs_char */
765
766
      /* If the *previous* sequence was a high surrogate ... */
767
2.78k
      if (tok->high_surrogate)
768
986
      {
769
986
        if (IS_LOW_SURROGATE(tok->ucs_char))
770
422
        {
771
          /* Recalculate the ucs_char, then fall thru to process normally */
772
422
          tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate,
773
422
                                                tok->ucs_char);
774
422
        }
775
564
        else
776
564
        {
777
          /* High surrogate was not followed by a low surrogate
778
           * Replace the high and process the rest normally
779
           */
780
564
          printbuf_memappend_checked(tok->pb,
781
564
                                     (char *)utf8_replacement_char, 3);
782
564
        }
783
986
        tok->high_surrogate = 0;
784
986
      }
785
786
2.78k
      if (tok->ucs_char < 0x80)
787
259
      {
788
259
        unsigned char unescaped_utf[1];
789
259
        unescaped_utf[0] = tok->ucs_char;
790
259
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 1);
791
259
      }
792
2.53k
      else if (tok->ucs_char < 0x800)
793
207
      {
794
207
        unsigned char unescaped_utf[2];
795
207
        unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
796
207
        unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
797
207
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 2);
798
207
      }
799
2.32k
      else if (IS_HIGH_SURROGATE(tok->ucs_char))
800
1.54k
      {
801
        /*
802
         * The next two characters should be \u, HOWEVER,
803
         * we can't simply peek ahead here, because the
804
         * characters we need might not be passed to us
805
         * until a subsequent call to json_tokener_parse.
806
         * Instead, transition through a couple of states.
807
         * (now):
808
         *   _escape_unicode => _unicode_need_escape
809
         * (see a '\\' char):
810
         *   _unicode_need_escape => _unicode_need_u
811
         * (see a 'u' char):
812
         *   _unicode_need_u => _escape_unicode
813
         *      ...and we'll end up back around here.
814
         */
815
1.54k
        tok->high_surrogate = tok->ucs_char;
816
1.54k
        tok->ucs_char = 0;
817
1.54k
        state = json_tokener_state_escape_unicode_need_escape;
818
1.54k
        break;
819
1.54k
      }
820
781
      else if (IS_LOW_SURROGATE(tok->ucs_char))
821
279
      {
822
        /* Got a low surrogate not preceded by a high */
823
279
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
824
279
      }
825
502
      else if (tok->ucs_char < 0x10000)
826
272
      {
827
272
        unsigned char unescaped_utf[3];
828
272
        unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
829
272
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
830
272
        unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
831
272
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 3);
832
272
      }
833
230
      else if (tok->ucs_char < 0x110000)
834
230
      {
835
230
        unsigned char unescaped_utf[4];
836
230
        unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
837
230
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
838
230
        unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
839
230
        unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
840
230
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 4);
841
230
      }
842
0
      else
843
0
      {
844
        /* Don't know what we got--insert the replacement char */
845
0
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
846
0
      }
847
1.24k
      state = saved_state; // i.e. _state_string or _state_object_field
848
1.24k
    }
849
0
    break;
850
851
1.54k
    case json_tokener_state_escape_unicode_need_escape:
852
      // We get here after processing a high_surrogate
853
      // require a '\\' char
854
1.54k
      if (!c || c != '\\')
855
298
      {
856
        /* Got a high surrogate without another sequence following
857
         * it.  Put a replacement char in for the high surrogate
858
         * and pop back up to _state_string or _state_object_field.
859
         */
860
298
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
861
298
        tok->high_surrogate = 0;
862
298
        tok->ucs_char = 0;
863
298
        tok->st_pos = 0;
864
298
        state = saved_state;
865
298
        goto redo_char;
866
298
      }
867
1.24k
      state = json_tokener_state_escape_unicode_need_u;
868
1.24k
      break;
869
870
1.24k
    case json_tokener_state_escape_unicode_need_u:
871
      /* We already had a \ char, check that it's \u */
872
1.24k
      if (!c || c != 'u')
873
247
      {
874
        /* Got a high surrogate with some non-unicode escape
875
         * sequence following it.
876
         * Put a replacement char in for the high surrogate
877
         * and handle the escape sequence normally.
878
         */
879
247
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
880
247
        tok->high_surrogate = 0;
881
247
        tok->ucs_char = 0;
882
247
        tok->st_pos = 0;
883
247
        state = json_tokener_state_string_escape;
884
247
        goto redo_char;
885
247
      }
886
997
      state = json_tokener_state_escape_unicode;
887
997
      break;
888
889
      // ===================================================
890
891
7.88k
    case json_tokener_state_boolean:
892
7.88k
    {
893
7.88k
      int size1, size2;
894
7.88k
      printbuf_memappend_checked(tok->pb, &c, 1);
895
7.88k
      size1 = json_min(tok->st_pos + 1, json_true_str_len);
896
7.88k
      size2 = json_min(tok->st_pos + 1, json_false_str_len);
897
7.88k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
898
7.88k
           strncasecmp(json_true_str, tok->pb->buf, size1) == 0) ||
899
4.49k
          (strncmp(json_true_str, tok->pb->buf, size1) == 0))
900
3.38k
      {
901
3.38k
        if (tok->st_pos == json_true_str_len)
902
656
        {
903
656
          current = json_object_new_boolean(1);
904
656
          if (current == NULL)
905
0
          {
906
0
            tok->err = json_tokener_error_memory;
907
0
            goto out;
908
0
          }
909
656
          saved_state = json_tokener_state_finish;
910
656
          state = json_tokener_state_eatws;
911
656
          goto redo_char;
912
656
        }
913
3.38k
      }
914
4.49k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
915
4.49k
                strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
916
138
               (strncmp(json_false_str, tok->pb->buf, size2) == 0))
917
4.35k
      {
918
4.35k
        if (tok->st_pos == json_false_str_len)
919
702
        {
920
702
          current = json_object_new_boolean(0);
921
702
          if (current == NULL)
922
0
          {
923
0
            tok->err = json_tokener_error_memory;
924
0
            goto out;
925
0
          }
926
702
          saved_state = json_tokener_state_finish;
927
702
          state = json_tokener_state_eatws;
928
702
          goto redo_char;
929
702
        }
930
4.35k
      }
931
138
      else
932
138
      {
933
138
        tok->err = json_tokener_error_parse_boolean;
934
138
        goto out;
935
138
      }
936
6.38k
      tok->st_pos++;
937
6.38k
    }
938
0
    break;
939
940
29.3k
    case json_tokener_state_number:
941
29.3k
    {
942
      /* Advance until we change state */
943
29.3k
      const char *case_start = str;
944
29.3k
      int case_len = 0;
945
29.3k
      int is_exponent = 0;
946
29.3k
      int neg_sign_ok = 1;
947
29.3k
      int pos_sign_ok = 0;
948
29.3k
      if (printbuf_length(tok->pb) > 0)
949
0
      {
950
        /* We don't save all state from the previous incremental parse
951
           so we need to re-generate it based on the saved string so far.
952
         */
953
0
        char *e_loc = strchr(tok->pb->buf, 'e');
954
0
        if (!e_loc)
955
0
          e_loc = strchr(tok->pb->buf, 'E');
956
0
        if (e_loc)
957
0
        {
958
0
          char *last_saved_char =
959
0
              &tok->pb->buf[printbuf_length(tok->pb) - 1];
960
0
          is_exponent = 1;
961
0
          pos_sign_ok = neg_sign_ok = 1;
962
          /* If the "e" isn't at the end, we can't start with a '-' */
963
0
          if (e_loc != last_saved_char)
964
0
          {
965
0
            neg_sign_ok = 0;
966
0
            pos_sign_ok = 0;
967
0
          }
968
          // else leave it set to 1, i.e. start of the new input
969
0
        }
970
0
      }
971
972
96.9k
      while (c && ((c >= '0' && c <= '9') ||
973
32.9k
                   (!is_exponent && (c == 'e' || c == 'E')) ||
974
31.9k
                   (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') ||
975
29.6k
                   (!tok->is_double && c == '.')))
976
67.6k
      {
977
67.6k
        pos_sign_ok = neg_sign_ok = 0;
978
67.6k
        ++case_len;
979
980
        /* non-digit characters checks */
981
        /* note: since the main loop condition to get here was
982
         * an input starting with 0-9 or '-', we are
983
         * protected from input starting with '.' or
984
         * e/E.
985
         */
986
67.6k
        switch (c)
987
67.6k
        {
988
645
        case '.':
989
645
          tok->is_double = 1;
990
645
          pos_sign_ok = 1;
991
645
          neg_sign_ok = 1;
992
645
          break;
993
364
        case 'e': /* FALLTHRU */
994
997
        case 'E':
995
997
          is_exponent = 1;
996
997
          tok->is_double = 1;
997
          /* the exponent part can begin with a negative sign */
998
997
          pos_sign_ok = neg_sign_ok = 1;
999
997
          break;
1000
65.9k
        default: break;
1001
67.6k
        }
1002
1003
67.6k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
1004
0
        {
1005
0
          printbuf_memappend_checked(tok->pb, case_start, case_len);
1006
0
          goto out;
1007
0
        }
1008
67.6k
      }
1009
      /*
1010
        Now we know c isn't a valid number char, but check whether
1011
        it might have been intended to be, and return a potentially
1012
        more understandable error right away.
1013
        However, if we're at the top-level, use the number as-is
1014
        because c can be part of a new object to parse on the
1015
        next call to json_tokener_parse().
1016
       */
1017
29.3k
      if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
1018
1.71k
          c != 'I' && c != 'i' && !is_ws_char(c))
1019
165
      {
1020
165
        tok->err = json_tokener_error_parse_number;
1021
165
        goto out;
1022
165
      }
1023
29.2k
      if (case_len > 0)
1024
29.2k
        printbuf_memappend_checked(tok->pb, case_start, case_len);
1025
1026
      // Check for -Infinity
1027
29.2k
      if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
1028
583
      {
1029
583
        state = json_tokener_state_inf;
1030
583
        tok->st_pos = 0;
1031
583
        goto redo_char;
1032
583
      }
1033
28.6k
      if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
1034
1.34k
      {
1035
        /* Trim some chars off the end, to allow things
1036
           like "123e+" to parse ok. */
1037
2.96k
        while (printbuf_length(tok->pb) > 1)
1038
2.34k
        {
1039
2.34k
          char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1];
1040
2.34k
          if (last_char != 'e' && last_char != 'E' &&
1041
1.37k
              last_char != '-' && last_char != '+')
1042
718
          {
1043
718
            break;
1044
718
          }
1045
1.62k
          tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0';
1046
1.62k
          printbuf_length(tok->pb)--;
1047
1.62k
        }
1048
1.34k
      }
1049
28.6k
    }
1050
0
      {
1051
28.6k
        int64_t num64;
1052
28.6k
        uint64_t numuint64;
1053
28.6k
        double numd;
1054
28.6k
        if (!tok->is_double && tok->pb->buf[0] == '-' &&
1055
935
            json_parse_int64(tok->pb->buf, &num64) == 0)
1056
903
        {
1057
903
          if (errno == ERANGE && (tok->flags & JSON_TOKENER_STRICT))
1058
0
          {
1059
0
            tok->err = json_tokener_error_parse_number;
1060
0
            goto out;
1061
0
          }
1062
903
          current = json_object_new_int64(num64);
1063
903
          if (current == NULL)
1064
0
          {
1065
0
            tok->err = json_tokener_error_memory;
1066
0
            goto out;
1067
0
          }
1068
903
        }
1069
27.7k
        else if (!tok->is_double && tok->pb->buf[0] != '-' &&
1070
26.3k
                 json_parse_uint64(tok->pb->buf, &numuint64) == 0)
1071
26.3k
        {
1072
26.3k
          if (errno == ERANGE && (tok->flags & JSON_TOKENER_STRICT))
1073
0
          {
1074
0
            tok->err = json_tokener_error_parse_number;
1075
0
            goto out;
1076
0
          }
1077
26.3k
          if (numuint64 && tok->pb->buf[0] == '0' &&
1078
254
              (tok->flags & JSON_TOKENER_STRICT))
1079
0
          {
1080
0
            tok->err = json_tokener_error_parse_number;
1081
0
            goto out;
1082
0
          }
1083
26.3k
          if (numuint64 <= INT64_MAX)
1084
26.0k
          {
1085
26.0k
            num64 = (uint64_t)numuint64;
1086
26.0k
            current = json_object_new_int64(num64);
1087
26.0k
            if (current == NULL)
1088
0
            {
1089
0
              tok->err = json_tokener_error_memory;
1090
0
              goto out;
1091
0
            }
1092
26.0k
          }
1093
296
          else
1094
296
          {
1095
296
            current = json_object_new_uint64(numuint64);
1096
296
            if (current == NULL)
1097
0
            {
1098
0
              tok->err = json_tokener_error_memory;
1099
0
              goto out;
1100
0
            }
1101
296
          }
1102
26.3k
        }
1103
1.37k
        else if (tok->is_double &&
1104
1.34k
                 json_tokener_parse_double(
1105
1.34k
                     tok->pb->buf, printbuf_length(tok->pb), &numd) == 0)
1106
1.32k
        {
1107
1.32k
          current = json_object_new_double_s(numd, tok->pb->buf);
1108
1.32k
          if (current == NULL)
1109
0
          {
1110
0
            tok->err = json_tokener_error_memory;
1111
0
            goto out;
1112
0
          }
1113
1.32k
        }
1114
50
        else
1115
50
        {
1116
50
          tok->err = json_tokener_error_parse_number;
1117
50
          goto out;
1118
50
        }
1119
28.5k
        saved_state = json_tokener_state_finish;
1120
28.5k
        state = json_tokener_state_eatws;
1121
28.5k
        goto redo_char;
1122
28.6k
      }
1123
0
      break;
1124
1125
25.5k
    case json_tokener_state_array_after_sep:
1126
30.9k
    case json_tokener_state_array:
1127
30.9k
      if (c == ']')
1128
2.87k
      {
1129
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1130
2.87k
        json_object_array_shrink(current, 0);
1131
1132
2.87k
        if (state == json_tokener_state_array_after_sep &&
1133
217
            (tok->flags & JSON_TOKENER_STRICT))
1134
0
        {
1135
0
          tok->err = json_tokener_error_parse_unexpected;
1136
0
          goto out;
1137
0
        }
1138
2.87k
        saved_state = json_tokener_state_finish;
1139
2.87k
        state = json_tokener_state_eatws;
1140
2.87k
      }
1141
28.0k
      else
1142
28.0k
      {
1143
28.0k
        if (tok->depth >= tok->max_depth - 1)
1144
1
        {
1145
1
          tok->err = json_tokener_error_depth;
1146
1
          goto out;
1147
1
        }
1148
28.0k
        state = json_tokener_state_array_add;
1149
28.0k
        tok->depth++;
1150
28.0k
        json_tokener_reset_level(tok, tok->depth);
1151
28.0k
        goto redo_char;
1152
28.0k
      }
1153
2.87k
      break;
1154
1155
27.0k
    case json_tokener_state_array_add:
1156
27.0k
      if (json_object_array_add(current, obj) != 0)
1157
0
      {
1158
0
        tok->err = json_tokener_error_memory;
1159
0
        goto out;
1160
0
      }
1161
27.0k
      saved_state = json_tokener_state_array_sep;
1162
27.0k
      state = json_tokener_state_eatws;
1163
27.0k
      goto redo_char;
1164
1165
27.0k
    case json_tokener_state_array_sep:
1166
27.0k
      if (c == ']')
1167
1.30k
      {
1168
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1169
1.30k
        json_object_array_shrink(current, 0);
1170
1171
1.30k
        saved_state = json_tokener_state_finish;
1172
1.30k
        state = json_tokener_state_eatws;
1173
1.30k
      }
1174
25.7k
      else if (c == ',')
1175
25.5k
      {
1176
25.5k
        saved_state = json_tokener_state_array_after_sep;
1177
25.5k
        state = json_tokener_state_eatws;
1178
25.5k
      }
1179
152
      else
1180
152
      {
1181
152
        tok->err = json_tokener_error_parse_array;
1182
152
        goto out;
1183
152
      }
1184
26.8k
      break;
1185
1186
26.8k
    case json_tokener_state_object_field_start:
1187
13.4k
    case json_tokener_state_object_field_start_after_sep:
1188
13.4k
      if (c == '}')
1189
818
      {
1190
818
        if (state == json_tokener_state_object_field_start_after_sep &&
1191
225
            (tok->flags & JSON_TOKENER_STRICT))
1192
0
        {
1193
0
          tok->err = json_tokener_error_parse_unexpected;
1194
0
          goto out;
1195
0
        }
1196
818
        saved_state = json_tokener_state_finish;
1197
818
        state = json_tokener_state_eatws;
1198
818
      }
1199
12.6k
      else if (c == '"' || c == '\'')
1200
12.4k
      {
1201
12.4k
        tok->quote_char = c;
1202
12.4k
        printbuf_reset(tok->pb);
1203
12.4k
        state = json_tokener_state_object_field;
1204
12.4k
      }
1205
179
      else
1206
179
      {
1207
179
        tok->err = json_tokener_error_parse_object_key_name;
1208
179
        goto out;
1209
179
      }
1210
13.2k
      break;
1211
1212
13.3k
    case json_tokener_state_object_field:
1213
13.3k
    {
1214
      /* Advance until we change state */
1215
13.3k
      const char *case_start = str;
1216
117k
      while (1)
1217
117k
      {
1218
117k
        if (c == tok->quote_char)
1219
12.2k
        {
1220
12.2k
          printbuf_memappend_checked(tok->pb, case_start,
1221
12.2k
                                     str - case_start);
1222
12.2k
          obj_field_name = strdup(tok->pb->buf);
1223
12.2k
          if (obj_field_name == NULL)
1224
0
          {
1225
0
            tok->err = json_tokener_error_memory;
1226
0
            goto out;
1227
0
          }
1228
12.2k
          saved_state = json_tokener_state_object_field_end;
1229
12.2k
          state = json_tokener_state_eatws;
1230
12.2k
          break;
1231
12.2k
        }
1232
105k
        else if (c == '\\')
1233
917
        {
1234
917
          printbuf_memappend_checked(tok->pb, case_start,
1235
917
                                     str - case_start);
1236
917
          saved_state = json_tokener_state_object_field;
1237
917
          state = json_tokener_state_string_escape;
1238
917
          break;
1239
917
        }
1240
104k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
1241
126
        {
1242
126
          printbuf_memappend_checked(tok->pb, case_start,
1243
126
                                     str - case_start);
1244
126
          goto out;
1245
126
        }
1246
104k
      }
1247
13.3k
    }
1248
13.1k
    break;
1249
1250
13.1k
    case json_tokener_state_object_field_end:
1251
12.2k
      if (c == ':')
1252
12.2k
      {
1253
12.2k
        saved_state = json_tokener_state_object_value;
1254
12.2k
        state = json_tokener_state_eatws;
1255
12.2k
      }
1256
47
      else
1257
47
      {
1258
47
        tok->err = json_tokener_error_parse_object_key_sep;
1259
47
        goto out;
1260
47
      }
1261
12.2k
      break;
1262
1263
12.2k
    case json_tokener_state_object_value:
1264
12.2k
      if (tok->depth >= tok->max_depth - 1)
1265
2
      {
1266
2
        tok->err = json_tokener_error_depth;
1267
2
        goto out;
1268
2
      }
1269
12.2k
      state = json_tokener_state_object_value_add;
1270
12.2k
      tok->depth++;
1271
12.2k
      json_tokener_reset_level(tok, tok->depth);
1272
12.2k
      goto redo_char;
1273
1274
11.6k
    case json_tokener_state_object_value_add:
1275
11.6k
      if (json_object_object_add(current, obj_field_name, obj) != 0)
1276
0
      {
1277
0
        tok->err = json_tokener_error_memory;
1278
0
        goto out;
1279
0
      }
1280
11.6k
      free(obj_field_name);
1281
11.6k
      obj_field_name = NULL;
1282
11.6k
      saved_state = json_tokener_state_object_sep;
1283
11.6k
      state = json_tokener_state_eatws;
1284
11.6k
      goto redo_char;
1285
1286
11.6k
    case json_tokener_state_object_sep:
1287
      /* { */
1288
11.6k
      if (c == '}')
1289
653
      {
1290
653
        saved_state = json_tokener_state_finish;
1291
653
        state = json_tokener_state_eatws;
1292
653
      }
1293
10.9k
      else if (c == ',')
1294
10.8k
      {
1295
10.8k
        saved_state = json_tokener_state_object_field_start_after_sep;
1296
10.8k
        state = json_tokener_state_eatws;
1297
10.8k
      }
1298
138
      else
1299
138
      {
1300
138
        tok->err = json_tokener_error_parse_object_value_sep;
1301
138
        goto out;
1302
138
      }
1303
11.4k
      break;
1304
498k
    }
1305
122k
    (void)ADVANCE_CHAR(str, tok);
1306
122k
    if (!c) // This is the char *before* advancing
1307
43
      break;
1308
122k
  } /* while(PEEK_CHAR) */
1309
1310
2.46k
out:
1311
2.46k
  if ((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && (nBytes != 0))
1312
0
  {
1313
0
    tok->err = json_tokener_error_parse_utf8_string;
1314
0
  }
1315
2.46k
  if (c && (state == json_tokener_state_finish) && (tok->depth == 0) &&
1316
24
      (tok->flags & (JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS)) ==
1317
24
          JSON_TOKENER_STRICT)
1318
0
  {
1319
    /* unexpected char after JSON data */
1320
0
    tok->err = json_tokener_error_parse_unexpected;
1321
0
  }
1322
2.46k
  if (!c)
1323
1.99k
  {
1324
    /* We hit an eof char (0) */
1325
1.99k
    if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
1326
1.57k
      tok->err = json_tokener_error_parse_eof;
1327
1.99k
  }
1328
1329
2.46k
#ifdef HAVE_USELOCALE
1330
2.46k
  uselocale(oldlocale);
1331
2.46k
  freelocale(newloc);
1332
#elif defined(HAVE_SETLOCALE)
1333
  setlocale(LC_NUMERIC, oldlocale);
1334
  free(oldlocale);
1335
#endif
1336
1337
2.46k
  if (tok->err == json_tokener_success)
1338
430
  {
1339
430
    json_object *ret = json_object_get(current);
1340
430
    int ii;
1341
1342
    /* Partially reset, so we parse additional objects on subsequent calls. */
1343
1.04k
    for (ii = tok->depth; ii >= 0; ii--)
1344
612
      json_tokener_reset_level(tok, ii);
1345
430
    return ret;
1346
430
  }
1347
1348
2.03k
  MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
1349
2.03k
           tok->char_offset);
1350
2.03k
  return NULL;
1351
2.46k
}
1352
1353
static json_bool json_tokener_validate_utf8(const char c, unsigned int *nBytes)
1354
0
{
1355
0
  unsigned char chr = c;
1356
0
  if (*nBytes == 0)
1357
0
  {
1358
0
    if (chr >= 0x80)
1359
0
    {
1360
0
      if ((chr & 0xe0) == 0xc0)
1361
0
        *nBytes = 1;
1362
0
      else if ((chr & 0xf0) == 0xe0)
1363
0
        *nBytes = 2;
1364
0
      else if ((chr & 0xf8) == 0xf0)
1365
0
        *nBytes = 3;
1366
0
      else
1367
0
        return 0;
1368
0
    }
1369
0
  }
1370
0
  else
1371
0
  {
1372
0
    if ((chr & 0xC0) != 0x80)
1373
0
      return 0;
1374
0
    (*nBytes)--;
1375
0
  }
1376
0
  return 1;
1377
0
}
1378
1379
void json_tokener_set_flags(struct json_tokener *tok, int flags)
1380
0
{
1381
0
  tok->flags = flags;
1382
0
}
1383
1384
size_t json_tokener_get_parse_end(struct json_tokener *tok)
1385
0
{
1386
0
  assert(tok->char_offset >= 0); /* Drop this line when char_offset becomes a size_t */
1387
0
  return (size_t)tok->char_offset;
1388
0
}
1389
1390
static int json_tokener_parse_double(const char *buf, int len, double *retval)
1391
1.34k
{
1392
1.34k
  char *end;
1393
1.34k
  *retval = strtod(buf, &end);
1394
1.34k
  if (buf + len == end)
1395
1.32k
    return 0; // It worked
1396
18
  return 1;
1397
1.34k
}