| 1724 | } |
| 1725 | |
| 1726 | static int jl_decode_utf8(const unsigned char *text, size_t remaining, uint32_t *codepoint, |
| 1727 | size_t *byte_count) { |
| 1728 | if (remaining == 0U) { |
| 1729 | return -1; |
| 1730 | } |
| 1731 | unsigned char first = text[0]; |
| 1732 | if (first < 0x80U) { |
| 1733 | *codepoint = first; |
| 1734 | *byte_count = 1U; |
| 1735 | return 0; |
| 1736 | } |
| 1737 | size_t count = 0; |
| 1738 | uint32_t value = 0; |
| 1739 | uint32_t minimum = 0; |
| 1740 | if (first >= 0xC2U && first <= 0xDFU) { |
| 1741 | count = 2U; |
| 1742 | value = first & 0x1FU; |
| 1743 | minimum = 0x80U; |
| 1744 | } else if (first >= 0xE0U && first <= 0xEFU) { |
| 1745 | count = 3U; |
| 1746 | value = first & 0x0FU; |
| 1747 | minimum = 0x800U; |
| 1748 | } else if (first >= 0xF0U && first <= 0xF4U) { |
| 1749 | count = 4U; |
| 1750 | value = first & 0x07U; |
| 1751 | minimum = 0x10000U; |
| 1752 | } else { |
| 1753 | return -1; |
| 1754 | } |
| 1755 | if (remaining < count) { |
| 1756 | return -1; |
| 1757 | } |
| 1758 | for (size_t i = 1U; i < count; i++) { |
| 1759 | if ((text[i] & 0xC0U) != 0x80U) { |
| 1760 | return -1; |
| 1761 | } |
| 1762 | value = (value << 6U) | (text[i] & 0x3FU); |
| 1763 | } |
| 1764 | if (value < minimum || value > 0x10FFFFU || (value >= 0xD800U && value <= 0xDFFFU)) { |
| 1765 | return -1; |
| 1766 | } |
| 1767 | *codepoint = value; |
| 1768 | *byte_count = count; |
| 1769 | return 0; |
| 1770 | } |
| 1771 | |
| 1772 | static int jl_validate_utf8(const char *text, size_t length) { |
| 1773 | size_t pos = 0; |
no outgoing calls
no test coverage detected