Coverage Report

Created: 2026-07-16 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensips/lib/cJSON.c
Line
Count
Source
1
/*
2
  Copyright (c) 2009 Dave Gamble
3
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
  of this software and associated documentation files (the "Software"), to deal
6
  in the Software without restriction, including without limitation the rights
7
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
  copies of the Software, and to permit persons to whom the Software is
9
  furnished to do so, subject to the following conditions:
10
11
  The above copyright notice and this permission notice shall be included in
12
  all copies or substantial portions of the Software.
13
14
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
  THE SOFTWARE.
21
*/
22
23
/* cJSON */
24
/* JSON parser in C. */
25
26
#include <string.h>
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <float.h>
30
#include <limits.h>
31
#include <ctype.h>
32
33
#ifdef HAVE_LIBMATH
34
  #include <math.h>
35
#endif
36
37
#include "cJSON.h"
38
#include "../mem/mem.h"
39
#include "osips_malloc.h"
40
41
/* Determine the number of bits that an integer has using the preprocessor */
42
#if INT_MAX == 32767
43
    /* 16 bits */
44
    #define INTEGER_SIZE 0x0010
45
#elif INT_MAX == 2147483647
46
    /* 32 bits */
47
    #define INTEGER_SIZE 0x0100
48
#elif INT_MAX == 9223372036854775807
49
    /* 64 bits */
50
    #define INTEGER_SIZE 0x1000
51
#else
52
    #error "Failed to determine the size of an integer"
53
#endif
54
55
#ifdef HAVE_LIBMATH
56
  #define FABS fabs
57
#else
58
  double myfabs(double x)
59
0
  {
60
0
    if ( x < 0 ) return (-x);
61
0
    return x;
62
0
  }
63
0
  #define FABS myfabs
64
#endif
65
66
67
#ifdef HAVE_LIBMATH
68
  #define FLOOR floor
69
#else
70
  double myfloor(double x)
71
0
  {
72
0
    if ( x > 0 ) return (long)x;
73
0
    return (long)(x-0.9999999999999999);
74
0
  }
75
0
  #define FLOOR myfloor
76
#endif
77
78
/* define our own boolean type */
79
typedef int cjbool;
80
0
#define true ((cjbool)1)
81
0
#define false ((cjbool)0)
82
83
static const unsigned char *global_ep = NULL;
84
85
cJSON_Hooks sys_mem_hooks = {
86
  .malloc_fn = malloc,
87
  .free_fn   = free,
88
};
89
90
cJSON_Hooks shm_mem_hooks = {
91
  .malloc_fn = osips_shm_malloc,
92
  .free_fn   = osips_shm_free,
93
};
94
95
int cJSON_NumberIsInt(cJSON *item)
96
0
{
97
0
   return ((FABS((double)item->valueint - item->valuedouble) <= DBL_EPSILON) &&
98
0
   (item->valuedouble <= INT_MAX) && (item->valuedouble >= INT_MIN));
99
0
}
100
101
const char *cJSON_GetErrorPtr(void)
102
0
{
103
0
    return (const char*) global_ep;
104
0
}
105
106
extern const char* cJSON_Version(void)
107
0
{
108
0
    static char version[15];
109
0
    sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
110
111
0
    return version;
112
0
}
113
114
/* case insensitive strcmp */
115
static int cJSON_strcasecmp(const unsigned char *s1, const unsigned char *s2)
116
0
{
117
0
    if (!s1)
118
0
    {
119
0
        return (s1 == s2) ? 0 : 1; /* both NULL? */
120
0
    }
121
0
    if (!s2)
122
0
    {
123
0
        return 1;
124
0
    }
125
0
    for(; tolower(*s1) == tolower(*s2); ++s1, ++s2)
126
0
    {
127
0
        if (*s1 == '\0')
128
0
        {
129
0
            return 0;
130
0
        }
131
0
    }
132
133
0
    return tolower(*s1) - tolower(*s2);
134
0
}
135
136
#if defined(__GNUC__) || defined(__clang__)
137
#define CJSON_TLS __thread
138
#elif defined(_MSC_VER)
139
#define CJSON_TLS __declspec(thread)
140
#else
141
#error "Thread-local storage support required for cJSON allocator hooks"
142
#endif
143
144
/* allocator hooks are switched at runtime; keep them thread-local to avoid
145
 * cross-thread SHM/PKG allocator mixing when cJSON_InitHooks() is used */
146
static CJSON_TLS void *(*cJSON_malloc)(size_t sz) = osips_pkg_malloc;
147
static CJSON_TLS void (*cJSON_free)(void *ptr) = osips_pkg_free;
148
#undef CJSON_TLS
149
150
static unsigned char* cJSON_strdup(const unsigned char* str)
151
0
{
152
0
    size_t len = 0;
153
0
    unsigned char *copy = NULL;
154
155
0
    if (str == NULL)
156
0
    {
157
0
        return NULL;
158
0
    }
159
160
0
    len = strlen((const char*)str) + 1;
161
0
    if (!(copy = (unsigned char*)cJSON_malloc(len)))
162
0
    {
163
0
        return NULL;
164
0
    }
165
0
    memcpy(copy, str, len);
166
167
0
    return copy;
168
0
}
169
170
0
static unsigned char* cJSON_strndup(const unsigned char* str, size_t len) {
171
0
    unsigned char *copy = NULL;
172
173
0
    if (str == NULL)
174
0
    {
175
0
        return NULL;
176
0
    }
177
178
0
    if (!(copy = (unsigned char*)cJSON_malloc(len + 1)))
179
0
    {
180
0
        return NULL;
181
0
    }
182
0
    memcpy(copy, str, len);
183
0
  copy[len] = 0;
184
185
0
    return copy;
186
0
}
187
188
void cJSON_InitHooks(cJSON_Hooks* hooks)
189
0
{
190
0
    if (!hooks)
191
0
    {
192
        /* Reset hooks */
193
0
        cJSON_malloc = osips_pkg_malloc;
194
0
        cJSON_free = osips_pkg_free;
195
0
        return;
196
0
    }
197
198
0
    cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : osips_pkg_malloc;
199
0
    cJSON_free = (hooks->free_fn) ? hooks->free_fn : osips_pkg_free;
200
0
}
201
202
/* Internal constructor. */
203
static cJSON *cJSON_New_Item(void)
204
0
{
205
0
    cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
206
0
    if (node)
207
0
    {
208
0
        memset(node, '\0', sizeof(cJSON));
209
0
    }
210
211
0
    return node;
212
0
}
213
214
/* Delete a cJSON structure. */
215
void cJSON_Delete(cJSON *c)
216
0
{
217
0
    cJSON *next;
218
0
    while (c)
219
0
    {
220
0
        next = c->next;
221
0
        if (!(c->type & cJSON_IsReference) && c->child)
222
0
        {
223
0
            cJSON_Delete(c->child);
224
0
        }
225
0
        if (!(c->type & cJSON_IsReference) && c->valuestring)
226
0
        {
227
0
            cJSON_free(c->valuestring);
228
0
        }
229
0
        if (!(c->type & cJSON_StringIsConst) && c->string)
230
0
        {
231
0
            cJSON_free(c->string);
232
0
        }
233
0
        cJSON_free(c);
234
0
        c = next;
235
0
    }
236
0
}
237
238
/* Parse the input text to generate a number, and populate the result into item. */
239
static const unsigned char *parse_number(cJSON *item, const unsigned char *num)
240
0
{
241
0
    double number = 0;
242
0
    unsigned char *endpointer = NULL;
243
244
0
    if (num == NULL)
245
0
    {
246
0
        return NULL;
247
0
    }
248
249
0
    number = strtod((const char*)num, (char**)&endpointer);
250
0
    if ((num == endpointer) || (num == NULL))
251
0
    {
252
        /* parse_error */
253
0
        return NULL;
254
0
    }
255
256
0
    item->valuedouble = number;
257
258
    /* use saturation in case of overflow */
259
0
    if (number >= INT_MAX)
260
0
    {
261
0
        item->valueint = INT_MAX;
262
0
    }
263
0
    else if (number <= INT_MIN)
264
0
    {
265
0
        item->valueint = INT_MIN;
266
0
    }
267
0
    else
268
0
    {
269
0
        item->valueint = (int)number;
270
0
    }
271
0
    item->type = cJSON_Number;
272
273
0
    return endpointer;
274
0
}
275
276
/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
277
double cJSON_SetNumberHelper(cJSON *object, double number)
278
0
{
279
0
    if (number >= INT_MAX)
280
0
    {
281
0
        object->valueint = INT_MAX;
282
0
    }
283
0
    else if (number <= INT_MIN)
284
0
    {
285
0
        object->valueint = INT_MIN;
286
0
    }
287
0
    else
288
0
    {
289
0
        object->valueint = cJSON_Number;
290
0
    }
291
292
0
    return object->valuedouble = number;
293
0
}
294
295
/* calculate the next largest power of 2 */
296
static int pow2gt (int x)
297
0
{
298
0
    --x;
299
300
0
    x |= x >> 1;
301
0
    x |= x >> 2;
302
0
    x |= x >> 4;
303
0
#if INTEGER_SIZE & 0x1110 /* at least 16 bit */
304
0
    x |= x >> 8;
305
0
#endif
306
0
#if INTEGER_SIZE & 0x1100 /* at least 32 bit */
307
0
    x |= x >> 16;
308
0
#endif
309
#if INTEGER_SIZE & 0x1000 /* 64 bit */
310
    x |= x >> 32;
311
#endif
312
313
0
    return x + 1;
314
0
}
315
316
typedef struct
317
{
318
    unsigned char *buffer;
319
    size_t length;
320
    size_t offset;
321
    cjbool noalloc;
322
  flush_fn *flush;
323
  void *flush_p;
324
} printbuffer;
325
326
/* realloc printbuffer if necessary to have at least "needed" bytes more */
327
static unsigned char* ensure(printbuffer *p, size_t needed)
328
0
{
329
0
    unsigned char *newbuffer = NULL;
330
0
    size_t newsize = 0;
331
0
  int written;
332
0
  int flushed = 0;
333
334
0
    if (needed > INT_MAX)
335
0
    {
336
        /* sizes bigger than INT_MAX are currently not supported */
337
0
        return NULL;
338
0
    }
339
340
0
    if (!p || !p->buffer)
341
0
    {
342
0
        return NULL;
343
0
    }
344
345
0
retry:
346
0
    if (p->offset + needed <= p->length)
347
0
    {
348
0
        return p->buffer + p->offset;
349
0
    }
350
351
0
    if (p->noalloc) {
352
0
    if (!p->flush)
353
0
      return NULL;
354
    /* we will try to flush everything, so we can re-use the same buffer */
355
0
    if (flushed)
356
0
      return NULL; /* TODO: cannot flush what's in here - shall we "remember" the error? */
357
0
    written = (p->flush)(p->buffer, p->offset, p->flush_p);
358
0
    if (written <= 0)
359
0
      return NULL;
360
0
    memmove(p->buffer, p->buffer + written, p->offset - written);
361
0
    p->offset -= written;
362
0
    flushed = 1;
363
0
    goto retry;
364
0
    }
365
366
0
    needed += p->offset;
367
0
    newsize = (size_t) pow2gt((int)needed);
368
0
    newbuffer = (unsigned char*)cJSON_malloc(newsize);
369
0
    if (!newbuffer)
370
0
    {
371
0
        cJSON_free(p->buffer);
372
0
        p->length = 0;
373
0
        p->buffer = NULL;
374
375
0
        return NULL;
376
0
    }
377
0
    if (newbuffer)
378
0
    {
379
0
        memcpy(newbuffer, p->buffer, p->length);
380
0
    }
381
0
    cJSON_free(p->buffer);
382
0
    p->length = newsize;
383
0
    p->buffer = newbuffer;
384
385
0
    return newbuffer + p->offset;
386
0
}
387
388
/* calculate the new length of the string in a printbuffer */
389
static size_t update(const printbuffer *p)
390
0
{
391
0
    const unsigned char *str = NULL;
392
0
    if (!p || !p->buffer)
393
0
    {
394
0
        return 0;
395
0
    }
396
0
    str = p->buffer + p->offset;
397
398
0
    return p->offset + strlen((const char*)str);
399
0
}
400
401
/* Render the number nicely from the given item into a string. */
402
static unsigned char *print_number(const cJSON *item, printbuffer *p)
403
0
{
404
0
    unsigned char *str = NULL;
405
0
    double d = item->valuedouble;
406
    /* special case for 0. */
407
0
    if (d == 0)
408
0
    {
409
0
        if (p)
410
0
        {
411
0
            str = ensure(p, 2);
412
0
        }
413
0
        else
414
0
        {
415
0
            str = (unsigned char*)cJSON_malloc(2);
416
0
        }
417
0
        if (str)
418
0
        {
419
0
            strcpy((char*)str,"0");
420
0
        }
421
0
    }
422
    /* value is an int */
423
0
    else if ((FABS(((double)item->valueint) - d) <= DBL_EPSILON) && (d <= INT_MAX) && (d >= INT_MIN))
424
0
    {
425
0
        if (p)
426
0
        {
427
0
            str = ensure(p, 21);
428
0
        }
429
0
        else
430
0
        {
431
            /* 2^64+1 can be represented in 21 chars. */
432
0
            str = (unsigned char*)cJSON_malloc(21);
433
0
        }
434
0
        if (str)
435
0
        {
436
0
            sprintf((char*)str, "%d", item->valueint);
437
0
        }
438
0
    }
439
    /* value is a floating point number */
440
0
    else
441
0
    {
442
0
        if (p)
443
0
        {
444
            /* This is a nice tradeoff. */
445
0
            str = ensure(p, 64);
446
0
        }
447
0
        else
448
0
        {
449
            /* This is a nice tradeoff. */
450
0
            str = (unsigned char*)cJSON_malloc(64);
451
0
        }
452
0
        if (str)
453
0
        {
454
            /* This checks for NaN and Infinity */
455
0
            if ((d * 0) != 0)
456
0
            {
457
0
                sprintf((char*)str, "null");
458
0
            }
459
0
            else if ((FABS(FLOOR(d) - d) <= DBL_EPSILON) && (FABS(d) < 1.0e60))
460
0
            {
461
0
                sprintf((char*)str, "%.0f", d);
462
0
            }
463
0
            else if ((FABS(d) < 1.0e-6) || (FABS(d) > 1.0e9))
464
0
            {
465
0
                sprintf((char*)str, "%e", d);
466
0
            }
467
0
            else
468
0
            {
469
0
                sprintf((char*)str, "%f", d);
470
0
            }
471
0
        }
472
0
    }
473
0
    return str;
474
0
}
475
476
/* parse 4 digit hexadecimal number */
477
static unsigned parse_hex4(const unsigned char *str)
478
0
{
479
0
    unsigned int h = 0;
480
0
    size_t i = 0;
481
482
0
    for (i = 0; i < 4; i++)
483
0
    {
484
        /* parse digit */
485
0
        if ((*str >= '0') && (*str <= '9'))
486
0
        {
487
0
            h += (unsigned int) (*str) - '0';
488
0
        }
489
0
        else if ((*str >= 'A') && (*str <= 'F'))
490
0
        {
491
0
            h += (unsigned int) 10 + (*str) - 'A';
492
0
        }
493
0
        else if ((*str >= 'a') && (*str <= 'f'))
494
0
        {
495
0
            h += (unsigned int) 10 + (*str) - 'a';
496
0
        }
497
0
        else /* invalid */
498
0
        {
499
0
            return 0;
500
0
        }
501
502
0
        if (i < 3)
503
0
        {
504
            /* shift left to make place for the next nibble */
505
0
            h = h << 4;
506
0
            str++;
507
0
        }
508
0
    }
509
510
0
    return h;
511
0
}
512
513
/* first bytes of UTF8 encoding for a given length in bytes */
514
static const unsigned char firstByteMark[5] =
515
{
516
    0x00, /* should never happen */
517
    0x00, /* 0xxxxxxx */
518
    0xC0, /* 110xxxxx */
519
    0xE0, /* 1110xxxx */
520
    0xF0 /* 11110xxx */
521
};
522
523
/* Parse the input text into an unescaped cstring, and populate item. */
524
static const unsigned char *parse_string(cJSON *item, const unsigned char *str, const unsigned char **ep)
525
0
{
526
0
    const unsigned char *ptr = str + 1;
527
0
    const unsigned char *end_ptr = str + 1;
528
0
    unsigned char *ptr2 = NULL;
529
0
    unsigned char *out = NULL;
530
0
    size_t len = 0;
531
0
    unsigned uc = 0;
532
0
    unsigned uc2 = 0;
533
534
    /* not a string! */
535
0
    if (*str != '\"')
536
0
    {
537
0
        *ep = str;
538
0
        goto fail;
539
0
    }
540
541
0
    while ((*end_ptr != '\"') && *end_ptr)
542
0
    {
543
0
        if (*end_ptr++ == '\\')
544
0
        {
545
0
            if (*end_ptr == '\0')
546
0
            {
547
                /* prevent buffer overflow when last input character is a backslash */
548
0
                goto fail;
549
0
            }
550
            /* Skip escaped quotes. */
551
0
            end_ptr++;
552
0
        }
553
0
        len++;
554
0
    }
555
556
    /* This is at most how long we need for the string, roughly. */
557
0
    out = (unsigned char*)cJSON_malloc(len + 1);
558
0
    if (!out)
559
0
    {
560
0
        goto fail;
561
0
    }
562
0
    item->valuestring = (char*)out; /* assign here so out will be deleted during cJSON_Delete() later */
563
0
    item->type = cJSON_String;
564
565
0
    ptr = str + 1;
566
0
    ptr2 = out;
567
    /* loop through the string literal */
568
0
    while (ptr < end_ptr)
569
0
    {
570
0
        if (*ptr != '\\')
571
0
        {
572
0
            *ptr2++ = *ptr++;
573
0
        }
574
        /* escape sequence */
575
0
        else
576
0
        {
577
0
            ptr++;
578
0
            switch (*ptr)
579
0
            {
580
0
                case 'b':
581
0
                    *ptr2++ = '\b';
582
0
                    break;
583
0
                case 'f':
584
0
                    *ptr2++ = '\f';
585
0
                    break;
586
0
                case 'n':
587
0
                    *ptr2++ = '\n';
588
0
                    break;
589
0
                case 'r':
590
0
                    *ptr2++ = '\r';
591
0
                    break;
592
0
                case 't':
593
0
                    *ptr2++ = '\t';
594
0
                    break;
595
0
                case '\"':
596
0
                case '\\':
597
0
                case '/':
598
0
                    *ptr2++ = *ptr;
599
0
                    break;
600
0
                case 'u':
601
                    /* transcode utf16 to utf8. See RFC2781 and RFC3629. */
602
0
                    uc = parse_hex4(ptr + 1); /* get the unicode char. */
603
0
                    ptr += 4;
604
0
                    if (ptr >= end_ptr)
605
0
                    {
606
                        /* invalid */
607
0
                        *ep = str;
608
0
                        goto fail;
609
0
                    }
610
                    /* check for invalid. */
611
0
                    if (((uc >= 0xDC00) && (uc <= 0xDFFF)) || (uc == 0))
612
0
                    {
613
0
                        *ep = str;
614
0
                        goto fail;
615
0
                    }
616
617
                    /* UTF16 surrogate pairs. */
618
0
                    if ((uc >= 0xD800) && (uc<=0xDBFF))
619
0
                    {
620
0
                        if ((ptr + 6) > end_ptr)
621
0
                        {
622
                            /* invalid */
623
0
                            *ep = str;
624
0
                            goto fail;
625
0
                        }
626
0
                        if ((ptr[1] != '\\') || (ptr[2] != 'u'))
627
0
                        {
628
                            /* missing second-half of surrogate. */
629
0
                            *ep = str;
630
0
                            goto fail;
631
0
                        }
632
0
                        uc2 = parse_hex4(ptr + 3);
633
0
                        ptr += 6; /* \uXXXX */
634
0
                        if ((uc2 < 0xDC00) || (uc2 > 0xDFFF))
635
0
                        {
636
                            /* invalid second-half of surrogate. */
637
0
                            *ep = str;
638
0
                            goto fail;
639
0
                        }
640
                        /* calculate unicode codepoint from the surrogate pair */
641
0
                        uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF));
642
0
                    }
643
644
                    /* encode as UTF8
645
                     * takes at maximum 4 bytes to encode:
646
                     * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
647
0
                    len = 4;
648
0
                    if (uc < 0x80)
649
0
                    {
650
                        /* normal ascii, encoding 0xxxxxxx */
651
0
                        len = 1;
652
0
                    }
653
0
                    else if (uc < 0x800)
654
0
                    {
655
                        /* two bytes, encoding 110xxxxx 10xxxxxx */
656
0
                        len = 2;
657
0
                    }
658
0
                    else if (uc < 0x10000)
659
0
                    {
660
                        /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */
661
0
                        len = 3;
662
0
                    }
663
0
                    ptr2 += len;
664
665
0
                    switch (len) {
666
0
                        case 4:
667
                            /* 10xxxxxx */
668
0
                            *--ptr2 = (unsigned char)((uc | 0x80) & 0xBF);
669
0
                            uc >>= 6;
670
0
                        case 3:
671
                            /* 10xxxxxx */
672
0
                            *--ptr2 = (unsigned char)((uc | 0x80) & 0xBF);
673
0
                            uc >>= 6;
674
0
                        case 2:
675
                            /* 10xxxxxx */
676
0
                            *--ptr2 = (unsigned char)((uc | 0x80) & 0xBF);
677
0
                            uc >>= 6;
678
0
                        case 1:
679
                            /* depending on the length in bytes this determines the
680
                             * encoding ofthe first UTF8 byte */
681
0
                            *--ptr2 = (unsigned char)((uc | firstByteMark[len]) & 0xFF);
682
0
                            break;
683
0
                        default:
684
0
                            *ep = str;
685
0
                            goto fail;
686
0
                    }
687
0
                    ptr2 += len;
688
0
                    break;
689
0
                default:
690
0
                    *ep = str;
691
0
                    goto fail;
692
0
            }
693
0
            ptr++;
694
0
        }
695
0
    }
696
0
    *ptr2 = '\0';
697
0
    if (*ptr == '\"')
698
0
    {
699
0
        ptr++;
700
0
    }
701
702
0
    return ptr;
703
704
0
fail:
705
0
    if (out != NULL)
706
0
    {
707
0
        cJSON_free(out);
708
0
        item->valuestring = NULL;
709
0
    }
710
711
0
    return NULL;
712
0
}
713
714
/* Render the cstring provided to an escaped version that can be printed. */
715
static unsigned char *print_string_ptr(const unsigned char *str, printbuffer *p)
716
0
{
717
0
    const unsigned char *ptr = NULL;
718
0
    unsigned char *ptr2 = NULL;
719
0
    unsigned char *out = NULL;
720
0
    size_t len = 0;
721
0
    cjbool flag = false;
722
0
    unsigned char token = '\0';
723
724
    /* empty string */
725
0
    if (!str)
726
0
    {
727
0
        if (p)
728
0
        {
729
0
            out = ensure(p, 3);
730
0
        }
731
0
        else
732
0
        {
733
0
            out = (unsigned char*)cJSON_malloc(3);
734
0
        }
735
0
        if (!out)
736
0
        {
737
0
            return NULL;
738
0
        }
739
0
        strcpy((char*)out, "\"\"");
740
741
0
        return out;
742
0
    }
743
744
    /* set "flag" to 1 if something needs to be escaped */
745
0
    for (ptr = str; *ptr; ptr++)
746
0
    {
747
0
        flag |= (((*ptr > 0) && (*ptr < 32)) /* unprintable characters */
748
0
                || (*ptr == '\"') /* double quote */
749
0
                || (*ptr == '\\')) /* backslash */
750
0
            ? 1
751
0
            : 0;
752
0
    }
753
    /* no characters have to be escaped */
754
0
    if (!flag)
755
0
    {
756
0
        len = (size_t)(ptr - str);
757
0
        if (p)
758
0
        {
759
0
            out = ensure(p, len + 3);
760
0
        }
761
0
        else
762
0
        {
763
0
            out = (unsigned char*)cJSON_malloc(len + 3);
764
0
        }
765
0
        if (!out)
766
0
        {
767
0
            return NULL;
768
0
        }
769
770
0
        ptr2 = out;
771
0
        *ptr2++ = '\"';
772
0
        strcpy((char*)ptr2, (const char*)str);
773
0
        ptr2[len] = '\"';
774
0
        ptr2[len + 1] = '\0';
775
776
0
        return out;
777
0
    }
778
779
0
    ptr = str;
780
    /* calculate additional space that is needed for escaping */
781
0
    while ((token = *ptr))
782
0
    {
783
0
        ++len;
784
0
        if (strchr("\"\\\b\f\n\r\t", token))
785
0
        {
786
0
            len++; /* +1 for the backslash */
787
0
        }
788
0
        else if (token < 32)
789
0
        {
790
0
            len += 5; /* +5 for \uXXXX */
791
0
        }
792
0
        ptr++;
793
0
    }
794
795
0
    if (p)
796
0
    {
797
0
        out = ensure(p, len + 3);
798
0
    }
799
0
    else
800
0
    {
801
0
        out = (unsigned char*)cJSON_malloc(len + 3);
802
0
    }
803
0
    if (!out)
804
0
    {
805
0
        return NULL;
806
0
    }
807
808
0
    ptr2 = out;
809
0
    ptr = str;
810
0
    *ptr2++ = '\"';
811
    /* copy the string */
812
0
    while (*ptr)
813
0
    {
814
0
        if ((*ptr > 31) && (*ptr != '\"') && (*ptr != '\\'))
815
0
        {
816
            /* normal character, copy */
817
0
            *ptr2++ = *ptr++;
818
0
        }
819
0
        else
820
0
        {
821
            /* character needs to be escaped */
822
0
            *ptr2++ = '\\';
823
0
            switch (token = *ptr++)
824
0
            {
825
0
                case '\\':
826
0
                    *ptr2++ = '\\';
827
0
                    break;
828
0
                case '\"':
829
0
                    *ptr2++ = '\"';
830
0
                    break;
831
0
                case '\b':
832
0
                    *ptr2++ = 'b';
833
0
                    break;
834
0
                case '\f':
835
0
                    *ptr2++ = 'f';
836
0
                    break;
837
0
                case '\n':
838
0
                    *ptr2++ = 'n';
839
0
                    break;
840
0
                case '\r':
841
0
                    *ptr2++ = 'r';
842
0
                    break;
843
0
                case '\t':
844
0
                    *ptr2++ = 't';
845
0
                    break;
846
0
                default:
847
                    /* escape and print as unicode codepoint */
848
0
                    sprintf((char*)ptr2, "u%04x", token);
849
0
                    ptr2 += 5;
850
0
                    break;
851
0
            }
852
0
        }
853
0
    }
854
0
    *ptr2++ = '\"';
855
0
    *ptr2++ = '\0';
856
857
0
    return out;
858
0
}
859
860
/* Invoke print_string_ptr (which is useful) on an item. */
861
static unsigned char *print_string(const cJSON *item, printbuffer *p)
862
0
{
863
0
    return print_string_ptr((unsigned char*)item->valuestring, p);
864
0
}
865
866
/* Predeclare these prototypes. */
867
static const unsigned char *parse_value(cJSON *item, const unsigned char *value, const unsigned char **ep);
868
static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p);
869
static const unsigned char *parse_array(cJSON *item, const unsigned char *value, const unsigned char **ep);
870
static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p);
871
static const unsigned char *parse_object(cJSON *item, const unsigned char *value, const unsigned char **ep);
872
static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p);
873
874
/* Utility to jump whitespace and cr/lf */
875
static const unsigned char *skip(const unsigned char *in)
876
0
{
877
0
    while (in && *in && (*in <= 32))
878
0
    {
879
0
        in++;
880
0
    }
881
882
0
    return in;
883
0
}
884
885
/* Parse an object - create a new root, and populate. */
886
cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cjbool require_null_terminated)
887
0
{
888
0
    const unsigned char *end = NULL;
889
    /* use global error pointer if no specific one was given */
890
0
    const unsigned char **ep = return_parse_end ? (const unsigned char**)return_parse_end : &global_ep;
891
0
    cJSON *c = cJSON_New_Item();
892
0
    *ep = NULL;
893
0
    if (!c) /* memory fail */
894
0
    {
895
0
        return NULL;
896
0
    }
897
898
0
    end = parse_value(c, skip((const unsigned char*)value), ep);
899
0
    if (!end)
900
0
    {
901
        /* parse failure. ep is set. */
902
0
        cJSON_Delete(c);
903
0
        return NULL;
904
0
    }
905
906
    /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
907
0
    if (require_null_terminated)
908
0
    {
909
0
        end = skip(end);
910
0
        if (*end)
911
0
        {
912
0
            cJSON_Delete(c);
913
0
            *ep = end;
914
0
            return NULL;
915
0
        }
916
0
    }
917
0
    if (return_parse_end)
918
0
    {
919
0
        *return_parse_end = (const char*)end;
920
0
    }
921
922
0
    return c;
923
0
}
924
925
/* Default options for cJSON_Parse */
926
cJSON *cJSON_Parse(const char *value)
927
0
{
928
0
    return cJSON_ParseWithOpts(value, 0, 0);
929
0
}
930
931
/* Render a cJSON item/entity/structure to text. */
932
char *cJSON_Print(const cJSON *item)
933
0
{
934
0
    return (char*)print_value(item, 0, 1, 0);
935
0
}
936
937
void cJSON_PurgeString(char *ptr)
938
0
{
939
0
  cJSON_free(ptr);
940
0
}
941
942
char *cJSON_PrintUnformatted(const cJSON *item)
943
0
{
944
0
    return (char*)print_value(item, 0, 0, 0);
945
0
}
946
947
char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, cjbool fmt)
948
0
{
949
0
    printbuffer p;
950
951
0
    if (prebuffer < 0)
952
0
    {
953
0
        return NULL;
954
0
    }
955
956
0
    p.buffer = (unsigned char*)cJSON_malloc((size_t)prebuffer);
957
0
    if (!p.buffer)
958
0
    {
959
0
        return NULL;
960
0
    }
961
962
0
  memset(&p, 0, sizeof(p));
963
0
    p.length = (size_t)prebuffer;
964
0
    p.offset = 0;
965
0
    p.noalloc = false;
966
967
0
    return (char*)print_value(item, 0, fmt, &p);
968
0
}
969
970
int cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cjbool fmt)
971
0
{
972
0
    printbuffer p;
973
974
0
    if (len < 0)
975
0
    {
976
0
        return false;
977
0
    }
978
979
0
  memset(&p, 0, sizeof(p));
980
0
    p.buffer = (unsigned char*)buf;
981
0
    p.length = (size_t)len;
982
0
    p.offset = 0;
983
0
    p.noalloc = true;
984
0
    return print_value(item, 0, fmt, &p) != NULL;
985
0
}
986
987
int cJSON_PrintFlushed(cJSON *item, char *buf, const int len, const int fmt, flush_fn *func, void *param)
988
0
{
989
0
    printbuffer p;
990
0
  int ret;
991
992
0
    if (len < 0)
993
0
    {
994
0
        return false;
995
0
    }
996
997
0
  memset(&p, 0, sizeof(p));
998
0
    p.buffer = (unsigned char*)buf;
999
0
    p.length = (size_t)len;
1000
0
    p.offset = 0;
1001
0
    p.noalloc = true;
1002
0
    p.flush = func;
1003
0
    p.flush_p = param;
1004
0
    ret = (print_value(item, 0, fmt, &p) != NULL);
1005
0
  if (!ret || !p.offset)
1006
0
    return ret;
1007
    /* flush everything in the end */
1008
0
  return (p.flush)(p.buffer, p.offset + 1/* last } */, p.flush_p) > 0;
1009
0
}
1010
1011
/* Parser core - when encountering text, process appropriately. */
1012
static const unsigned  char *parse_value(cJSON *item, const unsigned char *value, const unsigned char **ep)
1013
0
{
1014
0
    if (!value)
1015
0
    {
1016
        /* Fail on null. */
1017
0
        return NULL;
1018
0
    }
1019
1020
    /* parse the different types of values */
1021
0
    if (!strncmp((const char*)value, "null", 4))
1022
0
    {
1023
0
        item->type = cJSON_NULL;
1024
0
        return value + 4;
1025
0
    }
1026
0
    if (!strncmp((const char*)value, "false", 5))
1027
0
    {
1028
0
        item->type = cJSON_False;
1029
0
        return value + 5;
1030
0
    }
1031
0
    if (!strncmp((const char*)value, "true", 4))
1032
0
    {
1033
0
        item->type = cJSON_True;
1034
0
        item->valueint = 1;
1035
0
        return value + 4;
1036
0
    }
1037
0
    if (*value == '\"')
1038
0
    {
1039
0
        return parse_string(item, value, ep);
1040
0
    }
1041
0
    if ((*value == '-') || ((*value >= '0') && (*value <= '9')))
1042
0
    {
1043
0
        return parse_number(item, value);
1044
0
    }
1045
0
    if (*value == '[')
1046
0
    {
1047
0
        return parse_array(item, value, ep);
1048
0
    }
1049
0
    if (*value == '{')
1050
0
    {
1051
0
        return parse_object(item, value, ep);
1052
0
    }
1053
1054
    /* failure. */
1055
0
    *ep = value;
1056
0
    return NULL;
1057
0
}
1058
1059
/* Render a value to text. */
1060
static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p)
1061
0
{
1062
0
    unsigned char *out = NULL;
1063
1064
0
    if (!item)
1065
0
    {
1066
0
        return NULL;
1067
0
    }
1068
0
    if (p)
1069
0
    {
1070
0
        switch ((item->type) & 0xFF)
1071
0
        {
1072
0
            case cJSON_NULL:
1073
0
                out = ensure(p, 5);
1074
0
                if (out)
1075
0
                {
1076
0
                    strcpy((char*)out, "null");
1077
0
                }
1078
0
                break;
1079
0
            case cJSON_False:
1080
0
                out = ensure(p, 6);
1081
0
                if (out)
1082
0
                {
1083
0
                    strcpy((char*)out, "false");
1084
0
                }
1085
0
                break;
1086
0
            case cJSON_True:
1087
0
                out = ensure(p, 5);
1088
0
                if (out)
1089
0
                {
1090
0
                    strcpy((char*)out, "true");
1091
0
                }
1092
0
                break;
1093
0
            case cJSON_Number:
1094
0
                out = print_number(item, p);
1095
0
                break;
1096
0
            case cJSON_Raw:
1097
0
            {
1098
0
                size_t raw_length = 0;
1099
0
                if (item->valuestring == NULL)
1100
0
                {
1101
0
                    if (!p->noalloc)
1102
0
                    {
1103
0
                        cJSON_free(p->buffer);
1104
0
                    }
1105
0
                    out = NULL;
1106
0
                    break;
1107
0
                }
1108
1109
0
                raw_length = strlen(item->valuestring) + sizeof('\0');
1110
0
                out = ensure(p, raw_length);
1111
0
                if (out)
1112
0
                {
1113
0
                    memcpy(out, item->valuestring, raw_length);
1114
0
                }
1115
0
                break;
1116
0
            }
1117
0
            case cJSON_String:
1118
0
                out = print_string(item, p);
1119
0
                break;
1120
0
            case cJSON_Array:
1121
0
                out = print_array(item, depth, fmt, p);
1122
0
                break;
1123
0
            case cJSON_Object:
1124
0
                out = print_object(item, depth, fmt, p);
1125
0
                break;
1126
0
            default:
1127
0
                out = NULL;
1128
0
                break;
1129
0
        }
1130
0
    }
1131
0
    else
1132
0
    {
1133
0
        switch ((item->type) & 0xFF)
1134
0
        {
1135
0
            case cJSON_NULL:
1136
0
                out = cJSON_strdup((const unsigned char*)"null");
1137
0
                break;
1138
0
            case cJSON_False:
1139
0
                out = cJSON_strdup((const unsigned char*)"false");
1140
0
                break;
1141
0
            case cJSON_True:
1142
0
                out = cJSON_strdup((const unsigned char*)"true");
1143
0
                break;
1144
0
            case cJSON_Number:
1145
0
                out = print_number(item, 0);
1146
0
                break;
1147
0
            case cJSON_Raw:
1148
0
                out = cJSON_strdup((unsigned char*)item->valuestring);
1149
0
                break;
1150
0
            case cJSON_String:
1151
0
                out = print_string(item, 0);
1152
0
                break;
1153
0
            case cJSON_Array:
1154
0
                out = print_array(item, depth, fmt, 0);
1155
0
                break;
1156
0
            case cJSON_Object:
1157
0
                out = print_object(item, depth, fmt, 0);
1158
0
                break;
1159
0
            default:
1160
0
                out = NULL;
1161
0
                break;
1162
0
        }
1163
0
    }
1164
1165
0
    return out;
1166
0
}
1167
1168
/* Build an array from input text. */
1169
static const unsigned char *parse_array(cJSON *item, const unsigned char *value, const unsigned char **ep)
1170
0
{
1171
0
    cJSON *child = NULL;
1172
0
    if (*value != '[')
1173
0
    {
1174
        /* not an array! */
1175
0
        *ep = value;
1176
0
        goto fail;
1177
0
    }
1178
1179
0
    item->type = cJSON_Array;
1180
0
    value = skip(value + 1);
1181
0
    if (*value == ']')
1182
0
    {
1183
        /* empty array. */
1184
0
        return value + 1;
1185
0
    }
1186
1187
0
    item->child = child = cJSON_New_Item();
1188
0
    if (!item->child)
1189
0
    {
1190
        /* memory fail */
1191
0
        goto fail;
1192
0
    }
1193
    /* skip any spacing, get the value. */
1194
0
    value = skip(parse_value(child, skip(value), ep));
1195
0
    if (!value)
1196
0
    {
1197
0
        goto fail;
1198
0
    }
1199
1200
    /* loop through the comma separated array elements */
1201
0
    while (*value == ',')
1202
0
    {
1203
0
        cJSON *new_item = NULL;
1204
0
        if (!(new_item = cJSON_New_Item()))
1205
0
        {
1206
            /* memory fail */
1207
0
            goto fail;
1208
0
        }
1209
        /* add new item to end of the linked list */
1210
0
        child->next = new_item;
1211
0
        new_item->prev = child;
1212
0
        child = new_item;
1213
1214
        /* go to the next comma */
1215
0
        value = skip(parse_value(child, skip(value + 1), ep));
1216
0
        if (!value)
1217
0
        {
1218
            /* memory fail */
1219
0
            goto fail;
1220
0
        }
1221
0
    }
1222
1223
0
    if (*value == ']')
1224
0
    {
1225
        /* end of array */
1226
0
        return value + 1;
1227
0
    }
1228
1229
    /* malformed. */
1230
0
    *ep = value;
1231
1232
0
fail:
1233
0
    if (item->child != NULL)
1234
0
    {
1235
0
        cJSON_Delete(item->child);
1236
0
        item->child = NULL;
1237
0
    }
1238
1239
0
    return NULL;
1240
0
}
1241
1242
/* Render an array to text */
1243
static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p)
1244
0
{
1245
0
    unsigned char **entries;
1246
0
    unsigned char *out = NULL;
1247
0
    unsigned char *ptr = NULL;
1248
0
    unsigned char *ret = NULL;
1249
0
    size_t len = 5;
1250
0
    cJSON *child = item->child;
1251
0
    size_t numentries = 0;
1252
0
    size_t i = 0;
1253
0
    cjbool fail = false;
1254
0
    size_t tmplen = 0;
1255
1256
    /* How many entries in the array? */
1257
0
    while (child)
1258
0
    {
1259
0
        numentries++;
1260
0
        child = child->next;
1261
0
    }
1262
1263
    /* Explicitly handle numentries == 0 */
1264
0
    if (!numentries)
1265
0
    {
1266
0
        if (p)
1267
0
        {
1268
0
            out = ensure(p, 3);
1269
0
        }
1270
0
        else
1271
0
        {
1272
0
            out = (unsigned char*)cJSON_malloc(3);
1273
0
        }
1274
0
        if (out)
1275
0
        {
1276
0
            strcpy((char*)out, "[]");
1277
0
        }
1278
1279
0
        return out;
1280
0
    }
1281
1282
0
    if (p)
1283
0
    {
1284
        /* Compose the output array. */
1285
        /* opening square bracket */
1286
0
        i = p->offset;
1287
0
        ptr = ensure(p, 1);
1288
0
        if (!ptr)
1289
0
        {
1290
0
            return NULL;
1291
0
        }
1292
0
        *ptr = '[';
1293
0
        p->offset++;
1294
1295
0
        child = item->child;
1296
0
        while (child && !fail)
1297
0
        {
1298
0
            if (!print_value(child, depth + 1, fmt, p))
1299
0
            {
1300
0
                return NULL;
1301
0
            }
1302
0
            p->offset = update(p);
1303
0
            if (child->next)
1304
0
            {
1305
0
                len = fmt ? 2 : 1;
1306
0
                ptr = ensure(p, len + 1);
1307
0
                if (!ptr)
1308
0
                {
1309
0
                    return NULL;
1310
0
                }
1311
0
                *ptr++ = ',';
1312
0
                if(fmt)
1313
0
                {
1314
0
                    *ptr++ = ' ';
1315
0
                }
1316
0
                *ptr = '\0';
1317
0
                p->offset += len;
1318
0
            }
1319
0
            child = child->next;
1320
0
        }
1321
0
        ptr = ensure(p, 2);
1322
0
        if (!ptr)
1323
0
        {
1324
0
            return NULL;
1325
0
        }
1326
0
        *ptr++ = ']';
1327
0
        *ptr = '\0';
1328
0
        out = (p->buffer) + i;
1329
0
    }
1330
0
    else
1331
0
    {
1332
        /* Allocate an array to hold the pointers to all printed values */
1333
0
        entries = (unsigned char**)cJSON_malloc(numentries * sizeof(unsigned char*));
1334
0
        if (!entries)
1335
0
        {
1336
0
            return NULL;
1337
0
        }
1338
0
        memset(entries, '\0', numentries * sizeof(unsigned char*));
1339
1340
        /* Retrieve all the results: */
1341
0
        child = item->child;
1342
0
        while (child && !fail)
1343
0
        {
1344
0
            ret = print_value(child, depth + 1, fmt, 0);
1345
0
            entries[i++] = ret;
1346
0
            if (ret)
1347
0
            {
1348
0
                len += strlen((char*)ret) + 2 + (fmt ? 1 : 0);
1349
0
            }
1350
0
            else
1351
0
            {
1352
0
                fail = true;
1353
0
            }
1354
0
            child = child->next;
1355
0
        }
1356
1357
        /* If we didn't fail, try to malloc the output string */
1358
0
        if (!fail)
1359
0
        {
1360
0
            out = (unsigned char*)cJSON_malloc(len);
1361
0
        }
1362
        /* If that fails, we fail. */
1363
0
        if (!out)
1364
0
        {
1365
0
            fail = true;
1366
0
        }
1367
1368
        /* Handle failure. */
1369
0
        if (fail)
1370
0
        {
1371
            /* free all the entries in the array */
1372
0
            for (i = 0; i < numentries; i++)
1373
0
            {
1374
0
                if (entries[i])
1375
0
                {
1376
0
                    cJSON_free(entries[i]);
1377
0
                }
1378
0
            }
1379
0
            cJSON_free(entries);
1380
0
            return NULL;
1381
0
        }
1382
1383
        /* Compose the output array. */
1384
0
        *out='[';
1385
0
        ptr = out + 1;
1386
0
        *ptr = '\0';
1387
0
        for (i = 0; i < numentries; i++)
1388
0
        {
1389
0
            tmplen = strlen((char*)entries[i]);
1390
0
            memcpy(ptr, entries[i], tmplen);
1391
0
            ptr += tmplen;
1392
0
            if (i != (numentries - 1))
1393
0
            {
1394
0
                *ptr++ = ',';
1395
0
                if(fmt)
1396
0
                {
1397
0
                    *ptr++ = ' ';
1398
0
                }
1399
0
                *ptr = '\0';
1400
0
            }
1401
0
            cJSON_free(entries[i]);
1402
0
        }
1403
0
        cJSON_free(entries);
1404
0
        *ptr++ = ']';
1405
0
        *ptr++ = '\0';
1406
0
    }
1407
1408
0
    return out;
1409
0
}
1410
1411
/* Build an object from the text. */
1412
static const unsigned char *parse_object(cJSON *item, const unsigned char *value, const unsigned char **ep)
1413
0
{
1414
0
    cJSON *child = NULL;
1415
0
    if (*value != '{')
1416
0
    {
1417
        /* not an object! */
1418
0
        *ep = value;
1419
0
        goto fail;
1420
0
    }
1421
1422
0
    item->type = cJSON_Object;
1423
0
    value = skip(value + 1);
1424
0
    if (*value == '}')
1425
0
    {
1426
        /* empty object. */
1427
0
        return value + 1;
1428
0
    }
1429
1430
0
    child = cJSON_New_Item();
1431
0
    item->child = child;
1432
0
    if (!item->child)
1433
0
    {
1434
0
        goto fail;
1435
0
    }
1436
    /* parse first key */
1437
0
    value = skip(parse_string(child, skip(value), ep));
1438
0
    if (!value)
1439
0
    {
1440
0
        goto fail;
1441
0
    }
1442
    /* use string as key, not value */
1443
0
    child->string = child->valuestring;
1444
0
    child->valuestring = NULL;
1445
1446
0
    if (*value != ':')
1447
0
    {
1448
        /* invalid object. */
1449
0
        *ep = value;
1450
0
        goto fail;
1451
0
    }
1452
    /* skip any spacing, get the value. */
1453
0
    value = skip(parse_value(child, skip(value + 1), ep));
1454
0
    if (!value)
1455
0
    {
1456
0
        goto fail;
1457
0
    }
1458
1459
0
    while (*value == ',')
1460
0
    {
1461
0
        cJSON *new_item = NULL;
1462
0
        if (!(new_item = cJSON_New_Item()))
1463
0
        {
1464
            /* memory fail */
1465
0
            goto fail;
1466
0
        }
1467
        /* add to linked list */
1468
0
        child->next = new_item;
1469
0
        new_item->prev = child;
1470
1471
0
        child = new_item;
1472
0
        value = skip(parse_string(child, skip(value + 1), ep));
1473
0
        if (!value)
1474
0
        {
1475
0
            goto fail;
1476
0
        }
1477
1478
        /* use string as key, not value */
1479
0
        child->string = child->valuestring;
1480
0
        child->valuestring = NULL;
1481
1482
0
        if (*value != ':')
1483
0
        {
1484
            /* invalid object. */
1485
0
            *ep = value;
1486
0
            goto fail;
1487
0
        }
1488
        /* skip any spacing, get the value. */
1489
0
        value = skip(parse_value(child, skip(value + 1), ep));
1490
0
        if (!value)
1491
0
        {
1492
0
            goto fail;
1493
0
        }
1494
0
    }
1495
    /* end of object */
1496
0
    if (*value == '}')
1497
0
    {
1498
0
        return value + 1;
1499
0
    }
1500
1501
    /* malformed */
1502
0
    *ep = value;
1503
1504
0
fail:
1505
0
    if (item->child != NULL)
1506
0
    {
1507
0
        cJSON_Delete(item->child);
1508
0
        item->child = NULL;
1509
0
    }
1510
1511
0
    return NULL;
1512
0
}
1513
1514
/* Render an object to text. */
1515
static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p)
1516
0
{
1517
0
    unsigned char **entries = NULL;
1518
0
    unsigned char **names = NULL;
1519
0
    unsigned char *out = NULL;
1520
0
    unsigned char *ptr = NULL;
1521
0
    unsigned char *ret = NULL;
1522
0
    unsigned char *str = NULL;
1523
0
    size_t len = 7;
1524
0
    size_t i = 0;
1525
0
    size_t j = 0;
1526
0
    cJSON *child = item->child;
1527
0
    size_t numentries = 0;
1528
0
    cjbool fail = false;
1529
0
    size_t tmplen = 0;
1530
1531
    /* Count the number of entries. */
1532
0
    while (child)
1533
0
    {
1534
0
        numentries++;
1535
0
        child = child->next;
1536
0
    }
1537
1538
    /* Explicitly handle empty object case */
1539
0
    if (!numentries)
1540
0
    {
1541
0
        if (p)
1542
0
        {
1543
0
            out = ensure(p, fmt ? depth + 4 : 3);
1544
0
        }
1545
0
        else
1546
0
        {
1547
0
            out = (unsigned char*)cJSON_malloc(fmt ? depth + 4 : 3);
1548
0
        }
1549
0
        if (!out)
1550
0
        {
1551
0
            return NULL;
1552
0
        }
1553
0
        ptr = out;
1554
0
        *ptr++ = '{';
1555
0
        if (fmt) {
1556
0
            *ptr++ = '\n';
1557
0
            for (i = 0; i < depth; i++)
1558
0
            {
1559
0
                *ptr++ = '\t';
1560
0
            }
1561
0
        }
1562
0
        *ptr++ = '}';
1563
0
        *ptr++ = '\0';
1564
1565
0
        return out;
1566
0
    }
1567
1568
0
    if (p)
1569
0
    {
1570
        /* Compose the output: */
1571
0
        i = p->offset;
1572
0
        len = fmt ? 2 : 1; /* fmt: {\n */
1573
0
        ptr = ensure(p, len + 1);
1574
0
        if (!ptr)
1575
0
        {
1576
0
            return NULL;
1577
0
        }
1578
1579
0
        *ptr++ = '{';
1580
0
        if (fmt)
1581
0
        {
1582
0
            *ptr++ = '\n';
1583
0
        }
1584
0
        *ptr = '\0';
1585
0
        p->offset += len;
1586
1587
0
        child = item->child;
1588
0
        depth++;
1589
0
        while (child)
1590
0
        {
1591
0
            if (fmt)
1592
0
            {
1593
0
                ptr = ensure(p, depth);
1594
0
                if (!ptr)
1595
0
                {
1596
0
                    return NULL;
1597
0
                }
1598
0
                for (j = 0; j < depth; j++)
1599
0
                {
1600
0
                    *ptr++ = '\t';
1601
0
                }
1602
0
                p->offset += depth;
1603
0
            }
1604
1605
            /* print key */
1606
0
            if (!print_string_ptr((unsigned char*)child->string, p))
1607
0
            {
1608
0
                return NULL;
1609
0
            }
1610
0
            p->offset = update(p);
1611
1612
0
            len = fmt ? 2 : 1;
1613
0
            ptr = ensure(p, len);
1614
0
            if (!ptr)
1615
0
            {
1616
0
                return NULL;
1617
0
            }
1618
0
            *ptr++ = ':';
1619
0
            if (fmt)
1620
0
            {
1621
0
                *ptr++ = '\t';
1622
0
            }
1623
0
            p->offset+=len;
1624
1625
            /* print value */
1626
0
            if (!print_value(child, depth, fmt, p))
1627
0
            {
1628
0
                return NULL;
1629
0
            };
1630
0
            p->offset = update(p);
1631
1632
            /* print comma if not last */
1633
0
            len = (size_t) (fmt ? 1 : 0) + (child->next ? 1 : 0);
1634
0
            ptr = ensure(p, len + 1);
1635
0
            if (!ptr)
1636
0
            {
1637
0
                return NULL;
1638
0
            }
1639
0
            if (child->next)
1640
0
            {
1641
0
                *ptr++ = ',';
1642
0
            }
1643
1644
0
            if (fmt)
1645
0
            {
1646
0
                *ptr++ = '\n';
1647
0
            }
1648
0
            *ptr = '\0';
1649
0
            p->offset += len;
1650
1651
0
            child = child->next;
1652
0
        }
1653
1654
0
        ptr = ensure(p, fmt ? (depth + 1) : 2);
1655
0
        if (!ptr)
1656
0
        {
1657
0
            return NULL;
1658
0
        }
1659
0
        if (fmt)
1660
0
        {
1661
0
            for (i = 0; i < (depth - 1); i++)
1662
0
            {
1663
0
                *ptr++ = '\t';
1664
0
            }
1665
0
        }
1666
0
        *ptr++ = '}';
1667
0
        *ptr = '\0';
1668
0
        out = (p->buffer) + i;
1669
0
    }
1670
0
    else
1671
0
    {
1672
        /* Allocate space for the names and the objects */
1673
0
        entries = (unsigned char**)cJSON_malloc(numentries * sizeof(unsigned char*));
1674
0
        if (!entries)
1675
0
        {
1676
0
            return NULL;
1677
0
        }
1678
0
        names = (unsigned char**)cJSON_malloc(numentries * sizeof(unsigned char*));
1679
0
        if (!names)
1680
0
        {
1681
0
            cJSON_free(entries);
1682
0
            return NULL;
1683
0
        }
1684
0
        memset(entries, '\0', sizeof(unsigned char*) * numentries);
1685
0
        memset(names, '\0', sizeof(unsigned char*) * numentries);
1686
1687
        /* Collect all the results into our arrays: */
1688
0
        child = item->child;
1689
0
        depth++;
1690
0
        if (fmt)
1691
0
        {
1692
0
            len += depth;
1693
0
        }
1694
0
        while (child && !fail)
1695
0
        {
1696
0
            names[i] = str = print_string_ptr((unsigned char*)child->string, 0); /* print key */
1697
0
            entries[i++] = ret = print_value(child, depth, fmt, 0);
1698
0
            if (str && ret)
1699
0
            {
1700
0
                len += strlen((char*)ret) + strlen((char*)str) + 2 + (fmt ? 2 + depth : 0);
1701
0
            }
1702
0
            else
1703
0
            {
1704
0
                fail = true;
1705
0
            }
1706
0
            child = child->next;
1707
0
        }
1708
1709
        /* Try to allocate the output string */
1710
0
        if (!fail)
1711
0
        {
1712
0
            out = (unsigned char*)cJSON_malloc(len);
1713
0
        }
1714
0
        if (!out)
1715
0
        {
1716
0
            fail = true;
1717
0
        }
1718
1719
        /* Handle failure */
1720
0
        if (fail)
1721
0
        {
1722
            /* free all the printed keys and values */
1723
0
            for (i = 0; i < numentries; i++)
1724
0
            {
1725
0
                if (names[i])
1726
0
                {
1727
0
                    cJSON_free(names[i]);
1728
0
                }
1729
0
                if (entries[i])
1730
0
                {
1731
0
                    cJSON_free(entries[i]);
1732
0
                }
1733
0
            }
1734
0
            cJSON_free(names);
1735
0
            cJSON_free(entries);
1736
0
            return NULL;
1737
0
        }
1738
1739
        /* Compose the output: */
1740
0
        *out = '{';
1741
0
        ptr = out + 1;
1742
0
        if (fmt)
1743
0
        {
1744
0
            *ptr++ = '\n';
1745
0
        }
1746
0
        *ptr = '\0';
1747
0
        for (i = 0; i < numentries; i++)
1748
0
        {
1749
0
            if (fmt)
1750
0
            {
1751
0
                for (j = 0; j < depth; j++)
1752
0
                {
1753
0
                    *ptr++='\t';
1754
0
                }
1755
0
            }
1756
0
            tmplen = strlen((char*)names[i]);
1757
0
            memcpy(ptr, names[i], tmplen);
1758
0
            ptr += tmplen;
1759
0
            *ptr++ = ':';
1760
0
            if (fmt)
1761
0
            {
1762
0
                *ptr++ = '\t';
1763
0
            }
1764
0
            strcpy((char*)ptr, (char*)entries[i]);
1765
0
            ptr += strlen((char*)entries[i]);
1766
0
            if (i != (numentries - 1))
1767
0
            {
1768
0
                *ptr++ = ',';
1769
0
            }
1770
0
            if (fmt)
1771
0
            {
1772
0
                *ptr++ = '\n';
1773
0
            }
1774
0
            *ptr = '\0';
1775
0
            cJSON_free(names[i]);
1776
0
            cJSON_free(entries[i]);
1777
0
        }
1778
1779
0
        cJSON_free(names);
1780
0
        cJSON_free(entries);
1781
0
        if (fmt)
1782
0
        {
1783
0
            for (i = 0; i < (depth - 1); i++)
1784
0
            {
1785
0
                *ptr++ = '\t';
1786
0
            }
1787
0
        }
1788
0
        *ptr++ = '}';
1789
0
        *ptr++ = '\0';
1790
0
    }
1791
1792
0
    return out;
1793
0
}
1794
1795
/* Get Array size/item / object item. */
1796
int cJSON_GetArraySize(const cJSON *array)
1797
0
{
1798
0
    cJSON *c = array->child;
1799
0
    size_t i = 0;
1800
0
    while(c)
1801
0
    {
1802
0
        i++;
1803
0
        c = c->next;
1804
0
    }
1805
1806
    /* FIXME: Can overflow here. Cannot be fixed without breaking the API */
1807
1808
0
    return (int)i;
1809
0
}
1810
1811
cJSON *cJSON_GetArrayItem(const cJSON *array, int item)
1812
0
{
1813
0
    cJSON *c = array ? array->child : NULL;
1814
0
    while (c && item > 0)
1815
0
    {
1816
0
        item--;
1817
0
        c = c->next;
1818
0
    }
1819
1820
0
    return c;
1821
0
}
1822
1823
cJSON *cJSON_GetObjectItem(const cJSON *object, const char *string)
1824
0
{
1825
0
    cJSON *c = object ? object->child : NULL;
1826
0
    while (c && cJSON_strcasecmp((unsigned char*)c->string, (const unsigned char*)string))
1827
0
    {
1828
0
        c = c->next;
1829
0
    }
1830
0
    return c;
1831
0
}
1832
1833
cjbool cJSON_HasObjectItem(const cJSON *object, const char *string)
1834
0
{
1835
0
    return cJSON_GetObjectItem(object, string) ? 1 : 0;
1836
0
}
1837
1838
/* Utility for array list handling. */
1839
static void suffix_object(cJSON *prev, cJSON *item)
1840
0
{
1841
0
    prev->next = item;
1842
0
    item->prev = prev;
1843
0
}
1844
1845
/* Utility for handling references. */
1846
static cJSON *create_reference(const cJSON *item)
1847
0
{
1848
0
    cJSON *ref = cJSON_New_Item();
1849
0
    if (!ref)
1850
0
    {
1851
0
        return NULL;
1852
0
    }
1853
0
    memcpy(ref, item, sizeof(cJSON));
1854
0
    ref->string = NULL;
1855
0
    ref->type |= cJSON_IsReference;
1856
0
    ref->next = ref->prev = NULL;
1857
0
    return ref;
1858
0
}
1859
1860
/* Add item to array/object. */
1861
void cJSON_AddItemToArray(cJSON *array, cJSON *item)
1862
0
{
1863
0
    cJSON *child = NULL;
1864
1865
0
    if ((item == NULL) || (array == NULL))
1866
0
    {
1867
0
        return;
1868
0
    }
1869
1870
0
    child = array->child;
1871
1872
0
    if (child == NULL)
1873
0
    {
1874
        /* list is empty, start new one */
1875
0
        array->child = item;
1876
0
    }
1877
0
    else
1878
0
    {
1879
        /* append to the end */
1880
0
        while (child->next)
1881
0
        {
1882
0
            child = child->next;
1883
0
        }
1884
0
        suffix_object(child, item);
1885
0
    }
1886
0
}
1887
1888
void   _cJSON_AddItemToObject(cJSON *object, const str *string, cJSON *item)
1889
0
{
1890
0
    if (!item)
1891
0
    {
1892
0
        return;
1893
0
    }
1894
1895
    /* free old key and set new one */
1896
0
    if (item->string)
1897
0
    {
1898
0
        cJSON_free(item->string);
1899
0
    }
1900
0
    item->string = (char*)cJSON_strndup((const unsigned char*)string->s, string->len);
1901
1902
0
    cJSON_AddItemToArray(object,item);
1903
0
}
1904
1905
void   cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
1906
0
{
1907
0
    if (!item)
1908
0
    {
1909
0
        return;
1910
0
    }
1911
1912
    /* free old key and set new one */
1913
0
    if (item->string)
1914
0
    {
1915
0
        cJSON_free(item->string);
1916
0
    }
1917
0
    item->string = (char*)cJSON_strdup((const unsigned char*)string);
1918
1919
0
    cJSON_AddItemToArray(object,item);
1920
0
}
1921
1922
/* Add an item to an object with constant string as key */
1923
void   cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
1924
0
{
1925
0
    if (!item)
1926
0
    {
1927
0
        return;
1928
0
    }
1929
0
    if (!(item->type & cJSON_StringIsConst) && item->string)
1930
0
    {
1931
0
        cJSON_free(item->string);
1932
0
    }
1933
#if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || (__GNUC__ > 4)
1934
_Pragma("GCC diagnostic push")
1935
_Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1936
    item->string = (char*)string;
1937
_Pragma("GCC diagnostic pop")
1938
#else
1939
0
    item->string = (char*)string;
1940
0
#endif
1941
0
    item->type |= cJSON_StringIsConst;
1942
0
    cJSON_AddItemToArray(object, item);
1943
0
}
1944
1945
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
1946
0
{
1947
0
    cJSON_AddItemToArray(array, create_reference(item));
1948
0
}
1949
1950
void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
1951
0
{
1952
0
    cJSON_AddItemToObject(object, string, create_reference(item));
1953
0
}
1954
1955
static cJSON *DetachItemFromArray(cJSON *array, size_t which)
1956
0
{
1957
0
    cJSON *c = array->child;
1958
0
    while (c && (which > 0))
1959
0
    {
1960
0
        c = c->next;
1961
0
        which--;
1962
0
    }
1963
0
    if (!c)
1964
0
    {
1965
        /* item doesn't exist */
1966
0
        return NULL;
1967
0
    }
1968
0
    if (c->prev)
1969
0
    {
1970
        /* not the first element */
1971
0
        c->prev->next = c->next;
1972
0
    }
1973
0
    if (c->next)
1974
0
    {
1975
0
        c->next->prev = c->prev;
1976
0
    }
1977
0
    if (c==array->child)
1978
0
    {
1979
0
        array->child = c->next;
1980
0
    }
1981
    /* make sure the detached item doesn't point anywhere anymore */
1982
0
    c->prev = c->next = NULL;
1983
1984
0
    return c;
1985
0
}
1986
cJSON *cJSON_DetachItemFromArray(cJSON *array, int which)
1987
0
{
1988
0
    if (which < 0)
1989
0
    {
1990
0
        return NULL;
1991
0
    }
1992
1993
0
    return DetachItemFromArray(array, (size_t)which);
1994
0
}
1995
1996
void cJSON_DeleteItemFromArray(cJSON *array, int which)
1997
0
{
1998
0
    cJSON_Delete(cJSON_DetachItemFromArray(array, which));
1999
0
}
2000
2001
cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string)
2002
0
{
2003
0
    size_t i = 0;
2004
0
    cJSON *c = object->child;
2005
0
    while (c && cJSON_strcasecmp((unsigned char*)c->string, (const unsigned char*)string))
2006
0
    {
2007
0
        i++;
2008
0
        c = c->next;
2009
0
    }
2010
0
    if (c)
2011
0
    {
2012
0
        return DetachItemFromArray(object, i);
2013
0
    }
2014
2015
0
    return NULL;
2016
0
}
2017
2018
void cJSON_DeleteItemFromObject(cJSON *object, const char *string)
2019
0
{
2020
0
    cJSON_Delete(cJSON_DetachItemFromObject(object, string));
2021
0
}
2022
2023
/* Replace array/object items with new ones. */
2024
void cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
2025
0
{
2026
0
    cJSON *c = array->child;
2027
0
    while (c && (which > 0))
2028
0
    {
2029
0
        c = c->next;
2030
0
        which--;
2031
0
    }
2032
0
    if (!c)
2033
0
    {
2034
0
        cJSON_AddItemToArray(array, newitem);
2035
0
        return;
2036
0
    }
2037
0
    newitem->next = c;
2038
0
    newitem->prev = c->prev;
2039
0
    c->prev = newitem;
2040
0
    if (c == array->child)
2041
0
    {
2042
0
        array->child = newitem;
2043
0
    }
2044
0
    else
2045
0
    {
2046
0
        newitem->prev->next = newitem;
2047
0
    }
2048
0
}
2049
2050
static void ReplaceItemInArray(cJSON *array, size_t which, cJSON *newitem)
2051
0
{
2052
0
    cJSON *c = array->child;
2053
0
    while (c && (which > 0))
2054
0
    {
2055
0
        c = c->next;
2056
0
        which--;
2057
0
    }
2058
0
    if (!c)
2059
0
    {
2060
0
        return;
2061
0
    }
2062
0
    newitem->next = c->next;
2063
0
    newitem->prev = c->prev;
2064
0
    if (newitem->next)
2065
0
    {
2066
0
        newitem->next->prev = newitem;
2067
0
    }
2068
0
    if (c == array->child)
2069
0
    {
2070
0
        array->child = newitem;
2071
0
    }
2072
0
    else
2073
0
    {
2074
0
        newitem->prev->next = newitem;
2075
0
    }
2076
0
    c->next = c->prev = NULL;
2077
0
    cJSON_Delete(c);
2078
0
}
2079
void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
2080
0
{
2081
0
    if (which < 0)
2082
0
    {
2083
0
        return;
2084
0
    }
2085
2086
0
    ReplaceItemInArray(array, (size_t)which, newitem);
2087
0
}
2088
2089
void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
2090
0
{
2091
0
    size_t i = 0;
2092
0
    cJSON *c = object->child;
2093
0
    while(c && cJSON_strcasecmp((unsigned char*)c->string, (const unsigned char*)string))
2094
0
    {
2095
0
        i++;
2096
0
        c = c->next;
2097
0
    }
2098
0
    if(c)
2099
0
    {
2100
        /* free the old string if not const */
2101
0
        if (!(newitem->type & cJSON_StringIsConst) && newitem->string)
2102
0
        {
2103
0
             cJSON_free(newitem->string);
2104
0
        }
2105
2106
0
        newitem->string = (char*)cJSON_strdup((const unsigned char*)string);
2107
0
        ReplaceItemInArray(object, i, newitem);
2108
0
    }
2109
0
}
2110
2111
/* Create basic types: */
2112
cJSON *cJSON_CreateNull(void)
2113
0
{
2114
0
    cJSON *item = cJSON_New_Item();
2115
0
    if(item)
2116
0
    {
2117
0
        item->type = cJSON_NULL;
2118
0
    }
2119
2120
0
    return item;
2121
0
}
2122
2123
cJSON *cJSON_CreateTrue(void)
2124
0
{
2125
0
    cJSON *item = cJSON_New_Item();
2126
0
    if(item)
2127
0
    {
2128
0
        item->type = cJSON_True;
2129
0
    }
2130
2131
0
    return item;
2132
0
}
2133
2134
cJSON *cJSON_CreateFalse(void)
2135
0
{
2136
0
    cJSON *item = cJSON_New_Item();
2137
0
    if(item)
2138
0
    {
2139
0
        item->type = cJSON_False;
2140
0
    }
2141
2142
0
    return item;
2143
0
}
2144
2145
cJSON *cJSON_CreateBool(cjbool b)
2146
0
{
2147
0
    cJSON *item = cJSON_New_Item();
2148
0
    if(item)
2149
0
    {
2150
0
        item->type = b ? cJSON_True : cJSON_False;
2151
0
    }
2152
2153
0
    return item;
2154
0
}
2155
2156
cJSON *cJSON_CreateNumber(double num)
2157
0
{
2158
0
    cJSON *item = cJSON_New_Item();
2159
0
    if(item)
2160
0
    {
2161
0
        item->type = cJSON_Number;
2162
0
        item->valuedouble = num;
2163
2164
        /* use saturation in case of overflow */
2165
0
        if (num >= INT_MAX)
2166
0
        {
2167
0
            item->valueint = INT_MAX;
2168
0
        }
2169
0
        else if (num <= INT_MIN)
2170
0
        {
2171
0
            item->valueint = INT_MIN;
2172
0
        }
2173
0
        else
2174
0
        {
2175
0
            item->valueint = (int)num;
2176
0
        }
2177
0
    }
2178
2179
0
    return item;
2180
0
}
2181
2182
cJSON *cJSON_CreateString(const char *string)
2183
0
{
2184
0
    cJSON *item = cJSON_New_Item();
2185
0
    if(item)
2186
0
    {
2187
0
        item->type = cJSON_String;
2188
0
        item->valuestring = (char*)cJSON_strdup((const unsigned char*)string);
2189
0
        if(!item->valuestring)
2190
0
        {
2191
0
            cJSON_Delete(item);
2192
0
            return NULL;
2193
0
        }
2194
0
    }
2195
2196
0
    return item;
2197
0
}
2198
2199
cJSON *cJSON_CreateStr(const char *string, size_t len)
2200
0
{
2201
0
    cJSON *item = cJSON_New_Item();
2202
0
    if(item)
2203
0
    {
2204
0
        item->type = cJSON_String;
2205
0
        item->valuestring = (char*)cJSON_strndup((const unsigned char*)string, len);
2206
0
        if(!item->valuestring)
2207
0
        {
2208
0
            cJSON_Delete(item);
2209
0
            return NULL;
2210
0
        }
2211
0
    }
2212
2213
0
    return item;
2214
0
}
2215
2216
extern cJSON *cJSON_CreateRaw(const char *raw)
2217
0
{
2218
0
    cJSON *item = cJSON_New_Item();
2219
0
    if(item)
2220
0
    {
2221
0
        item->type = cJSON_Raw;
2222
0
        item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw);
2223
0
        if(!item->valuestring)
2224
0
        {
2225
0
            cJSON_Delete(item);
2226
0
            return NULL;
2227
0
        }
2228
0
    }
2229
2230
0
    return item;
2231
0
}
2232
2233
cJSON *cJSON_CreateArray(void)
2234
0
{
2235
0
    cJSON *item = cJSON_New_Item();
2236
0
    if(item)
2237
0
    {
2238
0
        item->type=cJSON_Array;
2239
0
    }
2240
2241
0
    return item;
2242
0
}
2243
2244
cJSON *cJSON_CreateObject(void)
2245
0
{
2246
0
    cJSON *item = cJSON_New_Item();
2247
0
    if (item)
2248
0
    {
2249
0
        item->type = cJSON_Object;
2250
0
    }
2251
2252
0
    return item;
2253
0
}
2254
2255
/* Create Arrays: */
2256
cJSON *cJSON_CreateIntArray(const int *numbers, int count)
2257
0
{
2258
0
    size_t i = 0;
2259
0
    cJSON *n = NULL;
2260
0
    cJSON *p = NULL;
2261
0
    cJSON *a = NULL;
2262
2263
0
    if (count < 0)
2264
0
    {
2265
0
        return NULL;
2266
0
    }
2267
2268
0
    a = cJSON_CreateArray();
2269
0
    for(i = 0; a && (i < (size_t)count); i++)
2270
0
    {
2271
0
        n = cJSON_CreateNumber(numbers[i]);
2272
0
        if (!n)
2273
0
        {
2274
0
            cJSON_Delete(a);
2275
0
            return NULL;
2276
0
        }
2277
0
        if(!i)
2278
0
        {
2279
0
            a->child = n;
2280
0
        }
2281
0
        else
2282
0
        {
2283
0
            suffix_object(p, n);
2284
0
        }
2285
0
        p = n;
2286
0
    }
2287
2288
0
    return a;
2289
0
}
2290
2291
cJSON *cJSON_CreateFloatArray(const float *numbers, int count)
2292
0
{
2293
0
    size_t i = 0;
2294
0
    cJSON *n = NULL;
2295
0
    cJSON *p = NULL;
2296
0
    cJSON *a = NULL;
2297
2298
0
    if (count < 0)
2299
0
    {
2300
0
        return NULL;
2301
0
    }
2302
2303
0
    a = cJSON_CreateArray();
2304
2305
0
    for(i = 0; a && (i < (size_t)count); i++)
2306
0
    {
2307
0
        n = cJSON_CreateNumber(numbers[i]);
2308
0
        if(!n)
2309
0
        {
2310
0
            cJSON_Delete(a);
2311
0
            return NULL;
2312
0
        }
2313
0
        if(!i)
2314
0
        {
2315
0
            a->child = n;
2316
0
        }
2317
0
        else
2318
0
        {
2319
0
            suffix_object(p, n);
2320
0
        }
2321
0
        p = n;
2322
0
    }
2323
2324
0
    return a;
2325
0
}
2326
2327
cJSON *cJSON_CreateDoubleArray(const double *numbers, int count)
2328
0
{
2329
0
    size_t i = 0;
2330
0
    cJSON *n = NULL;
2331
0
    cJSON *p = NULL;
2332
0
    cJSON *a = NULL;
2333
2334
0
    if (count < 0)
2335
0
    {
2336
0
        return NULL;
2337
0
    }
2338
2339
0
    a = cJSON_CreateArray();
2340
2341
0
    for(i = 0;a && (i < (size_t)count); i++)
2342
0
    {
2343
0
        n = cJSON_CreateNumber(numbers[i]);
2344
0
        if(!n)
2345
0
        {
2346
0
            cJSON_Delete(a);
2347
0
            return NULL;
2348
0
        }
2349
0
        if(!i)
2350
0
        {
2351
0
            a->child = n;
2352
0
        }
2353
0
        else
2354
0
        {
2355
0
            suffix_object(p, n);
2356
0
        }
2357
0
        p = n;
2358
0
    }
2359
2360
0
    return a;
2361
0
}
2362
2363
cJSON *cJSON_CreateStringArray(const char **strings, int count)
2364
0
{
2365
0
    size_t i = 0;
2366
0
    cJSON *n = NULL;
2367
0
    cJSON *p = NULL;
2368
0
    cJSON *a = NULL;
2369
2370
0
    if (count < 0)
2371
0
    {
2372
0
        return NULL;
2373
0
    }
2374
2375
0
    a = cJSON_CreateArray();
2376
2377
0
    for (i = 0; a && (i < (size_t)count); i++)
2378
0
    {
2379
0
        n = cJSON_CreateString(strings[i]);
2380
0
        if(!n)
2381
0
        {
2382
0
            cJSON_Delete(a);
2383
0
            return NULL;
2384
0
        }
2385
0
        if(!i)
2386
0
        {
2387
0
            a->child = n;
2388
0
        }
2389
0
        else
2390
0
        {
2391
0
            suffix_object(p,n);
2392
0
        }
2393
0
        p = n;
2394
0
    }
2395
2396
0
    return a;
2397
0
}
2398
2399
/* Duplication */
2400
cJSON *cJSON_Duplicate(const cJSON *item, cjbool recurse)
2401
0
{
2402
0
    cJSON *newitem = NULL;
2403
0
    cJSON *child = NULL;
2404
0
    cJSON *next = NULL;
2405
0
    cJSON *newchild = NULL;
2406
2407
    /* Bail on bad ptr */
2408
0
    if (!item)
2409
0
    {
2410
0
        goto fail;
2411
0
    }
2412
    /* Create new item */
2413
0
    newitem = cJSON_New_Item();
2414
0
    if (!newitem)
2415
0
    {
2416
0
        goto fail;
2417
0
    }
2418
    /* Copy over all vars */
2419
0
    newitem->type = item->type & (~cJSON_IsReference);
2420
0
    newitem->valueint = item->valueint;
2421
0
    newitem->valuedouble = item->valuedouble;
2422
0
    if (item->valuestring)
2423
0
    {
2424
0
        newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring);
2425
0
        if (!newitem->valuestring)
2426
0
        {
2427
0
            goto fail;
2428
0
        }
2429
0
    }
2430
0
    if (item->string)
2431
0
    {
2432
0
        newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string);
2433
0
        if (!newitem->string)
2434
0
        {
2435
0
            goto fail;
2436
0
        }
2437
0
    }
2438
    /* If non-recursive, then we're done! */
2439
0
    if (!recurse)
2440
0
    {
2441
0
        return newitem;
2442
0
    }
2443
    /* Walk the ->next chain for the child. */
2444
0
    child = item->child;
2445
0
    while (child != NULL)
2446
0
    {
2447
0
        newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
2448
0
        if (!newchild)
2449
0
        {
2450
0
            goto fail;
2451
0
        }
2452
0
        if (next != NULL)
2453
0
        {
2454
            /* If newitem->child already set, then crosswire ->prev and ->next and move on */
2455
0
            next->next = newchild;
2456
0
            newchild->prev = next;
2457
0
            next = newchild;
2458
0
        }
2459
0
        else
2460
0
        {
2461
            /* Set newitem->child and move to it */
2462
0
            newitem->child = newchild;
2463
0
            next = newchild;
2464
0
        }
2465
0
        child = child->next;
2466
0
    }
2467
2468
0
    return newitem;
2469
2470
0
fail:
2471
0
    if (newitem != NULL)
2472
0
    {
2473
0
        cJSON_Delete(newitem);
2474
0
    }
2475
2476
0
    return NULL;
2477
0
}
2478
2479
void cJSON_Minify(char *json)
2480
0
{
2481
0
    unsigned char *into = (unsigned char*)json;
2482
0
    while (*json)
2483
0
    {
2484
0
        if (*json == ' ')
2485
0
        {
2486
0
            json++;
2487
0
        }
2488
0
        else if (*json == '\t')
2489
0
        {
2490
            /* Whitespace characters. */
2491
0
            json++;
2492
0
        }
2493
0
        else if (*json == '\r')
2494
0
        {
2495
0
            json++;
2496
0
        }
2497
0
        else if (*json=='\n')
2498
0
        {
2499
0
            json++;
2500
0
        }
2501
0
        else if ((*json == '/') && (json[1] == '/'))
2502
0
        {
2503
            /* double-slash comments, to end of line. */
2504
0
            while (*json && (*json != '\n'))
2505
0
            {
2506
0
                json++;
2507
0
            }
2508
0
        }
2509
0
        else if ((*json == '/') && (json[1] == '*'))
2510
0
        {
2511
            /* multiline comments. */
2512
0
            while (*json && !((*json == '*') && (json[1] == '/')))
2513
0
            {
2514
0
                json++;
2515
0
            }
2516
0
            json += 2;
2517
0
        }
2518
0
        else if (*json == '\"')
2519
0
        {
2520
            /* string literals, which are \" sensitive. */
2521
0
            *into++ = (unsigned char)*json++;
2522
0
            while (*json && (*json != '\"'))
2523
0
            {
2524
0
                if (*json == '\\')
2525
0
                {
2526
0
                    *into++ = (unsigned char)*json++;
2527
0
                }
2528
0
                *into++ = (unsigned char)*json++;
2529
0
            }
2530
0
            *into++ = (unsigned char)*json++;
2531
0
        }
2532
0
        else
2533
0
        {
2534
            /* All other characters. */
2535
0
            *into++ = (unsigned char)*json++;
2536
0
        }
2537
0
    }
2538
2539
    /* and null-terminate. */
2540
0
    *into = '\0';
2541
0
}
2542
2543
cjbool cJSON_IsObject(const cJSON * const item)
2544
0
{
2545
0
    if (item == NULL)
2546
0
    {
2547
0
        return false;
2548
0
    }
2549
2550
0
    return (item->type & 0xFF) == cJSON_Object;
2551
0
}
2552
2553
cjbool cJSON_IsNull(const cJSON * const item)
2554
0
{
2555
0
    if (item == NULL)
2556
0
    {
2557
0
        return false;
2558
0
    }
2559
2560
0
    return (item->type & 0xFF) == cJSON_NULL;
2561
0
}
2562
2563
2564
static cJSON *merge_patch(cJSON *target, const cJSON * const patch)
2565
0
{
2566
0
    cJSON *patch_child = NULL;
2567
2568
0
    if (!cJSON_IsObject(patch))
2569
0
    {
2570
        /* scalar value, array or NULL, just duplicate */
2571
0
        cJSON_Delete(target);
2572
0
        return cJSON_Duplicate(patch, 1);
2573
0
    }
2574
2575
0
    if (!cJSON_IsObject(target))
2576
0
    {
2577
0
        cJSON_Delete(target);
2578
0
        target = cJSON_CreateObject();
2579
0
    }
2580
2581
0
    patch_child = patch->child;
2582
0
    while (patch_child != NULL)
2583
0
    {
2584
0
        if (cJSON_IsNull(patch_child))
2585
0
        {
2586
0
            cJSON_DeleteItemFromObject(target, patch_child->string);
2587
0
        }
2588
0
        else
2589
0
        {
2590
0
            cJSON *replace_me = NULL;
2591
0
            cJSON *replacement = NULL;
2592
2593
0
            replace_me = cJSON_DetachItemFromObject(target, patch_child->string);
2594
2595
0
            replacement = merge_patch(replace_me, patch_child);
2596
0
            if (replacement == NULL)
2597
0
            {
2598
0
                return NULL;
2599
0
            }
2600
2601
0
            cJSON_AddItemToObject(target, patch_child->string, replacement);
2602
0
        }
2603
0
        patch_child = patch_child->next;
2604
0
    }
2605
0
    return target;
2606
0
}
2607
2608
cJSON * cJSONUtils_MergePatch(cJSON *target, const cJSON * const patch)
2609
0
{
2610
0
    return merge_patch(target, patch);
2611
0
}