Coverage Report

Created: 2026-08-14 07:17

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
13.8k
#define jt_hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x)&7) + 9)
48
49
#if !HAVE_STRNCASECMP && defined(_MSC_VER)
50
/* MSC has the version as _strnicmp */
51
#define strncasecmp _strnicmp
52
#elif !HAVE_STRNCASECMP
53
#error You do not have strncasecmp on your system.
54
#endif /* HAVE_STRNCASECMP */
55
56
#if defined(_MSC_VER) && (_MSC_VER <= 1800)
57
/* VS2013 doesn't know about "inline" */
58
#define inline __inline
59
#elif defined(AIX_CC)
60
#define inline
61
#endif
62
63
/* The following helper functions are used to speed up parsing. They
64
 * are faster than their ctype counterparts because they assume that
65
 * the input is in ASCII and that the locale is set to "C". The
66
 * compiler will also inline these functions, providing an additional
67
 * speedup by saving on function calls.
68
 */
69
static inline int is_ws_char(char c)
70
188k
{
71
188k
  return c == ' '
72
187k
      || c == '\t'
73
186k
      || c == '\n'
74
186k
      || c == '\r';
75
188k
}
76
77
static inline int is_hex_char(char c)
78
13.8k
{
79
13.8k
  return (c >= '0' && c <= '9')
80
10.1k
      || (c >= 'A' && c <= 'F')
81
6.07k
      || (c >= 'a' && c <= 'f');
82
13.8k
}
83
84
/* Use C99 NAN by default; if not available, nan("") should work too. */
85
#ifndef NAN
86
#define NAN nan("")
87
#endif /* !NAN */
88
89
static const char json_null_str[] = "null";
90
static const int json_null_str_len = sizeof(json_null_str) - 1;
91
static const char json_inf_str[] = "Infinity";
92
/* Swapped case "Infinity" to avoid need to call tolower() on input chars: */
93
static const char json_inf_str_invert[] = "iNFINITY";
94
static const unsigned int json_inf_str_len = sizeof(json_inf_str) - 1;
95
static const char json_nan_str[] = "NaN";
96
static const int json_nan_str_len = sizeof(json_nan_str) - 1;
97
static const char json_true_str[] = "true";
98
static const int json_true_str_len = sizeof(json_true_str) - 1;
99
static const char json_false_str[] = "false";
100
static const int json_false_str_len = sizeof(json_false_str) - 1;
101
102
/* clang-format off */
103
static const char *json_tokener_errors[] = {
104
  "success",
105
  "continue",
106
  "nesting too deep",
107
  "unexpected end of data",
108
  "unexpected character",
109
  "null expected",
110
  "boolean expected",
111
  "number expected",
112
  "array value separator ',' expected",
113
  "quoted object property name expected",
114
  "object property name separator ':' expected",
115
  "object value separator ',' expected",
116
  "invalid string sequence",
117
  "expected comment",
118
  "invalid utf-8 string",
119
  "buffer size overflow",
120
  "out of memory"
121
};
122
/* clang-format on */
123
124
/**
125
 * validete the utf-8 string in strict model.
126
 * if not utf-8 format, return err.
127
 */
128
static json_bool json_tokener_validate_utf8(const char c, unsigned int *nBytes);
129
130
static int json_tokener_parse_double(const char *buf, int len, double *retval);
131
132
const char *json_tokener_error_desc(enum json_tokener_error jerr)
133
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.86k
#define IS_HIGH_SURROGATE(uc) (((uc)&0xFC00) == 0xD800)
149
2.14k
#define IS_LOW_SURROGATE(uc) (((uc)&0xFC00) == 0xDC00)
150
498
#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.49k
{
155
2.49k
  struct json_tokener *tok;
156
157
2.49k
  tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
158
2.49k
  if (!tok)
159
0
    return NULL;
160
2.49k
  tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
161
2.49k
  if (!tok->stack)
162
0
  {
163
0
    free(tok);
164
0
    return NULL;
165
0
  }
166
2.49k
  tok->pb = printbuf_new();
167
2.49k
  if (!tok->pb)
168
0
  {
169
0
    free(tok->stack);
170
0
    free(tok);
171
0
    return NULL;
172
0
  }
173
2.49k
  tok->max_depth = depth;
174
2.49k
  json_tokener_reset(tok);
175
2.49k
  return tok;
176
2.49k
}
177
178
struct json_tokener *json_tokener_new(void)
179
2.49k
{
180
2.49k
  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
181
2.49k
}
182
183
void json_tokener_free(struct json_tokener *tok)
184
2.49k
{
185
2.49k
  json_tokener_reset(tok);
186
2.49k
  if (tok->pb)
187
2.49k
    printbuf_free(tok->pb);
188
2.49k
  free(tok->stack);
189
2.49k
  free(tok);
190
2.49k
}
191
192
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
193
84.6k
{
194
84.6k
  tok->stack[depth].state = json_tokener_state_eatws;
195
84.6k
  tok->stack[depth].saved_state = json_tokener_state_start;
196
84.6k
  json_object_put(tok->stack[depth].current);
197
84.6k
  tok->stack[depth].current = NULL;
198
84.6k
  free(tok->stack[depth].obj_field_name);
199
84.6k
  tok->stack[depth].obj_field_name = NULL;
200
84.6k
}
201
202
void json_tokener_reset(struct json_tokener *tok)
203
4.98k
{
204
4.98k
  int i;
205
4.98k
  if (!tok)
206
0
    return;
207
208
11.5k
  for (i = tok->depth; i >= 0; i--)
209
6.61k
    json_tokener_reset_level(tok, i);
210
4.98k
  tok->depth = 0;
211
4.98k
  tok->err = json_tokener_success;
212
4.98k
}
213
214
struct json_object *json_tokener_parse(const char *str)
215
2.49k
{
216
2.49k
  enum json_tokener_error jerr_ignored;
217
2.49k
  struct json_object *obj;
218
2.49k
  obj = json_tokener_parse_verbose(str, &jerr_ignored);
219
2.49k
  return obj;
220
2.49k
}
221
222
struct json_object *json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
223
2.49k
{
224
2.49k
  struct json_tokener *tok;
225
2.49k
  struct json_object *obj;
226
227
2.49k
  tok = json_tokener_new();
228
2.49k
  if (!tok)
229
0
  {
230
0
    *error = json_tokener_error_memory;
231
0
    return NULL;
232
0
  }
233
2.49k
  obj = json_tokener_parse_ex(tok, str, -1);
234
2.49k
  *error = tok->err;
235
2.49k
  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.49k
  )
245
246
2.04k
  {
247
2.04k
    if (obj != NULL)
248
0
      json_object_put(obj);
249
2.04k
    obj = NULL;
250
2.04k
  }
251
252
2.49k
  json_tokener_free(tok);
253
2.49k
  return obj;
254
2.49k
}
255
256
925k
#define state tok->stack[tok->depth].state
257
336k
#define saved_state tok->stack[tok->depth].saved_state
258
161k
#define current tok->stack[tok->depth].current
259
53.4k
#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
463k
  (((tok)->char_offset == len)                                         \
281
463k
       ? (((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
463k
       : (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) &&                \
286
463k
           (!json_tokener_validate_utf8(*str, nBytesp)))               \
287
463k
              ? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
288
463k
              : (((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
781k
#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
72.1k
  do {                                                  \
303
72.1k
    if (printbuf_memappend((p), (s), (l)) < 0)    \
304
72.1k
    {                                             \
305
0
      tok->err = json_tokener_error_memory; \
306
0
      goto out;                             \
307
0
    }                                             \
308
72.1k
  } 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.49k
{
314
2.49k
  struct json_object *obj = NULL;
315
2.49k
  char c = '\1';
316
2.49k
  unsigned int nBytes = 0;
317
2.49k
  unsigned int *nBytesp = &nBytes;
318
319
2.49k
#ifdef HAVE_USELOCALE
320
2.49k
  locale_t oldlocale = uselocale(NULL);
321
2.49k
  locale_t newloc;
322
#elif defined(HAVE_SETLOCALE)
323
  char *oldlocale = NULL;
324
#endif
325
326
2.49k
  tok->char_offset = 0;
327
2.49k
  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.49k
  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.49k
#ifdef HAVE_USELOCALE
342
2.49k
  {
343
2.49k
    locale_t duploc = duplocale(oldlocale);
344
2.49k
    if (duploc == NULL && errno == ENOMEM)
345
0
    {
346
0
      tok->err = json_tokener_error_memory;
347
0
      return NULL;
348
0
    }
349
2.49k
    newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
350
2.49k
    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.49k
    uselocale(newloc);
362
2.49k
  }
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
121k
  while (PEEK_CHAR(c, tok)) // Note: c might be '\0' !
381
121k
  {
382
383
485k
  redo_char:
384
485k
    switch (state)
385
485k
    {
386
387
185k
    case json_tokener_state_eatws:
388
      /* Advance until we change state */
389
186k
      while (is_ws_char(c))
390
1.90k
      {
391
1.90k
        if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
392
0
          goto out;
393
1.90k
      }
394
185k
      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
183k
      else
401
183k
      {
402
183k
        state = saved_state;
403
183k
        goto redo_char;
404
183k
      }
405
1.33k
      break;
406
407
41.7k
    case json_tokener_state_start:
408
41.7k
      switch (c)
409
41.7k
      {
410
2.51k
      case '{':
411
2.51k
        state = json_tokener_state_eatws;
412
2.51k
        saved_state = json_tokener_state_object_field_start;
413
2.51k
        current = json_object_new_object();
414
2.51k
        if (current == NULL)
415
0
        {
416
0
          tok->err = json_tokener_error_memory;
417
0
          goto out;
418
0
        }
419
2.51k
        break;
420
5.54k
      case '[':
421
5.54k
        state = json_tokener_state_eatws;
422
5.54k
        saved_state = json_tokener_state_array;
423
5.54k
        current = json_object_new_array();
424
5.54k
        if (current == NULL)
425
0
        {
426
0
          tok->err = json_tokener_error_memory;
427
0
          goto out;
428
0
        }
429
5.54k
        break;
430
5.54k
      case 'I':
431
668
      case 'i':
432
668
        state = json_tokener_state_inf;
433
668
        printbuf_reset(tok->pb);
434
668
        tok->st_pos = 0;
435
668
        goto redo_char;
436
665
      case 'N':
437
1.49k
      case 'n':
438
1.49k
        state = json_tokener_state_null; // or NaN
439
1.49k
        printbuf_reset(tok->pb);
440
1.49k
        tok->st_pos = 0;
441
1.49k
        goto redo_char;
442
747
      case '\'':
443
747
        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
296
      case 'T':
456
765
      case 't':
457
1.27k
      case 'F':
458
1.55k
      case 'f':
459
1.55k
        state = json_tokener_state_boolean;
460
1.55k
        printbuf_reset(tok->pb);
461
1.55k
        tok->st_pos = 0;
462
1.55k
        goto redo_char;
463
12.7k
      case '0':
464
14.3k
      case '1':
465
15.4k
      case '2':
466
16.1k
      case '3':
467
16.8k
      case '4':
468
17.9k
      case '5':
469
20.2k
      case '6':
470
21.4k
      case '7':
471
23.8k
      case '8':
472
26.3k
      case '9':
473
28.2k
      case '-':
474
28.2k
        state = json_tokener_state_number;
475
28.2k
        printbuf_reset(tok->pb);
476
28.2k
        tok->is_double = 0;
477
28.2k
        goto redo_char;
478
229
      default: tok->err = json_tokener_error_parse_unexpected; goto out;
479
41.7k
      }
480
9.53k
      break;
481
482
38.2k
    case json_tokener_state_finish:
483
38.2k
      if (tok->depth == 0)
484
410
        goto out;
485
37.8k
      obj = json_object_get(current);
486
37.8k
      json_tokener_reset_level(tok, tok->depth);
487
37.8k
      tok->depth--;
488
37.8k
      goto redo_char;
489
490
1.45k
    case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
491
1.45k
    {
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.45k
      int is_negative = 0;
500
501
      /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
502
12.6k
      while (tok->st_pos < (int)json_inf_str_len)
503
11.2k
      {
504
11.2k
        char inf_char = *str;
505
11.2k
        if (inf_char != json_inf_str[tok->st_pos] &&
506
5.90k
            ((tok->flags & JSON_TOKENER_STRICT) ||
507
5.90k
              inf_char != json_inf_str_invert[tok->st_pos])
508
11.2k
           )
509
71
        {
510
71
          tok->err = json_tokener_error_parse_unexpected;
511
71
          goto out;
512
71
        }
513
11.2k
        tok->st_pos++;
514
11.2k
        (void)ADVANCE_CHAR(str, tok);
515
11.2k
        if (!PEEK_CHAR(c, tok))
516
0
        {
517
          /* out of input chars, for now at least */
518
0
          goto out;
519
0
        }
520
11.2k
      }
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.38k
      if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
526
771
      {
527
771
        is_negative = 1;
528
771
      }
529
1.38k
      current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
530
1.38k
      if (current == NULL)
531
0
      {
532
0
        tok->err = json_tokener_error_memory;
533
0
        goto out;
534
0
      }
535
1.38k
      saved_state = json_tokener_state_finish;
536
1.38k
      state = json_tokener_state_eatws;
537
1.38k
      goto redo_char;
538
1.38k
    }
539
0
    break;
540
6.34k
    case json_tokener_state_null: /* aka starts with 'n' */
541
6.34k
    {
542
6.34k
      int size;
543
6.34k
      int size_nan;
544
6.34k
      printbuf_memappend_checked(tok->pb, &c, 1);
545
6.34k
      size = json_min(tok->st_pos + 1, json_null_str_len);
546
6.34k
      size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
547
6.34k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
548
6.34k
           strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
549
2.85k
          (strncmp(json_null_str, tok->pb->buf, size) == 0))
550
3.49k
      {
551
3.49k
        if (tok->st_pos == json_null_str_len)
552
491
        {
553
491
          current = NULL;
554
491
          saved_state = json_tokener_state_finish;
555
491
          state = json_tokener_state_eatws;
556
491
          goto redo_char;
557
491
        }
558
3.49k
      }
559
2.85k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
560
2.85k
                strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
561
90
               (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
562
2.76k
      {
563
2.76k
        if (tok->st_pos == json_nan_str_len)
564
915
        {
565
915
          current = json_object_new_double(NAN);
566
915
          if (current == NULL)
567
0
          {
568
0
            tok->err = json_tokener_error_memory;
569
0
            goto out;
570
0
          }
571
915
          saved_state = json_tokener_state_finish;
572
915
          state = json_tokener_state_eatws;
573
915
          goto redo_char;
574
915
        }
575
2.76k
      }
576
90
      else
577
90
      {
578
90
        tok->err = json_tokener_error_parse_null;
579
90
        goto out;
580
90
      }
581
4.85k
      tok->st_pos++;
582
4.85k
    }
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
900
      else if (c == '/')
591
858
      {
592
858
        state = json_tokener_state_comment_eol;
593
858
      }
594
42
      else
595
42
      {
596
42
        tok->err = json_tokener_error_parse_comment;
597
42
        goto out;
598
42
      }
599
1.29k
      printbuf_memappend_checked(tok->pb, &c, 1);
600
1.29k
      break;
601
602
1.68k
    case json_tokener_state_comment:
603
1.68k
    {
604
      /* Advance until we change state */
605
1.68k
      const char *case_start = str;
606
98.8k
      while (c != '*')
607
97.2k
      {
608
97.2k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
609
124
        {
610
124
          printbuf_memappend_checked(tok->pb, case_start,
611
124
                                     str - case_start);
612
124
          goto out;
613
124
        }
614
97.2k
      }
615
1.56k
      printbuf_memappend_checked(tok->pb, case_start, 1 + str - case_start);
616
1.56k
      state = json_tokener_state_comment_end;
617
1.56k
    }
618
0
    break;
619
620
858
    case json_tokener_state_comment_eol:
621
858
    {
622
      /* Advance until we change state */
623
858
      const char *case_start = str;
624
28.4k
      while (c != '\n')
625
27.6k
      {
626
27.6k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
627
68
        {
628
68
          printbuf_memappend_checked(tok->pb, case_start,
629
68
                                     str - case_start);
630
68
          goto out;
631
68
        }
632
27.6k
      }
633
790
      printbuf_memappend_checked(tok->pb, case_start, str - case_start);
634
790
      MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
635
790
      state = json_tokener_state_eatws;
636
790
    }
637
0
    break;
638
639
1.56k
    case json_tokener_state_comment_end:
640
1.56k
      printbuf_memappend_checked(tok->pb, &c, 1);
641
1.56k
      if (c == '/')
642
268
      {
643
268
        MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
644
268
        state = json_tokener_state_eatws;
645
268
      }
646
1.29k
      else
647
1.29k
      {
648
1.29k
        state = json_tokener_state_comment;
649
1.29k
      }
650
1.56k
      break;
651
652
4.82k
    case json_tokener_state_string:
653
4.82k
    {
654
      /* Advance until we change state */
655
4.82k
      const char *case_start = str;
656
43.3k
      while (1)
657
43.3k
      {
658
43.3k
        if (c == tok->quote_char)
659
1.07k
        {
660
1.07k
          printbuf_memappend_checked(tok->pb, case_start,
661
1.07k
                                     str - case_start);
662
1.07k
          current =
663
1.07k
              json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
664
1.07k
          if (current == NULL)
665
0
          {
666
0
            tok->err = json_tokener_error_memory;
667
0
            goto out;
668
0
          }
669
1.07k
          saved_state = json_tokener_state_finish;
670
1.07k
          state = json_tokener_state_eatws;
671
1.07k
          break;
672
1.07k
        }
673
42.2k
        else if (c == '\\')
674
3.46k
        {
675
3.46k
          printbuf_memappend_checked(tok->pb, case_start,
676
3.46k
                                     str - case_start);
677
3.46k
          saved_state = json_tokener_state_string;
678
3.46k
          state = json_tokener_state_string_escape;
679
3.46k
          break;
680
3.46k
        }
681
38.7k
        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.7k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
688
284
        {
689
284
          printbuf_memappend_checked(tok->pb, case_start,
690
284
                                     str - case_start);
691
284
          goto out;
692
284
        }
693
38.7k
      }
694
4.82k
    }
695
4.53k
    break;
696
697
4.93k
    case json_tokener_state_string_escape:
698
4.93k
      switch (c)
699
4.93k
      {
700
246
      case '"':
701
870
      case '\\':
702
1.09k
      case '/':
703
1.09k
        printbuf_memappend_checked(tok->pb, &c, 1);
704
1.09k
        state = saved_state;
705
1.09k
        break;
706
278
      case 'b':
707
533
      case 'n':
708
744
      case 'r':
709
1.10k
      case 't':
710
1.40k
      case 'f':
711
1.40k
        if (c == 'b')
712
278
          printbuf_memappend_checked(tok->pb, "\b", 1);
713
1.12k
        else if (c == 'n')
714
255
          printbuf_memappend_checked(tok->pb, "\n", 1);
715
872
        else if (c == 'r')
716
211
          printbuf_memappend_checked(tok->pb, "\r", 1);
717
661
        else if (c == 't')
718
356
          printbuf_memappend_checked(tok->pb, "\t", 1);
719
305
        else if (c == 'f')
720
305
          printbuf_memappend_checked(tok->pb, "\f", 1);
721
1.40k
        state = saved_state;
722
1.40k
        break;
723
2.38k
      case 'u':
724
2.38k
        tok->ucs_char = 0;
725
2.38k
        tok->st_pos = 0;
726
2.38k
        state = json_tokener_state_escape_unicode;
727
2.38k
        break;
728
51
      default: tok->err = json_tokener_error_parse_string; goto out;
729
4.93k
      }
730
4.88k
      break;
731
732
      // ===================================================
733
734
4.88k
    case json_tokener_state_escape_unicode:
735
3.52k
    {
736
      /* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */
737
13.9k
      while (1)
738
13.9k
      {
739
13.9k
        if (!c || !is_hex_char(c))
740
79
        {
741
79
          tok->err = json_tokener_error_parse_string;
742
79
          goto out;
743
79
        }
744
13.8k
        tok->ucs_char |=
745
13.8k
            ((unsigned int)jt_hexdigit(c) << ((3 - tok->st_pos) * 4));
746
13.8k
        tok->st_pos++;
747
13.8k
        if (tok->st_pos >= 4)
748
3.44k
          break;
749
750
10.4k
        (void)ADVANCE_CHAR(str, tok);
751
10.4k
        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
10.4k
      }
762
3.44k
      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
3.44k
      if (tok->high_surrogate)
768
1.12k
      {
769
1.12k
        if (IS_LOW_SURROGATE(tok->ucs_char))
770
498
        {
771
          /* Recalculate the ucs_char, then fall thru to process normally */
772
498
          tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate,
773
498
                                                tok->ucs_char);
774
498
        }
775
627
        else
776
627
        {
777
          /* High surrogate was not followed by a low surrogate
778
           * Replace the high and process the rest normally
779
           */
780
627
          printbuf_memappend_checked(tok->pb,
781
627
                                     (char *)utf8_replacement_char, 3);
782
627
        }
783
1.12k
        tok->high_surrogate = 0;
784
1.12k
      }
785
786
3.44k
      if (tok->ucs_char < 0x80)
787
383
      {
788
383
        unsigned char unescaped_utf[1];
789
383
        unescaped_utf[0] = tok->ucs_char;
790
383
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 1);
791
383
      }
792
3.06k
      else if (tok->ucs_char < 0x800)
793
205
      {
794
205
        unsigned char unescaped_utf[2];
795
205
        unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
796
205
        unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
797
205
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 2);
798
205
      }
799
2.86k
      else if (IS_HIGH_SURROGATE(tok->ucs_char))
800
1.84k
      {
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.84k
        tok->high_surrogate = tok->ucs_char;
816
1.84k
        tok->ucs_char = 0;
817
1.84k
        state = json_tokener_state_escape_unicode_need_escape;
818
1.84k
        break;
819
1.84k
      }
820
1.02k
      else if (IS_LOW_SURROGATE(tok->ucs_char))
821
282
      {
822
        /* Got a low surrogate not preceded by a high */
823
282
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
824
282
      }
825
738
      else if (tok->ucs_char < 0x10000)
826
431
      {
827
431
        unsigned char unescaped_utf[3];
828
431
        unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
829
431
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
830
431
        unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
831
431
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 3);
832
431
      }
833
307
      else if (tok->ucs_char < 0x110000)
834
307
      {
835
307
        unsigned char unescaped_utf[4];
836
307
        unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
837
307
        unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
838
307
        unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
839
307
        unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
840
307
        printbuf_memappend_checked(tok->pb, (char *)unescaped_utf, 4);
841
307
      }
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.60k
      state = saved_state; // i.e. _state_string or _state_object_field
848
1.60k
    }
849
0
    break;
850
851
1.84k
    case json_tokener_state_escape_unicode_need_escape:
852
      // We get here after processing a high_surrogate
853
      // require a '\\' char
854
1.84k
      if (!c || c != '\\')
855
450
      {
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
450
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
861
450
        tok->high_surrogate = 0;
862
450
        tok->ucs_char = 0;
863
450
        tok->st_pos = 0;
864
450
        state = saved_state;
865
450
        goto redo_char;
866
450
      }
867
1.39k
      state = json_tokener_state_escape_unicode_need_u;
868
1.39k
      break;
869
870
1.39k
    case json_tokener_state_escape_unicode_need_u:
871
      /* We already had a \ char, check that it's \u */
872
1.39k
      if (!c || c != 'u')
873
252
      {
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
252
        printbuf_memappend_checked(tok->pb, (char *)utf8_replacement_char, 3);
880
252
        tok->high_surrogate = 0;
881
252
        tok->ucs_char = 0;
882
252
        tok->st_pos = 0;
883
252
        state = json_tokener_state_string_escape;
884
252
        goto redo_char;
885
252
      }
886
1.13k
      state = json_tokener_state_escape_unicode;
887
1.13k
      break;
888
889
      // ===================================================
890
891
8.23k
    case json_tokener_state_boolean:
892
8.23k
    {
893
8.23k
      int size1, size2;
894
8.23k
      printbuf_memappend_checked(tok->pb, &c, 1);
895
8.23k
      size1 = json_min(tok->st_pos + 1, json_true_str_len);
896
8.23k
      size2 = json_min(tok->st_pos + 1, json_false_str_len);
897
8.23k
      if ((!(tok->flags & JSON_TOKENER_STRICT) &&
898
8.23k
           strncasecmp(json_true_str, tok->pb->buf, size1) == 0) ||
899
4.61k
          (strncmp(json_true_str, tok->pb->buf, size1) == 0))
900
3.61k
      {
901
3.61k
        if (tok->st_pos == json_true_str_len)
902
703
        {
903
703
          current = json_object_new_boolean(1);
904
703
          if (current == NULL)
905
0
          {
906
0
            tok->err = json_tokener_error_memory;
907
0
            goto out;
908
0
          }
909
703
          saved_state = json_tokener_state_finish;
910
703
          state = json_tokener_state_eatws;
911
703
          goto redo_char;
912
703
        }
913
3.61k
      }
914
4.61k
      else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
915
4.61k
                strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
916
133
               (strncmp(json_false_str, tok->pb->buf, size2) == 0))
917
4.48k
      {
918
4.48k
        if (tok->st_pos == json_false_str_len)
919
723
        {
920
723
          current = json_object_new_boolean(0);
921
723
          if (current == NULL)
922
0
          {
923
0
            tok->err = json_tokener_error_memory;
924
0
            goto out;
925
0
          }
926
723
          saved_state = json_tokener_state_finish;
927
723
          state = json_tokener_state_eatws;
928
723
          goto redo_char;
929
723
        }
930
4.48k
      }
931
133
      else
932
133
      {
933
133
        tok->err = json_tokener_error_parse_boolean;
934
133
        goto out;
935
133
      }
936
6.67k
      tok->st_pos++;
937
6.67k
    }
938
0
    break;
939
940
28.2k
    case json_tokener_state_number:
941
28.2k
    {
942
      /* Advance until we change state */
943
28.2k
      const char *case_start = str;
944
28.2k
      int case_len = 0;
945
28.2k
      int is_exponent = 0;
946
28.2k
      int neg_sign_ok = 1;
947
28.2k
      int pos_sign_ok = 0;
948
28.2k
      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
94.2k
      while (c && ((c >= '0' && c <= '9') ||
973
32.1k
                   (!is_exponent && (c == 'e' || c == 'E')) ||
974
31.1k
                   (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') ||
975
28.5k
                   (!tok->is_double && c == '.')))
976
65.9k
      {
977
65.9k
        pos_sign_ok = neg_sign_ok = 0;
978
65.9k
        ++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
65.9k
        switch (c)
987
65.9k
        {
988
615
        case '.':
989
615
          tok->is_double = 1;
990
615
          pos_sign_ok = 1;
991
615
          neg_sign_ok = 1;
992
615
          break;
993
342
        case 'e': /* FALLTHRU */
994
982
        case 'E':
995
982
          is_exponent = 1;
996
982
          tok->is_double = 1;
997
          /* the exponent part can begin with a negative sign */
998
982
          pos_sign_ok = neg_sign_ok = 1;
999
982
          break;
1000
64.3k
        default: break;
1001
65.9k
        }
1002
1003
65.9k
        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
65.9k
      }
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
28.2k
      if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
1018
1.85k
          c != 'I' && c != 'i' && !is_ws_char(c))
1019
177
      {
1020
177
        tok->err = json_tokener_error_parse_number;
1021
177
        goto out;
1022
177
      }
1023
28.1k
      if (case_len > 0)
1024
28.1k
        printbuf_memappend_checked(tok->pb, case_start, case_len);
1025
1026
      // Check for -Infinity
1027
28.1k
      if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
1028
790
      {
1029
790
        state = json_tokener_state_inf;
1030
790
        tok->st_pos = 0;
1031
790
        goto redo_char;
1032
790
      }
1033
27.3k
      if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
1034
1.29k
      {
1035
        /* Trim some chars off the end, to allow things
1036
           like "123e+" to parse ok. */
1037
2.91k
        while (printbuf_length(tok->pb) > 1)
1038
2.30k
        {
1039
2.30k
          char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1];
1040
2.30k
          if (last_char != 'e' && last_char != 'E' &&
1041
1.35k
              last_char != '-' && last_char != '+')
1042
686
          {
1043
686
            break;
1044
686
          }
1045
1.62k
          tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0';
1046
1.62k
          printbuf_length(tok->pb)--;
1047
1.62k
        }
1048
1.29k
      }
1049
27.3k
    }
1050
0
      {
1051
27.3k
        int64_t num64;
1052
27.3k
        uint64_t numuint64;
1053
27.3k
        double numd;
1054
27.3k
        if (!tok->is_double && tok->pb->buf[0] == '-' &&
1055
979
            json_parse_int64(tok->pb->buf, &num64) == 0)
1056
949
        {
1057
949
          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
949
          current = json_object_new_int64(num64);
1063
949
          if (current == NULL)
1064
0
          {
1065
0
            tok->err = json_tokener_error_memory;
1066
0
            goto out;
1067
0
          }
1068
949
        }
1069
26.3k
        else if (!tok->is_double && tok->pb->buf[0] != '-' &&
1070
25.0k
                 json_parse_uint64(tok->pb->buf, &numuint64) == 0)
1071
25.0k
        {
1072
25.0k
          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
25.0k
          if (numuint64 && tok->pb->buf[0] == '0' &&
1078
249
              (tok->flags & JSON_TOKENER_STRICT))
1079
0
          {
1080
0
            tok->err = json_tokener_error_parse_number;
1081
0
            goto out;
1082
0
          }
1083
25.0k
          if (numuint64 <= INT64_MAX)
1084
24.7k
          {
1085
24.7k
            num64 = (uint64_t)numuint64;
1086
24.7k
            current = json_object_new_int64(num64);
1087
24.7k
            if (current == NULL)
1088
0
            {
1089
0
              tok->err = json_tokener_error_memory;
1090
0
              goto out;
1091
0
            }
1092
24.7k
          }
1093
300
          else
1094
300
          {
1095
300
            current = json_object_new_uint64(numuint64);
1096
300
            if (current == NULL)
1097
0
            {
1098
0
              tok->err = json_tokener_error_memory;
1099
0
              goto out;
1100
0
            }
1101
300
          }
1102
25.0k
        }
1103
1.32k
        else if (tok->is_double &&
1104
1.29k
                 json_tokener_parse_double(
1105
1.29k
                     tok->pb->buf, printbuf_length(tok->pb), &numd) == 0)
1106
1.28k
        {
1107
1.28k
          current = json_object_new_double_s(numd, tok->pb->buf);
1108
1.28k
          if (current == NULL)
1109
0
          {
1110
0
            tok->err = json_tokener_error_memory;
1111
0
            goto out;
1112
0
          }
1113
1.28k
        }
1114
42
        else
1115
42
        {
1116
42
          tok->err = json_tokener_error_parse_number;
1117
42
          goto out;
1118
42
        }
1119
27.2k
        saved_state = json_tokener_state_finish;
1120
27.2k
        state = json_tokener_state_eatws;
1121
27.2k
        goto redo_char;
1122
27.3k
      }
1123
0
      break;
1124
1125
25.9k
    case json_tokener_state_array_after_sep:
1126
31.4k
    case json_tokener_state_array:
1127
31.4k
      if (c == ']')
1128
2.97k
      {
1129
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1130
2.97k
        json_object_array_shrink(current, 0);
1131
1132
2.97k
        if (state == json_tokener_state_array_after_sep &&
1133
211
            (tok->flags & JSON_TOKENER_STRICT))
1134
0
        {
1135
0
          tok->err = json_tokener_error_parse_unexpected;
1136
0
          goto out;
1137
0
        }
1138
2.97k
        saved_state = json_tokener_state_finish;
1139
2.97k
        state = json_tokener_state_eatws;
1140
2.97k
      }
1141
28.4k
      else
1142
28.4k
      {
1143
28.4k
        if (tok->depth >= tok->max_depth - 1)
1144
2
        {
1145
2
          tok->err = json_tokener_error_depth;
1146
2
          goto out;
1147
2
        }
1148
28.4k
        state = json_tokener_state_array_add;
1149
28.4k
        tok->depth++;
1150
28.4k
        json_tokener_reset_level(tok, tok->depth);
1151
28.4k
        goto redo_char;
1152
28.4k
      }
1153
2.97k
      break;
1154
1155
27.4k
    case json_tokener_state_array_add:
1156
27.4k
      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.4k
      saved_state = json_tokener_state_array_sep;
1162
27.4k
      state = json_tokener_state_eatws;
1163
27.4k
      goto redo_char;
1164
1165
27.4k
    case json_tokener_state_array_sep:
1166
27.4k
      if (c == ']')
1167
1.38k
      {
1168
        // Minimize memory usage; assume parsed objs are unlikely to be changed
1169
1.38k
        json_object_array_shrink(current, 0);
1170
1171
1.38k
        saved_state = json_tokener_state_finish;
1172
1.38k
        state = json_tokener_state_eatws;
1173
1.38k
      }
1174
26.0k
      else if (c == ',')
1175
25.9k
      {
1176
25.9k
        saved_state = json_tokener_state_array_after_sep;
1177
25.9k
        state = json_tokener_state_eatws;
1178
25.9k
      }
1179
151
      else
1180
151
      {
1181
151
        tok->err = json_tokener_error_parse_array;
1182
151
        goto out;
1183
151
      }
1184
27.3k
      break;
1185
1186
27.3k
    case json_tokener_state_object_field_start:
1187
12.2k
    case json_tokener_state_object_field_start_after_sep:
1188
12.2k
      if (c == '}')
1189
795
      {
1190
795
        if (state == json_tokener_state_object_field_start_after_sep &&
1191
221
            (tok->flags & JSON_TOKENER_STRICT))
1192
0
        {
1193
0
          tok->err = json_tokener_error_parse_unexpected;
1194
0
          goto out;
1195
0
        }
1196
795
        saved_state = json_tokener_state_finish;
1197
795
        state = json_tokener_state_eatws;
1198
795
      }
1199
11.4k
      else if (c == '"' || c == '\'')
1200
11.2k
      {
1201
11.2k
        tok->quote_char = c;
1202
11.2k
        printbuf_reset(tok->pb);
1203
11.2k
        state = json_tokener_state_object_field;
1204
11.2k
      }
1205
193
      else
1206
193
      {
1207
193
        tok->err = json_tokener_error_parse_object_key_name;
1208
193
        goto out;
1209
193
      }
1210
12.0k
      break;
1211
1212
12.4k
    case json_tokener_state_object_field:
1213
12.4k
    {
1214
      /* Advance until we change state */
1215
12.4k
      const char *case_start = str;
1216
101k
      while (1)
1217
101k
      {
1218
101k
        if (c == tok->quote_char)
1219
11.0k
        {
1220
11.0k
          printbuf_memappend_checked(tok->pb, case_start,
1221
11.0k
                                     str - case_start);
1222
11.0k
          obj_field_name = strdup(tok->pb->buf);
1223
11.0k
          if (obj_field_name == NULL)
1224
0
          {
1225
0
            tok->err = json_tokener_error_memory;
1226
0
            goto out;
1227
0
          }
1228
11.0k
          saved_state = json_tokener_state_object_field_end;
1229
11.0k
          state = json_tokener_state_eatws;
1230
11.0k
          break;
1231
11.0k
        }
1232
90.9k
        else if (c == '\\')
1233
1.22k
        {
1234
1.22k
          printbuf_memappend_checked(tok->pb, case_start,
1235
1.22k
                                     str - case_start);
1236
1.22k
          saved_state = json_tokener_state_object_field;
1237
1.22k
          state = json_tokener_state_string_escape;
1238
1.22k
          break;
1239
1.22k
        }
1240
89.6k
        if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
1241
119
        {
1242
119
          printbuf_memappend_checked(tok->pb, case_start,
1243
119
                                     str - case_start);
1244
119
          goto out;
1245
119
        }
1246
89.6k
      }
1247
12.4k
    }
1248
12.3k
    break;
1249
1250
12.3k
    case json_tokener_state_object_field_end:
1251
11.0k
      if (c == ':')
1252
11.0k
      {
1253
11.0k
        saved_state = json_tokener_state_object_value;
1254
11.0k
        state = json_tokener_state_eatws;
1255
11.0k
      }
1256
49
      else
1257
49
      {
1258
49
        tok->err = json_tokener_error_parse_object_key_sep;
1259
49
        goto out;
1260
49
      }
1261
11.0k
      break;
1262
1263
11.0k
    case json_tokener_state_object_value:
1264
11.0k
      if (tok->depth >= tok->max_depth - 1)
1265
2
      {
1266
2
        tok->err = json_tokener_error_depth;
1267
2
        goto out;
1268
2
      }
1269
11.0k
      state = json_tokener_state_object_value_add;
1270
11.0k
      tok->depth++;
1271
11.0k
      json_tokener_reset_level(tok, tok->depth);
1272
11.0k
      goto redo_char;
1273
1274
10.4k
    case json_tokener_state_object_value_add:
1275
10.4k
      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
10.4k
      free(obj_field_name);
1281
10.4k
      obj_field_name = NULL;
1282
10.4k
      saved_state = json_tokener_state_object_sep;
1283
10.4k
      state = json_tokener_state_eatws;
1284
10.4k
      goto redo_char;
1285
1286
10.4k
    case json_tokener_state_object_sep:
1287
      /* { */
1288
10.4k
      if (c == '}')
1289
606
      {
1290
606
        saved_state = json_tokener_state_finish;
1291
606
        state = json_tokener_state_eatws;
1292
606
      }
1293
9.82k
      else if (c == ',')
1294
9.69k
      {
1295
9.69k
        saved_state = json_tokener_state_object_field_start_after_sep;
1296
9.69k
        state = json_tokener_state_eatws;
1297
9.69k
      }
1298
133
      else
1299
133
      {
1300
133
        tok->err = json_tokener_error_parse_object_value_sep;
1301
133
        goto out;
1302
133
      }
1303
10.2k
      break;
1304
485k
    }
1305
118k
    (void)ADVANCE_CHAR(str, tok);
1306
118k
    if (!c) // This is the char *before* advancing
1307
42
      break;
1308
118k
  } /* while(PEEK_CHAR) */
1309
1310
2.49k
out:
1311
2.49k
  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.49k
  if (c && (state == json_tokener_state_finish) && (tok->depth == 0) &&
1316
31
      (tok->flags & (JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS)) ==
1317
31
          JSON_TOKENER_STRICT)
1318
0
  {
1319
    /* unexpected char after JSON data */
1320
0
    tok->err = json_tokener_error_parse_unexpected;
1321
0
  }
1322
2.49k
  if (!c)
1323
2.00k
  {
1324
    /* We hit an eof char (0) */
1325
2.00k
    if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
1326
1.57k
      tok->err = json_tokener_error_parse_eof;
1327
2.00k
  }
1328
1329
2.49k
#ifdef HAVE_USELOCALE
1330
2.49k
  uselocale(oldlocale);
1331
2.49k
  freelocale(newloc);
1332
#elif defined(HAVE_SETLOCALE)
1333
  setlocale(LC_NUMERIC, oldlocale);
1334
  free(oldlocale);
1335
#endif
1336
1337
2.49k
  if (tok->err == json_tokener_success)
1338
447
  {
1339
447
    json_object *ret = json_object_get(current);
1340
447
    int ii;
1341
1342
    /* Partially reset, so we parse additional objects on subsequent calls. */
1343
1.07k
    for (ii = tok->depth; ii >= 0; ii--)
1344
628
      json_tokener_reset_level(tok, ii);
1345
447
    return ret;
1346
447
  }
1347
1348
2.04k
  MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
1349
2.04k
           tok->char_offset);
1350
2.04k
  return NULL;
1351
2.49k
}
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.29k
{
1392
1.29k
  char *end;
1393
1.29k
  *retval = strtod(buf, &end);
1394
1.29k
  if (buf + len == end)
1395
1.28k
    return 0; // It worked
1396
12
  return 1;
1397
1.29k
}