Parse the input text into an unescaped cinput, and populate item. */
| 698 | |
| 699 | /* Parse the input text into an unescaped cinput, and populate item. */ |
| 700 | static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer) |
| 701 | { |
| 702 | const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; |
| 703 | const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; |
| 704 | unsigned char *output_pointer = NULL; |
| 705 | unsigned char *output = NULL; |
| 706 | |
| 707 | /* not a string */ |
| 708 | if (buffer_at_offset(input_buffer)[0] != '\"') |
| 709 | { |
| 710 | goto fail; |
| 711 | } |
| 712 | |
| 713 | { |
| 714 | /* calculate approximate size of the output (overestimate) */ |
| 715 | size_t allocation_length = 0; |
| 716 | size_t skipped_bytes = 0; |
| 717 | while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"')) |
| 718 | { |
| 719 | /* is escape sequence */ |
| 720 | if (input_end[0] == '\\') |
| 721 | { |
| 722 | if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) |
| 723 | { |
| 724 | /* prevent buffer overflow when last input character is a backslash */ |
| 725 | goto fail; |
| 726 | } |
| 727 | skipped_bytes++; |
| 728 | input_end++; |
| 729 | } |
| 730 | input_end++; |
| 731 | } |
| 732 | if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"')) |
| 733 | { |
| 734 | goto fail; /* string ended unexpectedly */ |
| 735 | } |
| 736 | |
| 737 | /* This is at most how much we need for the output */ |
| 738 | allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes; |
| 739 | output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof("")); |
| 740 | if (output == NULL) |
| 741 | { |
| 742 | goto fail; /* allocation failure */ |
| 743 | } |
| 744 | } |
| 745 | |
| 746 | output_pointer = output; |
| 747 | /* loop through the string literal */ |
| 748 | while (input_pointer < input_end) |
| 749 | { |
| 750 | if (*input_pointer != '\\') |
| 751 | { |
| 752 | *output_pointer++ = *input_pointer++; |
| 753 | } |
| 754 | /* escape sequence */ |
| 755 | else |
| 756 | { |
| 757 | unsigned char sequence_length = 2; |
no test coverage detected