Coverage Report

Created: 2026-10-18 06:56

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