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