1 /*
2   Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
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 /* disable warnings about old C89 functions in MSVC */
27 #if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
28 #define _CRT_SECURE_NO_DEPRECATE
29 #endif
30 
31 #ifdef __GNUC__
32 #pragma GCC visibility push(default)
33 #endif
34 #if defined(_MSC_VER)
35 #pragma warning (push)
36 /* disable warning about single line comments in system headers */
37 #pragma warning (disable : 4001)
38 #endif
39 
40 #include <string.h>
41 #include <stdio.h>
42 #include <math.h>
43 #include <stdlib.h>
44 #include <float.h>
45 #include <limits.h>
46 #include <ctype.h>
47 
48 #ifdef ENABLE_LOCALES
49 #include <locale.h>
50 #endif
51 
52 #if defined(_MSC_VER)
53 #pragma warning (pop)
54 #endif
55 #ifdef __GNUC__
56 #pragma GCC visibility pop
57 #endif
58 
59 #include "cJSON.h"
60 
61 /* define our own boolean type */
62 #define true ((cJSON_bool)1)
63 #define false ((cJSON_bool)0)
64 
65 typedef struct {
66     const unsigned char *json;
67     size_t position;
68 } error;
69 static error global_error = { NULL, 0 };
70 
cJSON_GetErrorPtr(void)71 CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
72 {
73     return (const char*) (global_error.json + global_error.position);
74 }
75 
cJSON_GetStringValue(cJSON * item)76 CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item) {
77     if (!cJSON_IsString(item)) {
78         return NULL;
79     }
80 
81     return item->valuestring;
82 }
83 
84 /* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
85 #if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 5)
86     #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
87 #endif
88 
cJSON_Version(void)89 CJSON_PUBLIC(const char*) cJSON_Version(void)
90 {
91     static char version[15];
92     sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
93 
94     return version;
95 }
96 
97 /* Case insensitive string comparison, doesn't consider two NULL pointers equal though */
case_insensitive_strcmp(const unsigned char * string1,const unsigned char * string2)98 static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)
99 {
100     if ((string1 == NULL) || (string2 == NULL))
101     {
102         return 1;
103     }
104 
105     if (string1 == string2)
106     {
107         return 0;
108     }
109 
110     for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)
111     {
112         if (*string1 == '\0')
113         {
114             return 0;
115         }
116     }
117 
118     return tolower(*string1) - tolower(*string2);
119 }
120 
121 typedef struct internal_hooks
122 {
123     void *(*allocate)(size_t size);
124     void (*deallocate)(void *pointer);
125     void *(*reallocate)(void *pointer, size_t size);
126 } internal_hooks;
127 
128 #if defined(_MSC_VER)
129 /* work around MSVC error C2322: '...' address of dillimport '...' is not static */
internal_malloc(size_t size)130 static void *internal_malloc(size_t size)
131 {
132     return malloc(size);
133 }
internal_free(void * pointer)134 static void internal_free(void *pointer)
135 {
136     free(pointer);
137 }
internal_realloc(void * pointer,size_t size)138 static void *internal_realloc(void *pointer, size_t size)
139 {
140     return realloc(pointer, size);
141 }
142 #else
143 #define internal_malloc malloc
144 #define internal_free free
145 #define internal_realloc realloc
146 #endif
147 
148 static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
149 
cJSON_strdup(const unsigned char * string,const internal_hooks * const hooks)150 static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
151 {
152     size_t length = 0;
153     unsigned char *copy = NULL;
154 
155     if (string == NULL)
156     {
157         return NULL;
158     }
159 
160     length = strlen((const char*)string) + sizeof("");
161     copy = (unsigned char*)hooks->allocate(length);
162     if (copy == NULL)
163     {
164         return NULL;
165     }
166     memcpy(copy, string, length);
167 
168     return copy;
169 }
170 
cJSON_InitHooks(cJSON_Hooks * hooks)171 CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
172 {
173     if (hooks == NULL)
174     {
175         /* Reset hooks */
176         global_hooks.allocate = malloc;
177         global_hooks.deallocate = free;
178         global_hooks.reallocate = realloc;
179         return;
180     }
181 
182     global_hooks.allocate = malloc;
183     if (hooks->malloc_fn != NULL)
184     {
185         global_hooks.allocate = hooks->malloc_fn;
186     }
187 
188     global_hooks.deallocate = free;
189     if (hooks->free_fn != NULL)
190     {
191         global_hooks.deallocate = hooks->free_fn;
192     }
193 
194     /* use realloc only if both free and malloc are used */
195     global_hooks.reallocate = NULL;
196     if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
197     {
198         global_hooks.reallocate = realloc;
199     }
200 }
201 
202 /* Internal constructor. */
cJSON_New_Item(const internal_hooks * const hooks)203 static cJSON *cJSON_New_Item(const internal_hooks * const hooks)
204 {
205     cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON));
206     if (node)
207     {
208         memset(node, '\0', sizeof(cJSON));
209     }
210 
211     return node;
212 }
213 
214 /* Delete a cJSON structure. */
cJSON_Delete(cJSON * item)215 CJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
216 {
217     cJSON *next = NULL;
218     while (item != NULL)
219     {
220         next = item->next;
221         if (!(item->type & cJSON_IsReference) && (item->child != NULL))
222         {
223             cJSON_Delete(item->child);
224         }
225         if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
226         {
227             global_hooks.deallocate(item->valuestring);
228         }
229         if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
230         {
231             global_hooks.deallocate(item->string);
232         }
233         global_hooks.deallocate(item);
234         item = next;
235     }
236 }
237 
238 /* get the decimal point character of the current locale */
get_decimal_point(void)239 static unsigned char get_decimal_point(void)
240 {
241 #ifdef ENABLE_LOCALES
242     struct lconv *lconv = localeconv();
243     return (unsigned char) lconv->decimal_point[0];
244 #else
245     return '.';
246 #endif
247 }
248 
249 typedef struct
250 {
251     const unsigned char *content;
252     size_t length;
253     size_t offset;
254     size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */
255     internal_hooks hooks;
256 } parse_buffer;
257 
258 /* check if the given size is left to read in a given parse buffer (starting with 1) */
259 #define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))
260 /* check if the buffer can be accessed at the given index (starting with 0) */
261 #define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))
262 #define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))
263 /* get a pointer to the buffer at the position */
264 #define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
265 
266 /* Parse the input text to generate a number, and populate the result into item. */
parse_number(cJSON * const item,parse_buffer * const input_buffer)267 static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)
268 {
269     double number = 0;
270     unsigned char *after_end = NULL;
271     unsigned char number_c_string[64];
272     unsigned char decimal_point = get_decimal_point();
273     size_t i = 0;
274 
275     if ((input_buffer == NULL) || (input_buffer->content == NULL))
276     {
277         return false;
278     }
279 
280     /* copy the number into a temporary buffer and replace '.' with the decimal point
281      * of the current locale (for strtod)
282      * This also takes care of '\0' not necessarily being available for marking the end of the input */
283     for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
284     {
285         switch (buffer_at_offset(input_buffer)[i])
286         {
287             case '0':
288             case '1':
289             case '2':
290             case '3':
291             case '4':
292             case '5':
293             case '6':
294             case '7':
295             case '8':
296             case '9':
297             case '+':
298             case '-':
299             case 'e':
300             case 'E':
301                 number_c_string[i] = buffer_at_offset(input_buffer)[i];
302                 break;
303 
304             case '.':
305                 number_c_string[i] = decimal_point;
306                 break;
307 
308             default:
309                 goto loop_end;
310         }
311     }
312 loop_end:
313     number_c_string[i] = '\0';
314 
315     number = strtod((const char*)number_c_string, (char**)&after_end);
316     if (number_c_string == after_end)
317     {
318         return false; /* parse_error */
319     }
320 
321     item->valuedouble = number;
322 
323     /* use saturation in case of overflow */
324     if (number >= INT_MAX)
325     {
326         item->valueint = INT_MAX;
327     }
328     else if (number <= INT_MIN)
329     {
330         item->valueint = INT_MIN;
331     }
332     else
333     {
334         item->valueint = (int)number;
335     }
336 
337     item->type = cJSON_Number;
338 
339     input_buffer->offset += (size_t)(after_end - number_c_string);
340     return true;
341 }
342 
343 /* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
cJSON_SetNumberHelper(cJSON * object,double number)344 CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
345 {
346     if (number >= INT_MAX)
347     {
348         object->valueint = INT_MAX;
349     }
350     else if (number <= INT_MIN)
351     {
352         object->valueint = INT_MIN;
353     }
354     else
355     {
356         object->valueint = (int)number;
357     }
358 
359     return object->valuedouble = number;
360 }
361 
362 typedef struct
363 {
364     unsigned char *buffer;
365     size_t length;
366     size_t offset;
367     size_t depth; /* current nesting depth (for formatted printing) */
368     cJSON_bool noalloc;
369     cJSON_bool format; /* is this print a formatted print */
370     internal_hooks hooks;
371 } printbuffer;
372 
373 /* realloc printbuffer if necessary to have at least "needed" bytes more */
ensure(printbuffer * const p,size_t needed)374 static unsigned char* ensure(printbuffer * const p, size_t needed)
375 {
376     unsigned char *newbuffer = NULL;
377     size_t newsize = 0;
378 
379     if ((p == NULL) || (p->buffer == NULL))
380     {
381         return NULL;
382     }
383 
384     if ((p->length > 0) && (p->offset >= p->length))
385     {
386         /* make sure that offset is valid */
387         return NULL;
388     }
389 
390     if (needed > INT_MAX)
391     {
392         /* sizes bigger than INT_MAX are currently not supported */
393         return NULL;
394     }
395 
396     needed += p->offset + 1;
397     if (needed <= p->length)
398     {
399         return p->buffer + p->offset;
400     }
401 
402     if (p->noalloc) {
403         return NULL;
404     }
405 
406     /* calculate new buffer size */
407     if (needed > (INT_MAX / 2))
408     {
409         /* overflow of int, use INT_MAX if possible */
410         if (needed <= INT_MAX)
411         {
412             newsize = INT_MAX;
413         }
414         else
415         {
416             return NULL;
417         }
418     }
419     else
420     {
421         newsize = needed * 2;
422     }
423 
424     if (p->hooks.reallocate != NULL)
425     {
426         /* reallocate with realloc if available */
427         newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);
428         if (newbuffer == NULL)
429         {
430             p->hooks.deallocate(p->buffer);
431             p->length = 0;
432             p->buffer = NULL;
433 
434             return NULL;
435         }
436     }
437     else
438     {
439         /* otherwise reallocate manually */
440         newbuffer = (unsigned char*)p->hooks.allocate(newsize);
441         if (!newbuffer)
442         {
443             p->hooks.deallocate(p->buffer);
444             p->length = 0;
445             p->buffer = NULL;
446 
447             return NULL;
448         } else {
449             memcpy(newbuffer, p->buffer, p->offset + 1);
450         }
451         p->hooks.deallocate(p->buffer);
452     }
453     p->length = newsize;
454     p->buffer = newbuffer;
455 
456     return newbuffer + p->offset;
457 }
458 
459 /* calculate the new length of the string in a printbuffer and update the offset */
update_offset(printbuffer * const buffer)460 static void update_offset(printbuffer * const buffer)
461 {
462     const unsigned char *buffer_pointer = NULL;
463     if ((buffer == NULL) || (buffer->buffer == NULL))
464     {
465         return;
466     }
467     buffer_pointer = buffer->buffer + buffer->offset;
468 
469     buffer->offset += strlen((const char*)buffer_pointer);
470 }
471 
472 /* Render the number nicely from the given item into a string. */
print_number(const cJSON * const item,printbuffer * const output_buffer)473 static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
474 {
475     unsigned char *output_pointer = NULL;
476     double d = item->valuedouble;
477     int length = 0;
478     size_t i = 0;
479     unsigned char number_buffer[26]; /* temporary buffer to print the number into */
480     unsigned char decimal_point = get_decimal_point();
481     double test;
482 
483     if (output_buffer == NULL)
484     {
485         return false;
486     }
487 
488     /* This checks for NaN and Infinity */
489     if ((d * 0) != 0)
490     {
491         length = sprintf((char*)number_buffer, "null");
492     }
493     else
494     {
495         /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
496         length = sprintf((char*)number_buffer, "%1.15g", d);
497 
498         /* Check whether the original double can be recovered */
499         if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != d))
500         {
501             /* If not, print with 17 decimal places of precision */
502             length = sprintf((char*)number_buffer, "%1.17g", d);
503         }
504     }
505 
506     /* sprintf failed or buffer overrun occurred */
507     if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
508     {
509         return false;
510     }
511 
512     /* reserve appropriate space in the output */
513     output_pointer = ensure(output_buffer, (size_t)length + sizeof(""));
514     if (output_pointer == NULL)
515     {
516         return false;
517     }
518 
519     /* copy the printed number to the output and replace locale
520      * dependent decimal point with '.' */
521     for (i = 0; i < ((size_t)length); i++)
522     {
523         if (number_buffer[i] == decimal_point)
524         {
525             output_pointer[i] = '.';
526             continue;
527         }
528 
529         output_pointer[i] = number_buffer[i];
530     }
531     output_pointer[i] = '\0';
532 
533     output_buffer->offset += (size_t)length;
534 
535     return true;
536 }
537 
538 /* parse 4 digit hexadecimal number */
parse_hex4(const unsigned char * const input)539 static unsigned parse_hex4(const unsigned char * const input)
540 {
541     unsigned int h = 0;
542     size_t i = 0;
543 
544     for (i = 0; i < 4; i++)
545     {
546         /* parse digit */
547         if ((input[i] >= '0') && (input[i] <= '9'))
548         {
549             h += (unsigned int) input[i] - '0';
550         }
551         else if ((input[i] >= 'A') && (input[i] <= 'F'))
552         {
553             h += (unsigned int) 10 + input[i] - 'A';
554         }
555         else if ((input[i] >= 'a') && (input[i] <= 'f'))
556         {
557             h += (unsigned int) 10 + input[i] - 'a';
558         }
559         else /* invalid */
560         {
561             return 0;
562         }
563 
564         if (i < 3)
565         {
566             /* shift left to make place for the next nibble */
567             h = h << 4;
568         }
569     }
570 
571     return h;
572 }
573 
574 /* converts a UTF-16 literal to UTF-8
575  * A literal can be one or two sequences of the form \uXXXX */
utf16_literal_to_utf8(const unsigned char * const input_pointer,const unsigned char * const input_end,unsigned char ** output_pointer)576 static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer)
577 {
578     long unsigned int codepoint = 0;
579     unsigned int first_code = 0;
580     const unsigned char *first_sequence = input_pointer;
581     unsigned char utf8_length = 0;
582     unsigned char utf8_position = 0;
583     unsigned char sequence_length = 0;
584     unsigned char first_byte_mark = 0;
585 
586     if ((input_end - first_sequence) < 6)
587     {
588         /* input ends unexpectedly */
589         goto fail;
590     }
591 
592     /* get the first utf16 sequence */
593     first_code = parse_hex4(first_sequence + 2);
594 
595     /* check that the code is valid */
596     if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
597     {
598         goto fail;
599     }
600 
601     /* UTF16 surrogate pair */
602     if ((first_code >= 0xD800) && (first_code <= 0xDBFF))
603     {
604         const unsigned char *second_sequence = first_sequence + 6;
605         unsigned int second_code = 0;
606         sequence_length = 12; /* \uXXXX\uXXXX */
607 
608         if ((input_end - second_sequence) < 6)
609         {
610             /* input ends unexpectedly */
611             goto fail;
612         }
613 
614         if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u'))
615         {
616             /* missing second half of the surrogate pair */
617             goto fail;
618         }
619 
620         /* get the second utf16 sequence */
621         second_code = parse_hex4(second_sequence + 2);
622         /* check that the code is valid */
623         if ((second_code < 0xDC00) || (second_code > 0xDFFF))
624         {
625             /* invalid second half of the surrogate pair */
626             goto fail;
627         }
628 
629 
630         /* calculate the unicode codepoint from the surrogate pair */
631         codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF));
632     }
633     else
634     {
635         sequence_length = 6; /* \uXXXX */
636         codepoint = first_code;
637     }
638 
639     /* encode as UTF-8
640      * takes at maximum 4 bytes to encode:
641      * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
642     if (codepoint < 0x80)
643     {
644         /* normal ascii, encoding 0xxxxxxx */
645         utf8_length = 1;
646     }
647     else if (codepoint < 0x800)
648     {
649         /* two bytes, encoding 110xxxxx 10xxxxxx */
650         utf8_length = 2;
651         first_byte_mark = 0xC0; /* 11000000 */
652     }
653     else if (codepoint < 0x10000)
654     {
655         /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */
656         utf8_length = 3;
657         first_byte_mark = 0xE0; /* 11100000 */
658     }
659     else if (codepoint <= 0x10FFFF)
660     {
661         /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */
662         utf8_length = 4;
663         first_byte_mark = 0xF0; /* 11110000 */
664     }
665     else
666     {
667         /* invalid unicode codepoint */
668         goto fail;
669     }
670 
671     /* encode as utf8 */
672     for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--)
673     {
674         /* 10xxxxxx */
675         (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF);
676         codepoint >>= 6;
677     }
678     /* encode first byte */
679     if (utf8_length > 1)
680     {
681         (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF);
682     }
683     else
684     {
685         (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F);
686     }
687 
688     *output_pointer += utf8_length;
689 
690     return sequence_length;
691 
692 fail:
693     return 0;
694 }
695 
696 /* Parse the input text into an unescaped cinput, and populate item. */
parse_string(cJSON * const item,parse_buffer * const input_buffer)697 static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer)
698 {
699     const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;
700     const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;
701     unsigned char *output_pointer = NULL;
702     unsigned char *output = NULL;
703 
704     /* not a string */
705     if (buffer_at_offset(input_buffer)[0] != '\"')
706     {
707         goto fail;
708     }
709 
710     {
711         /* calculate approximate size of the output (overestimate) */
712         size_t allocation_length = 0;
713         size_t skipped_bytes = 0;
714         while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"'))
715         {
716             /* is escape sequence */
717             if (input_end[0] == '\\')
718             {
719                 if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length)
720                 {
721                     /* prevent buffer overflow when last input character is a backslash */
722                     goto fail;
723                 }
724                 skipped_bytes++;
725                 input_end++;
726             }
727             input_end++;
728         }
729         if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"'))
730         {
731             goto fail; /* string ended unexpectedly */
732         }
733 
734         /* This is at most how much we need for the output */
735         allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes;
736         output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof(""));
737         if (output == NULL)
738         {
739             goto fail; /* allocation failure */
740         }
741     }
742 
743     output_pointer = output;
744     /* loop through the string literal */
745     while (input_pointer < input_end)
746     {
747         if (*input_pointer != '\\')
748         {
749             *output_pointer++ = *input_pointer++;
750         }
751         /* escape sequence */
752         else
753         {
754             unsigned char sequence_length = 2;
755             if ((input_end - input_pointer) < 1)
756             {
757                 goto fail;
758             }
759 
760             switch (input_pointer[1])
761             {
762                 case 'b':
763                     *output_pointer++ = '\b';
764                     break;
765                 case 'f':
766                     *output_pointer++ = '\f';
767                     break;
768                 case 'n':
769                     *output_pointer++ = '\n';
770                     break;
771                 case 'r':
772                     *output_pointer++ = '\r';
773                     break;
774                 case 't':
775                     *output_pointer++ = '\t';
776                     break;
777                 case '\"':
778                 case '\\':
779                 case '/':
780                     *output_pointer++ = input_pointer[1];
781                     break;
782 
783                 /* UTF-16 literal */
784                 case 'u':
785                     sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer);
786                     if (sequence_length == 0)
787                     {
788                         /* failed to convert UTF16-literal to UTF-8 */
789                         goto fail;
790                     }
791                     break;
792 
793                 default:
794                     goto fail;
795             }
796             input_pointer += sequence_length;
797         }
798     }
799 
800     /* zero terminate the output */
801     *output_pointer = '\0';
802 
803     item->type = cJSON_String;
804     item->valuestring = (char*)output;
805 
806     input_buffer->offset = (size_t) (input_end - input_buffer->content);
807     input_buffer->offset++;
808 
809     return true;
810 
811 fail:
812     if (output != NULL)
813     {
814         input_buffer->hooks.deallocate(output);
815     }
816 
817     if (input_pointer != NULL)
818     {
819         input_buffer->offset = (size_t)(input_pointer - input_buffer->content);
820     }
821 
822     return false;
823 }
824 
825 /* Render the cstring provided to an escaped version that can be printed. */
print_string_ptr(const unsigned char * const input,printbuffer * const output_buffer)826 static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer)
827 {
828     const unsigned char *input_pointer = NULL;
829     unsigned char *output = NULL;
830     unsigned char *output_pointer = NULL;
831     size_t output_length = 0;
832     /* numbers of additional characters needed for escaping */
833     size_t escape_characters = 0;
834 
835     if (output_buffer == NULL)
836     {
837         return false;
838     }
839 
840     /* empty string */
841     if (input == NULL)
842     {
843         output = ensure(output_buffer, sizeof("\"\""));
844         if (output == NULL)
845         {
846             return false;
847         }
848         strcpy((char*)output, "\"\"");
849 
850         return true;
851     }
852 
853     /* set "flag" to 1 if something needs to be escaped */
854     for (input_pointer = input; *input_pointer; input_pointer++)
855     {
856         switch (*input_pointer)
857         {
858             case '\"':
859             case '\\':
860             case '\b':
861             case '\f':
862             case '\n':
863             case '\r':
864             case '\t':
865                 /* one character escape sequence */
866                 escape_characters++;
867                 break;
868             default:
869                 if (*input_pointer < 32)
870                 {
871                     /* UTF-16 escape sequence uXXXX */
872                     escape_characters += 5;
873                 }
874                 break;
875         }
876     }
877     output_length = (size_t)(input_pointer - input) + escape_characters;
878 
879     output = ensure(output_buffer, output_length + sizeof("\"\""));
880     if (output == NULL)
881     {
882         return false;
883     }
884 
885     /* no characters have to be escaped */
886     if (escape_characters == 0)
887     {
888         output[0] = '\"';
889         memcpy(output + 1, input, output_length);
890         output[output_length + 1] = '\"';
891         output[output_length + 2] = '\0';
892 
893         return true;
894     }
895 
896     output[0] = '\"';
897     output_pointer = output + 1;
898     /* copy the string */
899     for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++)
900     {
901         if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\'))
902         {
903             /* normal character, copy */
904             *output_pointer = *input_pointer;
905         }
906         else
907         {
908             /* character needs to be escaped */
909             *output_pointer++ = '\\';
910             switch (*input_pointer)
911             {
912                 case '\\':
913                     *output_pointer = '\\';
914                     break;
915                 case '\"':
916                     *output_pointer = '\"';
917                     break;
918                 case '\b':
919                     *output_pointer = 'b';
920                     break;
921                 case '\f':
922                     *output_pointer = 'f';
923                     break;
924                 case '\n':
925                     *output_pointer = 'n';
926                     break;
927                 case '\r':
928                     *output_pointer = 'r';
929                     break;
930                 case '\t':
931                     *output_pointer = 't';
932                     break;
933                 default:
934                     /* escape and print as unicode codepoint */
935                     sprintf((char*)output_pointer, "u%04x", *input_pointer);
936                     output_pointer += 4;
937                     break;
938             }
939         }
940     }
941     output[output_length + 1] = '\"';
942     output[output_length + 2] = '\0';
943 
944     return true;
945 }
946 
947 /* Invoke print_string_ptr (which is useful) on an item. */
print_string(const cJSON * const item,printbuffer * const p)948 static cJSON_bool print_string(const cJSON * const item, printbuffer * const p)
949 {
950     return print_string_ptr((unsigned char*)item->valuestring, p);
951 }
952 
953 /* Predeclare these prototypes. */
954 static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer);
955 static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer);
956 static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer);
957 static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer);
958 static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer);
959 static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer);
960 
961 /* Utility to jump whitespace and cr/lf */
buffer_skip_whitespace(parse_buffer * const buffer)962 static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
963 {
964     if ((buffer == NULL) || (buffer->content == NULL))
965     {
966         return NULL;
967     }
968 
969     while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
970     {
971        buffer->offset++;
972     }
973 
974     if (buffer->offset == buffer->length)
975     {
976         buffer->offset--;
977     }
978 
979     return buffer;
980 }
981 
982 /* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */
skip_utf8_bom(parse_buffer * const buffer)983 static parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
984 {
985     if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0))
986     {
987         return NULL;
988     }
989 
990     if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0))
991     {
992         buffer->offset += 3;
993     }
994 
995     return buffer;
996 }
997 
998 /* Parse an object - create a new root, and populate. */
cJSON_ParseWithOpts(const char * value,const char ** return_parse_end,cJSON_bool require_null_terminated)999 CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)
1000 {
1001     parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
1002     cJSON *item = NULL;
1003 
1004     /* reset error position */
1005     global_error.json = NULL;
1006     global_error.position = 0;
1007 
1008     if (value == NULL)
1009     {
1010         goto fail;
1011     }
1012 
1013     buffer.content = (const unsigned char*)value;
1014     buffer.length = strlen((const char*)value) + sizeof("");
1015     buffer.offset = 0;
1016     buffer.hooks = global_hooks;
1017 
1018     item = cJSON_New_Item(&global_hooks);
1019     if (item == NULL) /* memory fail */
1020     {
1021         goto fail;
1022     }
1023 
1024     if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer))))
1025     {
1026         /* parse failure. ep is set. */
1027         goto fail;
1028     }
1029 
1030     /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
1031     if (require_null_terminated)
1032     {
1033         buffer_skip_whitespace(&buffer);
1034         if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0')
1035         {
1036             goto fail;
1037         }
1038     }
1039     if (return_parse_end)
1040     {
1041         *return_parse_end = (const char*)buffer_at_offset(&buffer);
1042     }
1043 
1044     return item;
1045 
1046 fail:
1047     if (item != NULL)
1048     {
1049         cJSON_Delete(item);
1050     }
1051 
1052     if (value != NULL)
1053     {
1054         error local_error;
1055         local_error.json = (const unsigned char*)value;
1056         local_error.position = 0;
1057 
1058         if (buffer.offset < buffer.length)
1059         {
1060             local_error.position = buffer.offset;
1061         }
1062         else if (buffer.length > 0)
1063         {
1064             local_error.position = buffer.length - 1;
1065         }
1066 
1067         if (return_parse_end != NULL)
1068         {
1069             *return_parse_end = (const char*)local_error.json + local_error.position;
1070         }
1071 
1072         global_error = local_error;
1073     }
1074 
1075     return NULL;
1076 }
1077 
1078 /* Default options for cJSON_Parse */
cJSON_Parse(const char * value)1079 CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value)
1080 {
1081     return cJSON_ParseWithOpts(value, 0, 0);
1082 }
1083 
1084 #define cjson_min(a, b) ((a < b) ? a : b)
1085 
print(const cJSON * const item,cJSON_bool format,const internal_hooks * const hooks)1086 static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks)
1087 {
1088     static const size_t default_buffer_size = 256;
1089     printbuffer buffer[1];
1090     unsigned char *printed = NULL;
1091 
1092     memset(buffer, 0, sizeof(buffer));
1093 
1094     /* create buffer */
1095     buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size);
1096     buffer->length = default_buffer_size;
1097     buffer->format = format;
1098     buffer->hooks = *hooks;
1099     if (buffer->buffer == NULL)
1100     {
1101         goto fail;
1102     }
1103 
1104     /* print the value */
1105     if (!print_value(item, buffer))
1106     {
1107         goto fail;
1108     }
1109     update_offset(buffer);
1110 
1111     /* check if reallocate is available */
1112     if (hooks->reallocate != NULL)
1113     {
1114         printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
1115         buffer->buffer = NULL;
1116         if (printed == NULL) {
1117             goto fail;
1118         }
1119     }
1120     else /* otherwise copy the JSON over to a new buffer */
1121     {
1122         printed = (unsigned char*) hooks->allocate(buffer->offset + 1);
1123         if (printed == NULL)
1124         {
1125             goto fail;
1126         }
1127         memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
1128         printed[buffer->offset] = '\0'; /* just to be sure */
1129 
1130         /* free the buffer */
1131         hooks->deallocate(buffer->buffer);
1132     }
1133 
1134     return printed;
1135 
1136 fail:
1137     if (buffer->buffer != NULL)
1138     {
1139         hooks->deallocate(buffer->buffer);
1140     }
1141 
1142     if (printed != NULL)
1143     {
1144         hooks->deallocate(printed);
1145     }
1146 
1147     return NULL;
1148 }
1149 
1150 /* Render a cJSON item/entity/structure to text. */
cJSON_Print(const cJSON * item)1151 CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item)
1152 {
1153     return (char*)print(item, true, &global_hooks);
1154 }
1155 
cJSON_PrintUnformatted(const cJSON * item)1156 CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item)
1157 {
1158     return (char*)print(item, false, &global_hooks);
1159 }
1160 
cJSON_PrintBuffered(const cJSON * item,int prebuffer,cJSON_bool fmt)1161 CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)
1162 {
1163     printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
1164 
1165     if (prebuffer < 0)
1166     {
1167         return NULL;
1168     }
1169 
1170     p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer);
1171     if (!p.buffer)
1172     {
1173         return NULL;
1174     }
1175 
1176     p.length = (size_t)prebuffer;
1177     p.offset = 0;
1178     p.noalloc = false;
1179     p.format = fmt;
1180     p.hooks = global_hooks;
1181 
1182     if (!print_value(item, &p))
1183     {
1184         global_hooks.deallocate(p.buffer);
1185         return NULL;
1186     }
1187 
1188     return (char*)p.buffer;
1189 }
1190 
cJSON_PrintPreallocated(cJSON * item,char * buf,const int len,const cJSON_bool fmt)1191 CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cJSON_bool fmt)
1192 {
1193     printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
1194 
1195     if ((len < 0) || (buf == NULL))
1196     {
1197         return false;
1198     }
1199 
1200     p.buffer = (unsigned char*)buf;
1201     p.length = (size_t)len;
1202     p.offset = 0;
1203     p.noalloc = true;
1204     p.format = fmt;
1205     p.hooks = global_hooks;
1206 
1207     return print_value(item, &p);
1208 }
1209 
1210 /* Parser core - when encountering text, process appropriately. */
parse_value(cJSON * const item,parse_buffer * const input_buffer)1211 static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer)
1212 {
1213     if ((input_buffer == NULL) || (input_buffer->content == NULL))
1214     {
1215         return false; /* no input */
1216     }
1217 
1218     /* parse the different types of values */
1219     /* null */
1220     if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0))
1221     {
1222         item->type = cJSON_NULL;
1223         input_buffer->offset += 4;
1224         return true;
1225     }
1226     /* false */
1227     if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0))
1228     {
1229         item->type = cJSON_False;
1230         input_buffer->offset += 5;
1231         return true;
1232     }
1233     /* true */
1234     if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0))
1235     {
1236         item->type = cJSON_True;
1237         item->valueint = 1;
1238         input_buffer->offset += 4;
1239         return true;
1240     }
1241     /* string */
1242     if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"'))
1243     {
1244         return parse_string(item, input_buffer);
1245     }
1246     /* number */
1247     if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9'))))
1248     {
1249         return parse_number(item, input_buffer);
1250     }
1251     /* array */
1252     if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '['))
1253     {
1254         return parse_array(item, input_buffer);
1255     }
1256     /* object */
1257     if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{'))
1258     {
1259         return parse_object(item, input_buffer);
1260     }
1261 
1262     return false;
1263 }
1264 
1265 /* Render a value to text. */
print_value(const cJSON * const item,printbuffer * const output_buffer)1266 static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer)
1267 {
1268     unsigned char *output = NULL;
1269 
1270     if ((item == NULL) || (output_buffer == NULL))
1271     {
1272         return false;
1273     }
1274 
1275     switch ((item->type) & 0xFF)
1276     {
1277         case cJSON_NULL:
1278             output = ensure(output_buffer, 5);
1279             if (output == NULL)
1280             {
1281                 return false;
1282             }
1283             strcpy((char*)output, "null");
1284             return true;
1285 
1286         case cJSON_False:
1287             output = ensure(output_buffer, 6);
1288             if (output == NULL)
1289             {
1290                 return false;
1291             }
1292             strcpy((char*)output, "false");
1293             return true;
1294 
1295         case cJSON_True:
1296             output = ensure(output_buffer, 5);
1297             if (output == NULL)
1298             {
1299                 return false;
1300             }
1301             strcpy((char*)output, "true");
1302             return true;
1303 
1304         case cJSON_Number:
1305             return print_number(item, output_buffer);
1306 
1307         case cJSON_Raw:
1308         {
1309             size_t raw_length = 0;
1310             if (item->valuestring == NULL)
1311             {
1312                 return false;
1313             }
1314 
1315             raw_length = strlen(item->valuestring) + sizeof("");
1316             output = ensure(output_buffer, raw_length);
1317             if (output == NULL)
1318             {
1319                 return false;
1320             }
1321             memcpy(output, item->valuestring, raw_length);
1322             return true;
1323         }
1324 
1325         case cJSON_String:
1326             return print_string(item, output_buffer);
1327 
1328         case cJSON_Array:
1329             return print_array(item, output_buffer);
1330 
1331         case cJSON_Object:
1332             return print_object(item, output_buffer);
1333 
1334         default:
1335             return false;
1336     }
1337 }
1338 
1339 /* Build an array from input text. */
parse_array(cJSON * const item,parse_buffer * const input_buffer)1340 static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer)
1341 {
1342     cJSON *head = NULL; /* head of the linked list */
1343     cJSON *current_item = NULL;
1344 
1345     if (input_buffer->depth >= CJSON_NESTING_LIMIT)
1346     {
1347         return false; /* to deeply nested */
1348     }
1349     input_buffer->depth++;
1350 
1351     if (buffer_at_offset(input_buffer)[0] != '[')
1352     {
1353         /* not an array */
1354         goto fail;
1355     }
1356 
1357     input_buffer->offset++;
1358     buffer_skip_whitespace(input_buffer);
1359     if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']'))
1360     {
1361         /* empty array */
1362         goto success;
1363     }
1364 
1365     /* check if we skipped to the end of the buffer */
1366     if (cannot_access_at_index(input_buffer, 0))
1367     {
1368         input_buffer->offset--;
1369         goto fail;
1370     }
1371 
1372     /* step back to character in front of the first element */
1373     input_buffer->offset--;
1374     /* loop through the comma separated array elements */
1375     do
1376     {
1377         /* allocate next item */
1378         cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
1379         if (new_item == NULL)
1380         {
1381             goto fail; /* allocation failure */
1382         }
1383 
1384         /* attach next item to list */
1385         if (head == NULL)
1386         {
1387             /* start the linked list */
1388             current_item = head = new_item;
1389         }
1390         else
1391         {
1392             /* add to the end and advance */
1393             current_item->next = new_item;
1394             new_item->prev = current_item;
1395             current_item = new_item;
1396         }
1397 
1398         /* parse next value */
1399         input_buffer->offset++;
1400         buffer_skip_whitespace(input_buffer);
1401         if (!parse_value(current_item, input_buffer))
1402         {
1403             goto fail; /* failed to parse value */
1404         }
1405         buffer_skip_whitespace(input_buffer);
1406     }
1407     while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
1408 
1409     if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']')
1410     {
1411         goto fail; /* expected end of array */
1412     }
1413 
1414 success:
1415     input_buffer->depth--;
1416 
1417     item->type = cJSON_Array;
1418     item->child = head;
1419 
1420     input_buffer->offset++;
1421 
1422     return true;
1423 
1424 fail:
1425     if (head != NULL)
1426     {
1427         cJSON_Delete(head);
1428     }
1429 
1430     return false;
1431 }
1432 
1433 /* Render an array to text */
print_array(const cJSON * const item,printbuffer * const output_buffer)1434 static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer)
1435 {
1436     unsigned char *output_pointer = NULL;
1437     size_t length;
1438     cJSON *current_element = item->child;
1439 
1440     if (output_buffer == NULL)
1441     {
1442         return false;
1443     }
1444 
1445     /* Compose the output array. */
1446     /* opening square bracket */
1447     output_pointer = ensure(output_buffer, 1);
1448     if (output_pointer == NULL)
1449     {
1450         return false;
1451     }
1452 
1453     *output_pointer = '[';
1454     output_buffer->offset++;
1455     output_buffer->depth++;
1456 
1457     while (current_element != NULL)
1458     {
1459         if (!print_value(current_element, output_buffer))
1460         {
1461             return false;
1462         }
1463         update_offset(output_buffer);
1464         if (current_element->next)
1465         {
1466             length = (size_t) (output_buffer->format ? 2 : 1);
1467             output_pointer = ensure(output_buffer, length + 1);
1468             if (output_pointer == NULL)
1469             {
1470                 return false;
1471             }
1472             *output_pointer++ = ',';
1473             if(output_buffer->format)
1474             {
1475                 *output_pointer++ = ' ';
1476             }
1477             *output_pointer = '\0';
1478             output_buffer->offset += length;
1479         }
1480         current_element = current_element->next;
1481     }
1482 
1483     output_pointer = ensure(output_buffer, 2);
1484     if (output_pointer == NULL)
1485     {
1486         return false;
1487     }
1488     *output_pointer++ = ']';
1489     *output_pointer = '\0';
1490     output_buffer->depth--;
1491 
1492     return true;
1493 }
1494 
1495 /* Build an object from the text. */
parse_object(cJSON * const item,parse_buffer * const input_buffer)1496 static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer)
1497 {
1498     cJSON *head = NULL; /* linked list head */
1499     cJSON *current_item = NULL;
1500 
1501     if (input_buffer->depth >= CJSON_NESTING_LIMIT)
1502     {
1503         return false; /* to deeply nested */
1504     }
1505     input_buffer->depth++;
1506 
1507     if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{'))
1508     {
1509         goto fail; /* not an object */
1510     }
1511 
1512     input_buffer->offset++;
1513     buffer_skip_whitespace(input_buffer);
1514     if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}'))
1515     {
1516         goto success; /* empty object */
1517     }
1518 
1519     /* check if we skipped to the end of the buffer */
1520     if (cannot_access_at_index(input_buffer, 0))
1521     {
1522         input_buffer->offset--;
1523         goto fail;
1524     }
1525 
1526     /* step back to character in front of the first element */
1527     input_buffer->offset--;
1528     /* loop through the comma separated array elements */
1529     do
1530     {
1531         /* allocate next item */
1532         cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
1533         if (new_item == NULL)
1534         {
1535             goto fail; /* allocation failure */
1536         }
1537 
1538         /* attach next item to list */
1539         if (head == NULL)
1540         {
1541             /* start the linked list */
1542             current_item = head = new_item;
1543         }
1544         else
1545         {
1546             /* add to the end and advance */
1547             current_item->next = new_item;
1548             new_item->prev = current_item;
1549             current_item = new_item;
1550         }
1551 
1552         /* parse the name of the child */
1553         input_buffer->offset++;
1554         buffer_skip_whitespace(input_buffer);
1555         if (!parse_string(current_item, input_buffer))
1556         {
1557             goto fail; /* failed to parse name */
1558         }
1559         buffer_skip_whitespace(input_buffer);
1560 
1561         /* swap valuestring and string, because we parsed the name */
1562         current_item->string = current_item->valuestring;
1563         current_item->valuestring = NULL;
1564 
1565         if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':'))
1566         {
1567             goto fail; /* invalid object */
1568         }
1569 
1570         /* parse the value */
1571         input_buffer->offset++;
1572         buffer_skip_whitespace(input_buffer);
1573         if (!parse_value(current_item, input_buffer))
1574         {
1575             goto fail; /* failed to parse value */
1576         }
1577         buffer_skip_whitespace(input_buffer);
1578     }
1579     while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
1580 
1581     if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}'))
1582     {
1583         goto fail; /* expected end of object */
1584     }
1585 
1586 success:
1587     input_buffer->depth--;
1588 
1589     item->type = cJSON_Object;
1590     item->child = head;
1591 
1592     input_buffer->offset++;
1593     return true;
1594 
1595 fail:
1596     if (head != NULL)
1597     {
1598         cJSON_Delete(head);
1599     }
1600 
1601     return false;
1602 }
1603 
1604 /* Render an object to text. */
print_object(const cJSON * const item,printbuffer * const output_buffer)1605 static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer)
1606 {
1607     unsigned char *output_pointer = NULL;
1608     size_t length = 0;
1609     cJSON *current_item = item->child;
1610 
1611     if (output_buffer == NULL)
1612     {
1613         return false;
1614     }
1615 
1616     /* Compose the output: */
1617     length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */
1618     output_pointer = ensure(output_buffer, length + 1);
1619     if (output_pointer == NULL)
1620     {
1621         return false;
1622     }
1623 
1624     *output_pointer++ = '{';
1625     output_buffer->depth++;
1626     if (output_buffer->format)
1627     {
1628         *output_pointer++ = '\n';
1629     }
1630     output_buffer->offset += length;
1631 
1632     while (current_item)
1633     {
1634         if (output_buffer->format)
1635         {
1636             size_t i;
1637             output_pointer = ensure(output_buffer, output_buffer->depth);
1638             if (output_pointer == NULL)
1639             {
1640                 return false;
1641             }
1642             for (i = 0; i < output_buffer->depth; i++)
1643             {
1644                 *output_pointer++ = '\t';
1645             }
1646             output_buffer->offset += output_buffer->depth;
1647         }
1648 
1649         /* print key */
1650         if (!print_string_ptr((unsigned char*)current_item->string, output_buffer))
1651         {
1652             return false;
1653         }
1654         update_offset(output_buffer);
1655 
1656         length = (size_t) (output_buffer->format ? 2 : 1);
1657         output_pointer = ensure(output_buffer, length);
1658         if (output_pointer == NULL)
1659         {
1660             return false;
1661         }
1662         *output_pointer++ = ':';
1663         if (output_buffer->format)
1664         {
1665             *output_pointer++ = '\t';
1666         }
1667         output_buffer->offset += length;
1668 
1669         /* print value */
1670         if (!print_value(current_item, output_buffer))
1671         {
1672             return false;
1673         }
1674         update_offset(output_buffer);
1675 
1676         /* print comma if not last */
1677         length = (size_t) ((output_buffer->format ? 1 : 0) + (current_item->next ? 1 : 0));
1678         output_pointer = ensure(output_buffer, length + 1);
1679         if (output_pointer == NULL)
1680         {
1681             return false;
1682         }
1683         if (current_item->next)
1684         {
1685             *output_pointer++ = ',';
1686         }
1687 
1688         if (output_buffer->format)
1689         {
1690             *output_pointer++ = '\n';
1691         }
1692         *output_pointer = '\0';
1693         output_buffer->offset += length;
1694 
1695         current_item = current_item->next;
1696     }
1697 
1698     output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2);
1699     if (output_pointer == NULL)
1700     {
1701         return false;
1702     }
1703     if (output_buffer->format)
1704     {
1705         size_t i;
1706         for (i = 0; i < (output_buffer->depth - 1); i++)
1707         {
1708             *output_pointer++ = '\t';
1709         }
1710     }
1711     *output_pointer++ = '}';
1712     *output_pointer = '\0';
1713     output_buffer->depth--;
1714 
1715     return true;
1716 }
1717 
1718 /* Get Array size/item / object item. */
cJSON_GetArraySize(const cJSON * array)1719 CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array)
1720 {
1721     cJSON *child = NULL;
1722     size_t size = 0;
1723 
1724     if (array == NULL)
1725     {
1726         return 0;
1727     }
1728 
1729     child = array->child;
1730 
1731     while(child != NULL)
1732     {
1733         size++;
1734         child = child->next;
1735     }
1736 
1737     /* FIXME: Can overflow here. Cannot be fixed without breaking the API */
1738 
1739     return (int)size;
1740 }
1741 
get_array_item(const cJSON * array,size_t index)1742 static cJSON* get_array_item(const cJSON *array, size_t index)
1743 {
1744     cJSON *current_child = NULL;
1745 
1746     if (array == NULL)
1747     {
1748         return NULL;
1749     }
1750 
1751     current_child = array->child;
1752     while ((current_child != NULL) && (index > 0))
1753     {
1754         index--;
1755         current_child = current_child->next;
1756     }
1757 
1758     return current_child;
1759 }
1760 
cJSON_GetArrayItem(const cJSON * array,int index)1761 CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index)
1762 {
1763     if (index < 0)
1764     {
1765         return NULL;
1766     }
1767 
1768     return get_array_item(array, (size_t)index);
1769 }
1770 
get_object_item(const cJSON * const object,const char * const name,const cJSON_bool case_sensitive)1771 static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive)
1772 {
1773     cJSON *current_element = NULL;
1774 
1775     if ((object == NULL) || (name == NULL))
1776     {
1777         return NULL;
1778     }
1779 
1780     current_element = object->child;
1781     if (case_sensitive)
1782     {
1783         while ((current_element != NULL) && (strcmp(name, current_element->string) != 0))
1784         {
1785             current_element = current_element->next;
1786         }
1787     }
1788     else
1789     {
1790         while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0))
1791         {
1792             current_element = current_element->next;
1793         }
1794     }
1795 
1796     return current_element;
1797 }
1798 
cJSON_GetObjectItem(const cJSON * const object,const char * const string)1799 CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string)
1800 {
1801     return get_object_item(object, string, false);
1802 }
1803 
cJSON_GetObjectItemCaseSensitive(const cJSON * const object,const char * const string)1804 CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string)
1805 {
1806     return get_object_item(object, string, true);
1807 }
1808 
cJSON_HasObjectItem(const cJSON * object,const char * string)1809 CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string)
1810 {
1811     return cJSON_GetObjectItem(object, string) ? 1 : 0;
1812 }
1813 
1814 /* Utility for array list handling. */
suffix_object(cJSON * prev,cJSON * item)1815 static void suffix_object(cJSON *prev, cJSON *item)
1816 {
1817     prev->next = item;
1818     item->prev = prev;
1819 }
1820 
1821 /* Utility for handling references. */
create_reference(const cJSON * item,const internal_hooks * const hooks)1822 static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks)
1823 {
1824     cJSON *reference = NULL;
1825     if (item == NULL)
1826     {
1827         return NULL;
1828     }
1829 
1830     reference = cJSON_New_Item(hooks);
1831     if (reference == NULL)
1832     {
1833         return NULL;
1834     }
1835 
1836     memcpy(reference, item, sizeof(cJSON));
1837     reference->string = NULL;
1838     reference->type |= cJSON_IsReference;
1839     reference->next = reference->prev = NULL;
1840     return reference;
1841 }
1842 
add_item_to_array(cJSON * array,cJSON * item)1843 static cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
1844 {
1845     cJSON *child = NULL;
1846 
1847     if ((item == NULL) || (array == NULL))
1848     {
1849         return false;
1850     }
1851 
1852     child = array->child;
1853 
1854     if (child == NULL)
1855     {
1856         /* list is empty, start new one */
1857         array->child = item;
1858     }
1859     else
1860     {
1861         /* append to the end */
1862         while (child->next)
1863         {
1864             child = child->next;
1865         }
1866         suffix_object(child, item);
1867     }
1868 
1869     return true;
1870 }
1871 
1872 /* Add item to array/object. */
cJSON_AddItemToArray(cJSON * array,cJSON * item)1873 CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item)
1874 {
1875     add_item_to_array(array, item);
1876 }
1877 
1878 #if defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
1879     #pragma GCC diagnostic push
1880 #endif
1881 #ifdef __GNUC__
1882 #pragma GCC diagnostic ignored "-Wcast-qual"
1883 #endif
1884 /* helper function to cast away const */
cast_away_const(const void * string)1885 static void* cast_away_const(const void* string)
1886 {
1887     return (void*)string;
1888 }
1889 #if defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
1890     #pragma GCC diagnostic pop
1891 #endif
1892 
1893 
add_item_to_object(cJSON * const object,const char * const string,cJSON * const item,const internal_hooks * const hooks,const cJSON_bool constant_key)1894 static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key)
1895 {
1896     char *new_key = NULL;
1897     int new_type = cJSON_Invalid;
1898 
1899     if ((object == NULL) || (string == NULL) || (item == NULL))
1900     {
1901         return false;
1902     }
1903 
1904     if (constant_key)
1905     {
1906         new_key = (char*)cast_away_const(string);
1907         new_type = item->type | cJSON_StringIsConst;
1908     }
1909     else
1910     {
1911         new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
1912         if (new_key == NULL)
1913         {
1914             return false;
1915         }
1916 
1917         new_type = item->type & ~cJSON_StringIsConst;
1918     }
1919 
1920     if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
1921     {
1922         hooks->deallocate(item->string);
1923     }
1924 
1925     item->string = new_key;
1926     item->type = new_type;
1927 
1928     return add_item_to_array(object, item);
1929 }
1930 
cJSON_AddItemToObject(cJSON * object,const char * string,cJSON * item)1931 CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
1932 {
1933     add_item_to_object(object, string, item, &global_hooks, false);
1934 }
1935 
1936 /* Add an item to an object with constant string as key */
cJSON_AddItemToObjectCS(cJSON * object,const char * string,cJSON * item)1937 CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
1938 {
1939     add_item_to_object(object, string, item, &global_hooks, true);
1940 }
1941 
cJSON_AddItemReferenceToArray(cJSON * array,cJSON * item)1942 CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
1943 {
1944     if (array == NULL)
1945     {
1946         return;
1947     }
1948 
1949     add_item_to_array(array, create_reference(item, &global_hooks));
1950 }
1951 
cJSON_AddItemReferenceToObject(cJSON * object,const char * string,cJSON * item)1952 CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
1953 {
1954     if ((object == NULL) || (string == NULL))
1955     {
1956         return;
1957     }
1958 
1959     add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
1960 }
1961 
cJSON_AddNullToObject(cJSON * const object,const char * const name)1962 CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)
1963 {
1964     cJSON *null = cJSON_CreateNull();
1965     if (add_item_to_object(object, name, null, &global_hooks, false))
1966     {
1967         return null;
1968     }
1969 
1970     cJSON_Delete(null);
1971     return NULL;
1972 }
1973 
cJSON_AddTrueToObject(cJSON * const object,const char * const name)1974 CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name)
1975 {
1976     cJSON *true_item = cJSON_CreateTrue();
1977     if (add_item_to_object(object, name, true_item, &global_hooks, false))
1978     {
1979         return true_item;
1980     }
1981 
1982     cJSON_Delete(true_item);
1983     return NULL;
1984 }
1985 
cJSON_AddFalseToObject(cJSON * const object,const char * const name)1986 CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name)
1987 {
1988     cJSON *false_item = cJSON_CreateFalse();
1989     if (add_item_to_object(object, name, false_item, &global_hooks, false))
1990     {
1991         return false_item;
1992     }
1993 
1994     cJSON_Delete(false_item);
1995     return NULL;
1996 }
1997 
cJSON_AddBoolToObject(cJSON * const object,const char * const name,const cJSON_bool boolean)1998 CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean)
1999 {
2000     cJSON *bool_item = cJSON_CreateBool(boolean);
2001     if (add_item_to_object(object, name, bool_item, &global_hooks, false))
2002     {
2003         return bool_item;
2004     }
2005 
2006     cJSON_Delete(bool_item);
2007     return NULL;
2008 }
2009 
cJSON_AddNumberToObject(cJSON * const object,const char * const name,const double number)2010 CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number)
2011 {
2012     cJSON *number_item = cJSON_CreateNumber(number);
2013     if (add_item_to_object(object, name, number_item, &global_hooks, false))
2014     {
2015         return number_item;
2016     }
2017 
2018     cJSON_Delete(number_item);
2019     return NULL;
2020 }
2021 
cJSON_AddStringToObject(cJSON * const object,const char * const name,const char * const string)2022 CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string)
2023 {
2024     cJSON *string_item = cJSON_CreateString(string);
2025     if (add_item_to_object(object, name, string_item, &global_hooks, false))
2026     {
2027         return string_item;
2028     }
2029 
2030     cJSON_Delete(string_item);
2031     return NULL;
2032 }
2033 
cJSON_AddRawToObject(cJSON * const object,const char * const name,const char * const raw)2034 CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw)
2035 {
2036     cJSON *raw_item = cJSON_CreateRaw(raw);
2037     if (add_item_to_object(object, name, raw_item, &global_hooks, false))
2038     {
2039         return raw_item;
2040     }
2041 
2042     cJSON_Delete(raw_item);
2043     return NULL;
2044 }
2045 
cJSON_AddObjectToObject(cJSON * const object,const char * const name)2046 CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name)
2047 {
2048     cJSON *object_item = cJSON_CreateObject();
2049     if (add_item_to_object(object, name, object_item, &global_hooks, false))
2050     {
2051         return object_item;
2052     }
2053 
2054     cJSON_Delete(object_item);
2055     return NULL;
2056 }
2057 
cJSON_AddArrayToObject(cJSON * const object,const char * const name)2058 CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name)
2059 {
2060     cJSON *array = cJSON_CreateArray();
2061     if (add_item_to_object(object, name, array, &global_hooks, false))
2062     {
2063         return array;
2064     }
2065 
2066     cJSON_Delete(array);
2067     return NULL;
2068 }
2069 
cJSON_DetachItemViaPointer(cJSON * parent,cJSON * const item)2070 CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
2071 {
2072     if ((parent == NULL) || (item == NULL))
2073     {
2074         return NULL;
2075     }
2076 
2077     if (item->prev != NULL)
2078     {
2079         /* not the first element */
2080         item->prev->next = item->next;
2081     }
2082     if (item->next != NULL)
2083     {
2084         /* not the last element */
2085         item->next->prev = item->prev;
2086     }
2087 
2088     if (item == parent->child)
2089     {
2090         /* first element */
2091         parent->child = item->next;
2092     }
2093     /* make sure the detached item doesn't point anywhere anymore */
2094     item->prev = NULL;
2095     item->next = NULL;
2096 
2097     return item;
2098 }
2099 
cJSON_DetachItemFromArray(cJSON * array,int which)2100 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which)
2101 {
2102     if (which < 0)
2103     {
2104         return NULL;
2105     }
2106 
2107     return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which));
2108 }
2109 
cJSON_DeleteItemFromArray(cJSON * array,int which)2110 CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which)
2111 {
2112     cJSON_Delete(cJSON_DetachItemFromArray(array, which));
2113 }
2114 
cJSON_DetachItemFromObject(cJSON * object,const char * string)2115 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string)
2116 {
2117     cJSON *to_detach = cJSON_GetObjectItem(object, string);
2118 
2119     return cJSON_DetachItemViaPointer(object, to_detach);
2120 }
2121 
cJSON_DetachItemFromObjectCaseSensitive(cJSON * object,const char * string)2122 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string)
2123 {
2124     cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string);
2125 
2126     return cJSON_DetachItemViaPointer(object, to_detach);
2127 }
2128 
cJSON_DeleteItemFromObject(cJSON * object,const char * string)2129 CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
2130 {
2131     cJSON_Delete(cJSON_DetachItemFromObject(object, string));
2132 }
2133 
cJSON_DeleteItemFromObjectCaseSensitive(cJSON * object,const char * string)2134 CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string)
2135 {
2136     cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string));
2137 }
2138 
2139 /* Replace array/object items with new ones. */
cJSON_InsertItemInArray(cJSON * array,int which,cJSON * newitem)2140 CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
2141 {
2142     cJSON *after_inserted = NULL;
2143 
2144     if (which < 0)
2145     {
2146         return;
2147     }
2148 
2149     after_inserted = get_array_item(array, (size_t)which);
2150     if (after_inserted == NULL)
2151     {
2152         add_item_to_array(array, newitem);
2153         return;
2154     }
2155 
2156     newitem->next = after_inserted;
2157     newitem->prev = after_inserted->prev;
2158     after_inserted->prev = newitem;
2159     if (after_inserted == array->child)
2160     {
2161         array->child = newitem;
2162     }
2163     else
2164     {
2165         newitem->prev->next = newitem;
2166     }
2167 }
2168 
cJSON_ReplaceItemViaPointer(cJSON * const parent,cJSON * const item,cJSON * replacement)2169 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
2170 {
2171     if ((parent == NULL) || (replacement == NULL) || (item == NULL))
2172     {
2173         return false;
2174     }
2175 
2176     if (replacement == item)
2177     {
2178         return true;
2179     }
2180 
2181     replacement->next = item->next;
2182     replacement->prev = item->prev;
2183 
2184     if (replacement->next != NULL)
2185     {
2186         replacement->next->prev = replacement;
2187     }
2188     if (replacement->prev != NULL)
2189     {
2190         replacement->prev->next = replacement;
2191     }
2192     if (parent->child == item)
2193     {
2194         parent->child = replacement;
2195     }
2196 
2197     item->next = NULL;
2198     item->prev = NULL;
2199     cJSON_Delete(item);
2200 
2201     return true;
2202 }
2203 
cJSON_ReplaceItemInArray(cJSON * array,int which,cJSON * newitem)2204 CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
2205 {
2206     if (which < 0)
2207     {
2208         return;
2209     }
2210 
2211     cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);
2212 }
2213 
replace_item_in_object(cJSON * object,const char * string,cJSON * replacement,cJSON_bool case_sensitive)2214 static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
2215 {
2216     if ((replacement == NULL) || (string == NULL))
2217     {
2218         return false;
2219     }
2220 
2221     /* replace the name in the replacement */
2222     if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL))
2223     {
2224         cJSON_free(replacement->string);
2225     }
2226     replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
2227     replacement->type &= ~cJSON_StringIsConst;
2228 
2229     cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
2230 
2231     return true;
2232 }
2233 
cJSON_ReplaceItemInObject(cJSON * object,const char * string,cJSON * newitem)2234 CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
2235 {
2236     replace_item_in_object(object, string, newitem, false);
2237 }
2238 
cJSON_ReplaceItemInObjectCaseSensitive(cJSON * object,const char * string,cJSON * newitem)2239 CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)
2240 {
2241     replace_item_in_object(object, string, newitem, true);
2242 }
2243 
2244 /* Create basic types: */
cJSON_CreateNull(void)2245 CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void)
2246 {
2247     cJSON *item = cJSON_New_Item(&global_hooks);
2248     if(item)
2249     {
2250         item->type = cJSON_NULL;
2251     }
2252 
2253     return item;
2254 }
2255 
cJSON_CreateTrue(void)2256 CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void)
2257 {
2258     cJSON *item = cJSON_New_Item(&global_hooks);
2259     if(item)
2260     {
2261         item->type = cJSON_True;
2262     }
2263 
2264     return item;
2265 }
2266 
cJSON_CreateFalse(void)2267 CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void)
2268 {
2269     cJSON *item = cJSON_New_Item(&global_hooks);
2270     if(item)
2271     {
2272         item->type = cJSON_False;
2273     }
2274 
2275     return item;
2276 }
2277 
cJSON_CreateBool(cJSON_bool b)2278 CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool b)
2279 {
2280     cJSON *item = cJSON_New_Item(&global_hooks);
2281     if(item)
2282     {
2283         item->type = b ? cJSON_True : cJSON_False;
2284     }
2285 
2286     return item;
2287 }
2288 
cJSON_CreateNumber(double num)2289 CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
2290 {
2291     cJSON *item = cJSON_New_Item(&global_hooks);
2292     if(item)
2293     {
2294         item->type = cJSON_Number;
2295         item->valuedouble = num;
2296 
2297         /* use saturation in case of overflow */
2298         if (num >= INT_MAX)
2299         {
2300             item->valueint = INT_MAX;
2301         }
2302         else if (num <= INT_MIN)
2303         {
2304             item->valueint = INT_MIN;
2305         }
2306         else
2307         {
2308             item->valueint = (int)num;
2309         }
2310     }
2311 
2312     return item;
2313 }
2314 
cJSON_CreateString(const char * string)2315 CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string)
2316 {
2317     cJSON *item = cJSON_New_Item(&global_hooks);
2318     if(item)
2319     {
2320         item->type = cJSON_String;
2321         item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
2322         if(!item->valuestring)
2323         {
2324             cJSON_Delete(item);
2325             return NULL;
2326         }
2327     }
2328 
2329     return item;
2330 }
2331 
cJSON_CreateStringReference(const char * string)2332 CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string)
2333 {
2334     cJSON *item = cJSON_New_Item(&global_hooks);
2335     if (item != NULL)
2336     {
2337         item->type = cJSON_String | cJSON_IsReference;
2338         item->valuestring = (char*)cast_away_const(string);
2339     }
2340 
2341     return item;
2342 }
2343 
cJSON_CreateObjectReference(const cJSON * child)2344 CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child)
2345 {
2346     cJSON *item = cJSON_New_Item(&global_hooks);
2347     if (item != NULL) {
2348         item->type = cJSON_Object | cJSON_IsReference;
2349         item->child = (cJSON*)cast_away_const(child);
2350     }
2351 
2352     return item;
2353 }
2354 
cJSON_CreateArrayReference(const cJSON * child)2355 CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) {
2356     cJSON *item = cJSON_New_Item(&global_hooks);
2357     if (item != NULL) {
2358         item->type = cJSON_Array | cJSON_IsReference;
2359         item->child = (cJSON*)cast_away_const(child);
2360     }
2361 
2362     return item;
2363 }
2364 
cJSON_CreateRaw(const char * raw)2365 CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw)
2366 {
2367     cJSON *item = cJSON_New_Item(&global_hooks);
2368     if(item)
2369     {
2370         item->type = cJSON_Raw;
2371         item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks);
2372         if(!item->valuestring)
2373         {
2374             cJSON_Delete(item);
2375             return NULL;
2376         }
2377     }
2378 
2379     return item;
2380 }
2381 
cJSON_CreateArray(void)2382 CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void)
2383 {
2384     cJSON *item = cJSON_New_Item(&global_hooks);
2385     if(item)
2386     {
2387         item->type=cJSON_Array;
2388     }
2389 
2390     return item;
2391 }
2392 
cJSON_CreateObject(void)2393 CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void)
2394 {
2395     cJSON *item = cJSON_New_Item(&global_hooks);
2396     if (item)
2397     {
2398         item->type = cJSON_Object;
2399     }
2400 
2401     return item;
2402 }
2403 
2404 /* Create Arrays: */
cJSON_CreateIntArray(const int * numbers,int count)2405 CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
2406 {
2407     size_t i = 0;
2408     cJSON *n = NULL;
2409     cJSON *p = NULL;
2410     cJSON *a = NULL;
2411 
2412     if ((count < 0) || (numbers == NULL))
2413     {
2414         return NULL;
2415     }
2416 
2417     a = cJSON_CreateArray();
2418     for(i = 0; a && (i < (size_t)count); i++)
2419     {
2420         n = cJSON_CreateNumber(numbers[i]);
2421         if (!n)
2422         {
2423             cJSON_Delete(a);
2424             return NULL;
2425         }
2426         if(!i)
2427         {
2428             a->child = n;
2429         }
2430         else
2431         {
2432             suffix_object(p, n);
2433         }
2434         p = n;
2435     }
2436 
2437     return a;
2438 }
2439 
cJSON_CreateFloatArray(const float * numbers,int count)2440 CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)
2441 {
2442     size_t i = 0;
2443     cJSON *n = NULL;
2444     cJSON *p = NULL;
2445     cJSON *a = NULL;
2446 
2447     if ((count < 0) || (numbers == NULL))
2448     {
2449         return NULL;
2450     }
2451 
2452     a = cJSON_CreateArray();
2453 
2454     for(i = 0; a && (i < (size_t)count); i++)
2455     {
2456         n = cJSON_CreateNumber((double)numbers[i]);
2457         if(!n)
2458         {
2459             cJSON_Delete(a);
2460             return NULL;
2461         }
2462         if(!i)
2463         {
2464             a->child = n;
2465         }
2466         else
2467         {
2468             suffix_object(p, n);
2469         }
2470         p = n;
2471     }
2472 
2473     return a;
2474 }
2475 
cJSON_CreateDoubleArray(const double * numbers,int count)2476 CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
2477 {
2478     size_t i = 0;
2479     cJSON *n = NULL;
2480     cJSON *p = NULL;
2481     cJSON *a = NULL;
2482 
2483     if ((count < 0) || (numbers == NULL))
2484     {
2485         return NULL;
2486     }
2487 
2488     a = cJSON_CreateArray();
2489 
2490     for(i = 0;a && (i < (size_t)count); i++)
2491     {
2492         n = cJSON_CreateNumber(numbers[i]);
2493         if(!n)
2494         {
2495             cJSON_Delete(a);
2496             return NULL;
2497         }
2498         if(!i)
2499         {
2500             a->child = n;
2501         }
2502         else
2503         {
2504             suffix_object(p, n);
2505         }
2506         p = n;
2507     }
2508 
2509     return a;
2510 }
2511 
cJSON_CreateStringArray(const char ** strings,int count)2512 CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count)
2513 {
2514     size_t i = 0;
2515     cJSON *n = NULL;
2516     cJSON *p = NULL;
2517     cJSON *a = NULL;
2518 
2519     if ((count < 0) || (strings == NULL))
2520     {
2521         return NULL;
2522     }
2523 
2524     a = cJSON_CreateArray();
2525 
2526     for (i = 0; a && (i < (size_t)count); i++)
2527     {
2528         n = cJSON_CreateString(strings[i]);
2529         if(!n)
2530         {
2531             cJSON_Delete(a);
2532             return NULL;
2533         }
2534         if(!i)
2535         {
2536             a->child = n;
2537         }
2538         else
2539         {
2540             suffix_object(p,n);
2541         }
2542         p = n;
2543     }
2544 
2545     return a;
2546 }
2547 
2548 /* Duplication */
cJSON_Duplicate(const cJSON * item,cJSON_bool recurse)2549 CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
2550 {
2551     cJSON *newitem = NULL;
2552     cJSON *child = NULL;
2553     cJSON *next = NULL;
2554     cJSON *newchild = NULL;
2555 
2556     /* Bail on bad ptr */
2557     if (!item)
2558     {
2559         goto fail;
2560     }
2561     /* Create new item */
2562     newitem = cJSON_New_Item(&global_hooks);
2563     if (!newitem)
2564     {
2565         goto fail;
2566     }
2567     /* Copy over all vars */
2568     newitem->type = item->type & (~cJSON_IsReference);
2569     newitem->valueint = item->valueint;
2570     newitem->valuedouble = item->valuedouble;
2571     if (item->valuestring)
2572     {
2573         newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks);
2574         if (!newitem->valuestring)
2575         {
2576             goto fail;
2577         }
2578     }
2579     if (item->string)
2580     {
2581         newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks);
2582         if (!newitem->string)
2583         {
2584             goto fail;
2585         }
2586     }
2587     /* If non-recursive, then we're done! */
2588     if (!recurse)
2589     {
2590         return newitem;
2591     }
2592     /* Walk the ->next chain for the child. */
2593     child = item->child;
2594     while (child != NULL)
2595     {
2596         newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
2597         if (!newchild)
2598         {
2599             goto fail;
2600         }
2601         if (next != NULL)
2602         {
2603             /* If newitem->child already set, then crosswire ->prev and ->next and move on */
2604             next->next = newchild;
2605             newchild->prev = next;
2606             next = newchild;
2607         }
2608         else
2609         {
2610             /* Set newitem->child and move to it */
2611             newitem->child = newchild;
2612             next = newchild;
2613         }
2614         child = child->next;
2615     }
2616 
2617     return newitem;
2618 
2619 fail:
2620     if (newitem != NULL)
2621     {
2622         cJSON_Delete(newitem);
2623     }
2624 
2625     return NULL;
2626 }
2627 
cJSON_Minify(char * json)2628 CJSON_PUBLIC(void) cJSON_Minify(char *json)
2629 {
2630     unsigned char *into = (unsigned char*)json;
2631 
2632     if (json == NULL)
2633     {
2634         return;
2635     }
2636 
2637     while (*json)
2638     {
2639         if (*json == ' ')
2640         {
2641             json++;
2642         }
2643         else if (*json == '\t')
2644         {
2645             /* Whitespace characters. */
2646             json++;
2647         }
2648         else if (*json == '\r')
2649         {
2650             json++;
2651         }
2652         else if (*json=='\n')
2653         {
2654             json++;
2655         }
2656         else if ((*json == '/') && (json[1] == '/'))
2657         {
2658             /* double-slash comments, to end of line. */
2659             while (*json && (*json != '\n'))
2660             {
2661                 json++;
2662             }
2663         }
2664         else if ((*json == '/') && (json[1] == '*'))
2665         {
2666             /* multiline comments. */
2667             while (*json && !((*json == '*') && (json[1] == '/')))
2668             {
2669                 json++;
2670             }
2671             json += 2;
2672         }
2673         else if (*json == '\"')
2674         {
2675             /* string literals, which are \" sensitive. */
2676             *into++ = (unsigned char)*json++;
2677             while (*json && (*json != '\"'))
2678             {
2679                 if (*json == '\\')
2680                 {
2681                     *into++ = (unsigned char)*json++;
2682                 }
2683                 *into++ = (unsigned char)*json++;
2684             }
2685             *into++ = (unsigned char)*json++;
2686         }
2687         else
2688         {
2689             /* All other characters. */
2690             *into++ = (unsigned char)*json++;
2691         }
2692     }
2693 
2694     /* and null-terminate. */
2695     *into = '\0';
2696 }
2697 
cJSON_IsInvalid(const cJSON * const item)2698 CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item)
2699 {
2700     if (item == NULL)
2701     {
2702         return false;
2703     }
2704 
2705     return (item->type & 0xFF) == cJSON_Invalid;
2706 }
2707 
cJSON_IsFalse(const cJSON * const item)2708 CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item)
2709 {
2710     if (item == NULL)
2711     {
2712         return false;
2713     }
2714 
2715     return (item->type & 0xFF) == cJSON_False;
2716 }
2717 
cJSON_IsTrue(const cJSON * const item)2718 CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item)
2719 {
2720     if (item == NULL)
2721     {
2722         return false;
2723     }
2724 
2725     return (item->type & 0xff) == cJSON_True;
2726 }
2727 
2728 
cJSON_IsBool(const cJSON * const item)2729 CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item)
2730 {
2731     if (item == NULL)
2732     {
2733         return false;
2734     }
2735 
2736     return (item->type & (cJSON_True | cJSON_False)) != 0;
2737 }
cJSON_IsNull(const cJSON * const item)2738 CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item)
2739 {
2740     if (item == NULL)
2741     {
2742         return false;
2743     }
2744 
2745     return (item->type & 0xFF) == cJSON_NULL;
2746 }
2747 
cJSON_IsNumber(const cJSON * const item)2748 CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item)
2749 {
2750     if (item == NULL)
2751     {
2752         return false;
2753     }
2754 
2755     return (item->type & 0xFF) == cJSON_Number;
2756 }
2757 
cJSON_IsString(const cJSON * const item)2758 CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item)
2759 {
2760     if (item == NULL)
2761     {
2762         return false;
2763     }
2764 
2765     return (item->type & 0xFF) == cJSON_String;
2766 }
2767 
cJSON_IsArray(const cJSON * const item)2768 CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item)
2769 {
2770     if (item == NULL)
2771     {
2772         return false;
2773     }
2774 
2775     return (item->type & 0xFF) == cJSON_Array;
2776 }
2777 
cJSON_IsObject(const cJSON * const item)2778 CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item)
2779 {
2780     if (item == NULL)
2781     {
2782         return false;
2783     }
2784 
2785     return (item->type & 0xFF) == cJSON_Object;
2786 }
2787 
cJSON_IsRaw(const cJSON * const item)2788 CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
2789 {
2790     if (item == NULL)
2791     {
2792         return false;
2793     }
2794 
2795     return (item->type & 0xFF) == cJSON_Raw;
2796 }
2797 
cJSON_Compare(const cJSON * const a,const cJSON * const b,const cJSON_bool case_sensitive)2798 CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
2799 {
2800     if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))
2801     {
2802         return false;
2803     }
2804 
2805     /* check if type is valid */
2806     switch (a->type & 0xFF)
2807     {
2808         case cJSON_False:
2809         case cJSON_True:
2810         case cJSON_NULL:
2811         case cJSON_Number:
2812         case cJSON_String:
2813         case cJSON_Raw:
2814         case cJSON_Array:
2815         case cJSON_Object:
2816             break;
2817 
2818         default:
2819             return false;
2820     }
2821 
2822     /* identical objects are equal */
2823     if (a == b)
2824     {
2825         return true;
2826     }
2827 
2828     switch (a->type & 0xFF)
2829     {
2830         /* in these cases and equal type is enough */
2831         case cJSON_False:
2832         case cJSON_True:
2833         case cJSON_NULL:
2834             return true;
2835 
2836         case cJSON_Number:
2837             if (a->valuedouble == b->valuedouble)
2838             {
2839                 return true;
2840             }
2841             return false;
2842 
2843         case cJSON_String:
2844         case cJSON_Raw:
2845             if ((a->valuestring == NULL) || (b->valuestring == NULL))
2846             {
2847                 return false;
2848             }
2849             if (strcmp(a->valuestring, b->valuestring) == 0)
2850             {
2851                 return true;
2852             }
2853 
2854             return false;
2855 
2856         case cJSON_Array:
2857         {
2858             cJSON *a_element = a->child;
2859             cJSON *b_element = b->child;
2860 
2861             for (; (a_element != NULL) && (b_element != NULL);)
2862             {
2863                 if (!cJSON_Compare(a_element, b_element, case_sensitive))
2864                 {
2865                     return false;
2866                 }
2867 
2868                 a_element = a_element->next;
2869                 b_element = b_element->next;
2870             }
2871 
2872             /* one of the arrays is longer than the other */
2873             if (a_element != b_element) {
2874                 return false;
2875             }
2876 
2877             return true;
2878         }
2879 
2880         case cJSON_Object:
2881         {
2882             cJSON *a_element = NULL;
2883             cJSON *b_element = NULL;
2884             cJSON_ArrayForEach(a_element, a)
2885             {
2886                 /* TODO This has O(n^2) runtime, which is horrible! */
2887                 b_element = get_object_item(b, a_element->string, case_sensitive);
2888                 if (b_element == NULL)
2889                 {
2890                     return false;
2891                 }
2892 
2893                 if (!cJSON_Compare(a_element, b_element, case_sensitive))
2894                 {
2895                     return false;
2896                 }
2897             }
2898 
2899             /* doing this twice, once on a and b to prevent true comparison if a subset of b
2900              * TODO: Do this the proper way, this is just a fix for now */
2901             cJSON_ArrayForEach(b_element, b)
2902             {
2903                 a_element = get_object_item(a, b_element->string, case_sensitive);
2904                 if (a_element == NULL)
2905                 {
2906                     return false;
2907                 }
2908 
2909                 if (!cJSON_Compare(b_element, a_element, case_sensitive))
2910                 {
2911                     return false;
2912                 }
2913             }
2914 
2915             return true;
2916         }
2917 
2918         default:
2919             return false;
2920     }
2921 }
2922 
cJSON_malloc(size_t size)2923 CJSON_PUBLIC(void *) cJSON_malloc(size_t size)
2924 {
2925     return global_hooks.allocate(size);
2926 }
2927 
cJSON_free(void * object)2928 CJSON_PUBLIC(void) cJSON_free(void *object)
2929 {
2930     global_hooks.deallocate(object);
2931 }
2932