/** | |
* Turn the number (in string form as either hexa- or plain decimal) coming from | |
* a numeric character reference into a character. | |
* | |
* Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes | |
* non-characters and control characters safe. | |
* | |
* @param {string} value | |
* Value to decode. | |
* @param {number} base | |
* Numeric base. | |
* @returns {string} | |
* Character. | |
*/ | |
export function decodeNumericCharacterReference(value, base) { | |
const code = Number.parseInt(value, base) | |
if ( | |
// C0 except for HT, LF, FF, CR, space. | |
code < 9 || | |
code === 11 || | |
(code > 13 && code < 32) || | |
// Control character (DEL) of C0, and C1 controls. | |
(code > 126 && code < 160) || | |
// Lone high surrogates and low surrogates. | |
(code > 55295 && code < 57344) || | |
// Noncharacters. | |
(code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || | |
(code & 65535) === 65535 || | |
(code & 65535) === 65534 /* eslint-enable no-bitwise */ || | |
// Out of range | |
code > 1114111 | |
) { | |
return '\uFFFD' | |
} | |
return String.fromCharCode(code) | |
} | |