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