converts a UTF-16 literal to UTF-8 * A literal can be one or two sequences of the form \uXXXX */
| 701 | /* converts a UTF-16 literal to UTF-8 |
| 702 | * A literal can be one or two sequences of the form \uXXXX */ |
| 703 | static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer) |
| 704 | { |
| 705 | long unsigned int codepoint = 0; |
| 706 | unsigned int first_code = 0; |
| 707 | const unsigned char *first_sequence = input_pointer; |
| 708 | unsigned char utf8_length = 0; |
| 709 | unsigned char utf8_position = 0; |
| 710 | unsigned char sequence_length = 0; |
| 711 | unsigned char first_byte_mark = 0; |
| 712 | |
| 713 | if ((input_end - first_sequence) < 6) |
| 714 | { |
| 715 | /* input ends unexpectedly */ |
| 716 | goto fail; |
| 717 | } |
| 718 | |
| 719 | /* get the first utf16 sequence */ |
| 720 | first_code = parse_hex4(first_sequence + 2); |
| 721 | |
| 722 | /* check that the code is valid */ |
| 723 | if (((first_code >= 0xDC00) && (first_code <= 0xDFFF))) |
| 724 | { |
| 725 | goto fail; |
| 726 | } |
| 727 | |
| 728 | /* UTF16 surrogate pair */ |
| 729 | if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) |
| 730 | { |
| 731 | const unsigned char *second_sequence = first_sequence + 6; |
| 732 | unsigned int second_code = 0; |
| 733 | sequence_length = 12; /* \uXXXX\uXXXX */ |
| 734 | |
| 735 | if ((input_end - second_sequence) < 6) |
| 736 | { |
| 737 | /* input ends unexpectedly */ |
| 738 | goto fail; |
| 739 | } |
| 740 | |
| 741 | if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u')) |
| 742 | { |
| 743 | /* missing second half of the surrogate pair */ |
| 744 | goto fail; |
| 745 | } |
| 746 | |
| 747 | /* get the second utf16 sequence */ |
| 748 | second_code = parse_hex4(second_sequence + 2); |
| 749 | /* check that the code is valid */ |
| 750 | if ((second_code < 0xDC00) || (second_code > 0xDFFF)) |
| 751 | { |
| 752 | /* invalid second half of the surrogate pair */ |
| 753 | goto fail; |
| 754 | } |
| 755 | |
| 756 | |
| 757 | /* calculate the unicode codepoint from the surrogate pair */ |
| 758 | codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); |
| 759 | } |
| 760 | else |
no test coverage detected