LICENSE.md
6 days ago
README.md
6 days ago
compat-utf8.php
6 days ago
composer.json
6 days ago
utf8-encoder.php
6 days ago
utf8.php
6 days ago
utf8-encoder.php
71 lines
| 1 | <?php |
| 2 | |
| 3 | namespace WordPress\Encoding; |
| 4 | |
| 5 | /** |
| 6 | * UTF-8 encoding pipeline by Dennis Snell (@dmsnell). |
| 7 | * |
| 8 | * It enables parsing XML documents with incomplete UTF-8 byte sequences |
| 9 | * without crashing or depending on the mbstring extension. |
| 10 | */ |
| 11 | |
| 12 | /** |
| 13 | * Encode a code point number into the UTF-8 encoding. |
| 14 | * |
| 15 | * This encoder implements the UTF-8 encoding algorithm for converting |
| 16 | * a code point into a byte sequence. If it receives an invalid code |
| 17 | * point it will return the Unicode Replacement Character U+FFFD `�`. |
| 18 | * |
| 19 | * Example: |
| 20 | * |
| 21 | * '� |
| 22 | �' === WP_HTML_Decoder::codepoint_to_utf8_bytes( 0x1f170 ); |
| 23 | * |
| 24 | * // Half of a surrogate pair is an invalid code point. |
| 25 | * '�' === WP_HTML_Decoder::codepoint_to_utf8_bytes( 0xd83c ); |
| 26 | * |
| 27 | * @since 6.6.0 |
| 28 | * |
| 29 | * @see https://www.rfc-editor.org/rfc/rfc3629 For the UTF-8 standard. |
| 30 | * |
| 31 | * @param int $codepoint Which code point to convert. |
| 32 | * @return string Converted code point, or `�` if invalid. |
| 33 | */ |
| 34 | function codepoint_to_utf8_bytes( $codepoint ) { |
| 35 | // Pre-check to ensure a valid code point. |
| 36 | if ( |
| 37 | $codepoint <= 0 || |
| 38 | ( $codepoint >= 0xD800 && $codepoint <= 0xDFFF ) || |
| 39 | $codepoint > 0x10FFFF |
| 40 | ) { |
| 41 | return '�'; |
| 42 | } |
| 43 | |
| 44 | if ( $codepoint <= 0x7F ) { |
| 45 | return chr( $codepoint ); |
| 46 | } |
| 47 | |
| 48 | if ( $codepoint <= 0x7FF ) { |
| 49 | $byte1 = chr( ( 0xC0 | ( ( $codepoint >> 6 ) & 0x1F ) ) ); |
| 50 | $byte2 = chr( $codepoint & 0x3F | 0x80 ); |
| 51 | |
| 52 | return "{$byte1}{$byte2}"; |
| 53 | } |
| 54 | |
| 55 | if ( $codepoint <= 0xFFFF ) { |
| 56 | $byte1 = chr( ( $codepoint >> 12 ) | 0xE0 ); |
| 57 | $byte2 = chr( ( $codepoint >> 6 ) & 0x3F | 0x80 ); |
| 58 | $byte3 = chr( $codepoint & 0x3F | 0x80 ); |
| 59 | |
| 60 | return "{$byte1}{$byte2}{$byte3}"; |
| 61 | } |
| 62 | |
| 63 | // Any values above U+10FFFF are eliminated above in the pre-check. |
| 64 | $byte1 = chr( ( $codepoint >> 18 ) | 0xF0 ); |
| 65 | $byte2 = chr( ( $codepoint >> 12 ) & 0x3F | 0x80 ); |
| 66 | $byte3 = chr( ( $codepoint >> 6 ) & 0x3F | 0x80 ); |
| 67 | $byte4 = chr( $codepoint & 0x3F | 0x80 ); |
| 68 | |
| 69 | return "{$byte1}{$byte2}{$byte3}{$byte4}"; |
| 70 | } |
| 71 |