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