|  | @@ -668,9 +668,9 @@ static unsigned char *print_string_ptr(const unsigned char * const input, printb
 | 
	
		
			
				|  |  |      const unsigned char *input_pointer = NULL;
 | 
	
		
			
				|  |  |      unsigned char *output = NULL;
 | 
	
		
			
				|  |  |      unsigned char *output_pointer = NULL;
 | 
	
		
			
				|  |  | -    size_t length = 0;
 | 
	
		
			
				|  |  | -    cjbool contains_special_char = false;
 | 
	
		
			
				|  |  | -    unsigned char token = '\0';
 | 
	
		
			
				|  |  | +    size_t output_length = 0;
 | 
	
		
			
				|  |  | +    /* numbers of additional characters needed for escaping */
 | 
	
		
			
				|  |  | +    size_t escape_characters = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      if (output_buffer == NULL)
 | 
	
		
			
				|  |  |      {
 | 
	
	
		
			
				|  | @@ -680,7 +680,7 @@ static unsigned char *print_string_ptr(const unsigned char * const input, printb
 | 
	
		
			
				|  |  |      /* empty string */
 | 
	
		
			
				|  |  |      if (input == NULL)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        output = ensure(output_buffer, 3);
 | 
	
		
			
				|  |  | +        output = ensure(output_buffer, sizeof("\"\""));
 | 
	
		
			
				|  |  |          if (output == NULL)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              return NULL;
 | 
	
	
		
			
				|  | @@ -693,102 +693,83 @@ static unsigned char *print_string_ptr(const unsigned char * const input, printb
 | 
	
		
			
				|  |  |      /* set "flag" to 1 if something needs to be escaped */
 | 
	
		
			
				|  |  |      for (input_pointer = input; *input_pointer; input_pointer++)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        contains_special_char |= (((*input_pointer > 0) && (*input_pointer < 32)) /* unprintable characters */
 | 
	
		
			
				|  |  | -                || (*input_pointer == '\"') /* double quote */
 | 
	
		
			
				|  |  | -                || (*input_pointer == '\\')) /* backslash */
 | 
	
		
			
				|  |  | -            ? 1
 | 
	
		
			
				|  |  | -            : 0;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    /* no characters have to be escaped */
 | 
	
		
			
				|  |  | -    if (!contains_special_char)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        length = (size_t)(input_pointer - input);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        output = ensure(output_buffer, length + 3);
 | 
	
		
			
				|  |  | -        if (output == NULL)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            return NULL;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        output_pointer = output;
 | 
	
		
			
				|  |  | -        *output_pointer++ = '\"';
 | 
	
		
			
				|  |  | -        strcpy((char*)output_pointer, (const char*)input);
 | 
	
		
			
				|  |  | -        output_pointer[length] = '\"';
 | 
	
		
			
				|  |  | -        output_pointer[length + 1] = '\0';
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        return output;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    input_pointer = input;
 | 
	
		
			
				|  |  | -    /* calculate additional space that is needed for escaping */
 | 
	
		
			
				|  |  | -    while ((token = *input_pointer))
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        ++length;
 | 
	
		
			
				|  |  | -        if (strchr("\"\\\b\f\n\r\t", token))
 | 
	
		
			
				|  |  | +        if (strchr("\"\\\b\f\n\r\t", *input_pointer))
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            length++; /* +1 for the backslash */
 | 
	
		
			
				|  |  | +            /* one character escape sequence */
 | 
	
		
			
				|  |  | +            escape_characters++;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        else if (token < 32)
 | 
	
		
			
				|  |  | +        else if (*input_pointer < 32)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            length += 5; /* +5 for \uXXXX */
 | 
	
		
			
				|  |  | +            /* UTF-16 escape sequence uXXXX */
 | 
	
		
			
				|  |  | +            escape_characters += 5;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        input_pointer++;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +    output_length = (size_t)(input_pointer - input) + escape_characters;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    output = ensure(output_buffer, length + 3);
 | 
	
		
			
				|  |  | +    output = ensure(output_buffer, output_length + sizeof("\"\""));
 | 
	
		
			
				|  |  |      if (output == NULL)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          return NULL;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    output_pointer = output;
 | 
	
		
			
				|  |  | -    input_pointer = input;
 | 
	
		
			
				|  |  | -    *output_pointer++ = '\"';
 | 
	
		
			
				|  |  | +    /* no characters have to be escaped */
 | 
	
		
			
				|  |  | +    if (escape_characters == 0)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        output[0] = '\"';
 | 
	
		
			
				|  |  | +        memcpy(output + 1, input, output_length);
 | 
	
		
			
				|  |  | +        output[output_length + 1] = '\"';
 | 
	
		
			
				|  |  | +        output[output_length + 2] = '\0';
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return output;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    output[0] = '\"';
 | 
	
		
			
				|  |  | +    output_pointer = output + 1;
 | 
	
		
			
				|  |  |      /* copy the string */
 | 
	
		
			
				|  |  | -    while (*input_pointer)
 | 
	
		
			
				|  |  | +    for (input_pointer = input; *input_pointer != '\0'; input_pointer++, output_pointer++)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\'))
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              /* normal character, copy */
 | 
	
		
			
				|  |  | -            *output_pointer++ = *input_pointer++;
 | 
	
		
			
				|  |  | +            *output_pointer = *input_pointer;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          else
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              /* character needs to be escaped */
 | 
	
		
			
				|  |  |              *output_pointer++ = '\\';
 | 
	
		
			
				|  |  | -            switch (token = *input_pointer++)
 | 
	
		
			
				|  |  | +            switch (*input_pointer)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  case '\\':
 | 
	
		
			
				|  |  | -                    *output_pointer++ = '\\';
 | 
	
		
			
				|  |  | +                    *output_pointer = '\\';
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  |                  case '\"':
 | 
	
		
			
				|  |  | -                    *output_pointer++ = '\"';
 | 
	
		
			
				|  |  | +                    *output_pointer = '\"';
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  |                  case '\b':
 | 
	
		
			
				|  |  | -                    *output_pointer++ = 'b';
 | 
	
		
			
				|  |  | +                    *output_pointer = 'b';
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  |                  case '\f':
 | 
	
		
			
				|  |  | -                    *output_pointer++ = 'f';
 | 
	
		
			
				|  |  | +                    *output_pointer = 'f';
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  |                  case '\n':
 | 
	
		
			
				|  |  | -                    *output_pointer++ = 'n';
 | 
	
		
			
				|  |  | +                    *output_pointer = 'n';
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  |                  case '\r':
 | 
	
		
			
				|  |  | -                    *output_pointer++ = 'r';
 | 
	
		
			
				|  |  | +                    *output_pointer = 'r';
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  |                  case '\t':
 | 
	
		
			
				|  |  | -                    *output_pointer++ = 't';
 | 
	
		
			
				|  |  | +                    *output_pointer = 't';
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  |                  default:
 | 
	
		
			
				|  |  |                      /* escape and print as unicode codepoint */
 | 
	
		
			
				|  |  | -                    sprintf((char*)output_pointer, "u%04x", token);
 | 
	
		
			
				|  |  | -                    output_pointer += 5;
 | 
	
		
			
				|  |  | +                    sprintf((char*)output_pointer, "u%04x", *input_pointer);
 | 
	
		
			
				|  |  | +                    output_pointer += 4;
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    *output_pointer++ = '\"';
 | 
	
		
			
				|  |  | -    *output_pointer++ = '\0';
 | 
	
		
			
				|  |  | +    output[output_length + 1] = '\"';
 | 
	
		
			
				|  |  | +    output[output_length + 2] = '\0';
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      return output;
 | 
	
		
			
				|  |  |  }
 |