|  | @@ -662,17 +662,17 @@ fail:
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  /* Parse the input text into an unescaped cinput, and populate item. */
 |  |  /* Parse the input text into an unescaped cinput, and populate item. */
 | 
											
												
													
														|  | -static const unsigned char *parse_string(cJSON * const item, const unsigned char * const input, const unsigned char ** const error_pointer, const internal_hooks * const hooks)
 |  | 
 | 
											
												
													
														|  | 
 |  | +static const unsigned char *parse_string(cJSON * const item, parse_buffer * const input_buffer, const unsigned char ** const error_pointer, const internal_hooks * const hooks)
 | 
											
												
													
														|  |  {
 |  |  {
 | 
											
												
													
														|  | -    const unsigned char *input_pointer = input + 1;
 |  | 
 | 
											
												
													
														|  | -    const unsigned char *input_end = input + 1;
 |  | 
 | 
											
												
													
														|  | 
 |  | +    const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;
 | 
											
												
													
														|  | 
 |  | +    const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;
 | 
											
												
													
														|  |      unsigned char *output_pointer = NULL;
 |  |      unsigned char *output_pointer = NULL;
 | 
											
												
													
														|  |      unsigned char *output = NULL;
 |  |      unsigned char *output = NULL;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      /* not a string */
 |  |      /* not a string */
 | 
											
												
													
														|  | -    if (*input != '\"')
 |  | 
 | 
											
												
													
														|  | 
 |  | +    if (buffer_at_offset(input_buffer)[0] != '\"')
 | 
											
												
													
														|  |      {
 |  |      {
 | 
											
												
													
														|  | -        *error_pointer = input;
 |  | 
 | 
											
												
													
														|  | 
 |  | +        *error_pointer = buffer_at_offset(input_buffer);
 | 
											
												
													
														|  |          goto fail;
 |  |          goto fail;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -680,12 +680,12 @@ static const unsigned char *parse_string(cJSON * const item, const unsigned char
 | 
											
												
													
														|  |          /* calculate approximate size of the output (overestimate) */
 |  |          /* calculate approximate size of the output (overestimate) */
 | 
											
												
													
														|  |          size_t allocation_length = 0;
 |  |          size_t allocation_length = 0;
 | 
											
												
													
														|  |          size_t skipped_bytes = 0;
 |  |          size_t skipped_bytes = 0;
 | 
											
												
													
														|  | -        while ((*input_end != '\"') && (*input_end != '\0'))
 |  | 
 | 
											
												
													
														|  | 
 |  | +        while ((*input_end != '\"') && ((size_t)(input_end - input_buffer->content) < input_buffer->length))
 | 
											
												
													
														|  |          {
 |  |          {
 | 
											
												
													
														|  |              /* is escape sequence */
 |  |              /* is escape sequence */
 | 
											
												
													
														|  |              if (input_end[0] == '\\')
 |  |              if (input_end[0] == '\\')
 | 
											
												
													
														|  |              {
 |  |              {
 | 
											
												
													
														|  | -                if (input_end[1] == '\0')
 |  | 
 | 
											
												
													
														|  | 
 |  | +                if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length)
 | 
											
												
													
														|  |                  {
 |  |                  {
 | 
											
												
													
														|  |                      /* prevent buffer overflow when last input character is a backslash */
 |  |                      /* prevent buffer overflow when last input character is a backslash */
 | 
											
												
													
														|  |                      goto fail;
 |  |                      goto fail;
 | 
											
										
											
												
													
														|  | @@ -695,13 +695,13 @@ static const unsigned char *parse_string(cJSON * const item, const unsigned char
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  |              input_end++;
 |  |              input_end++;
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  | -        if (*input_end == '\0')
 |  | 
 | 
											
												
													
														|  | 
 |  | +        if (*input_end != '\"')
 | 
											
												
													
														|  |          {
 |  |          {
 | 
											
												
													
														|  |              goto fail; /* string ended unexpectedly */
 |  |              goto fail; /* string ended unexpectedly */
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          /* This is at most how much we need for the output */
 |  |          /* This is at most how much we need for the output */
 | 
											
												
													
														|  | -        allocation_length = (size_t) (input_end - input) - skipped_bytes;
 |  | 
 | 
											
												
													
														|  | 
 |  | +        allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes;
 | 
											
												
													
														|  |          output = (unsigned char*)hooks->allocate(allocation_length + sizeof(""));
 |  |          output = (unsigned char*)hooks->allocate(allocation_length + sizeof(""));
 | 
											
												
													
														|  |          if (output == NULL)
 |  |          if (output == NULL)
 | 
											
												
													
														|  |          {
 |  |          {
 | 
											
										
											
												
													
														|  | @@ -721,6 +721,11 @@ static const unsigned char *parse_string(cJSON * const item, const unsigned char
 | 
											
												
													
														|  |          else
 |  |          else
 | 
											
												
													
														|  |          {
 |  |          {
 | 
											
												
													
														|  |              unsigned char sequence_length = 2;
 |  |              unsigned char sequence_length = 2;
 | 
											
												
													
														|  | 
 |  | +            if ((input_end - input_pointer) < 1)
 | 
											
												
													
														|  | 
 |  | +            {
 | 
											
												
													
														|  | 
 |  | +                goto fail;
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |              switch (input_pointer[1])
 |  |              switch (input_pointer[1])
 | 
											
												
													
														|  |              {
 |  |              {
 | 
											
												
													
														|  |                  case 'b':
 |  |                  case 'b':
 | 
											
										
											
												
													
														|  | @@ -768,7 +773,10 @@ static const unsigned char *parse_string(cJSON * const item, const unsigned char
 | 
											
												
													
														|  |      item->type = cJSON_String;
 |  |      item->type = cJSON_String;
 | 
											
												
													
														|  |      item->valuestring = (char*)output;
 |  |      item->valuestring = (char*)output;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    return input_end + 1;
 |  | 
 | 
											
												
													
														|  | 
 |  | +    input_buffer->offset = (size_t) (input_end - input_buffer->content);
 | 
											
												
													
														|  | 
 |  | +    input_buffer->offset++;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    return buffer_at_offset(input_buffer);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  fail:
 |  |  fail:
 | 
											
												
													
														|  |      if (output != NULL)
 |  |      if (output != NULL)
 | 
											
										
											
												
													
														|  | @@ -1141,14 +1149,7 @@ static const unsigned  char *parse_value(cJSON * const item, parse_buffer * cons
 | 
											
												
													
														|  |      /* string */
 |  |      /* string */
 | 
											
												
													
														|  |      if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"'))
 |  |      if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"'))
 | 
											
												
													
														|  |      {
 |  |      {
 | 
											
												
													
														|  | -        content_pointer = parse_string(item, buffer_at_offset(input_buffer), error_pointer, hooks);
 |  | 
 | 
											
												
													
														|  | -        if (content_pointer == NULL)
 |  | 
 | 
											
												
													
														|  | -        {
 |  | 
 | 
											
												
													
														|  | -            return NULL;
 |  | 
 | 
											
												
													
														|  | -        }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -        input_buffer->offset = (size_t)(content_pointer - input_buffer->content);
 |  | 
 | 
											
												
													
														|  | -        return buffer_at_offset(input_buffer);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        return content_pointer = parse_string(item, input_buffer, error_pointer, hooks);
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |      /* number */
 |  |      /* number */
 | 
											
												
													
														|  |      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'))))
 |  |      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'))))
 | 
											
										
											
												
													
														|  | @@ -1422,7 +1423,6 @@ static const unsigned char *parse_object(cJSON * const item, parse_buffer * cons
 | 
											
												
													
														|  |  {
 |  |  {
 | 
											
												
													
														|  |      cJSON *head = NULL; /* linked list head */
 |  |      cJSON *head = NULL; /* linked list head */
 | 
											
												
													
														|  |      cJSON *current_item = NULL;
 |  |      cJSON *current_item = NULL;
 | 
											
												
													
														|  | -    const unsigned char *content_pointer = NULL;
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{'))
 |  |      if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{'))
 | 
											
												
													
														|  |      {
 |  |      {
 | 
											
										
											
												
													
														|  | @@ -1474,12 +1474,10 @@ static const unsigned char *parse_object(cJSON * const item, parse_buffer * cons
 | 
											
												
													
														|  |          /* parse the name of the child */
 |  |          /* parse the name of the child */
 | 
											
												
													
														|  |          input_buffer->offset++;
 |  |          input_buffer->offset++;
 | 
											
												
													
														|  |          buffer_skip_whitespace(input_buffer);
 |  |          buffer_skip_whitespace(input_buffer);
 | 
											
												
													
														|  | -        content_pointer = parse_string(current_item, buffer_at_offset(input_buffer), error_pointer, hooks);
 |  | 
 | 
											
												
													
														|  | -        if (content_pointer == NULL)
 |  | 
 | 
											
												
													
														|  | 
 |  | +        if (parse_string(current_item, input_buffer, error_pointer, hooks) == NULL)
 | 
											
												
													
														|  |          {
 |  |          {
 | 
											
												
													
														|  |              goto fail; /* faile to parse name */
 |  |              goto fail; /* faile to parse name */
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  | -        input_buffer->offset = (size_t)(content_pointer - input_buffer->content);
 |  | 
 | 
											
												
													
														|  |          buffer_skip_whitespace(input_buffer);
 |  |          buffer_skip_whitespace(input_buffer);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          /* swap valuestring and string, because we parsed the name */
 |  |          /* swap valuestring and string, because we parsed the name */
 |