Coverage Report

Created: 2025-07-09 06:29

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