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