index.js 1.0 KB

1234567891011121314151617181920212223242526272829303132
  1. /**
  2. * Turn the number (in string form as either hexa- or plain decimal) coming from
  3. * a numeric character reference into a character.
  4. *
  5. * Sort of like `String.fromCodePoint(Number.parseInt(value, base))`, but makes
  6. * non-characters and control characters safe.
  7. *
  8. * @param {string} value
  9. * Value to decode.
  10. * @param {number} base
  11. * Numeric base.
  12. * @returns {string}
  13. * Character.
  14. */
  15. export function decodeNumericCharacterReference(value, base) {
  16. const code = Number.parseInt(value, base);
  17. if (
  18. // C0 except for HT, LF, FF, CR, space.
  19. code < 9 || code === 11 || code > 13 && code < 32 ||
  20. // Control character (DEL) of C0, and C1 controls.
  21. code > 126 && code < 160 ||
  22. // Lone high surrogates and low surrogates.
  23. code > 55_295 && code < 57_344 ||
  24. // Noncharacters.
  25. code > 64_975 && code < 65_008 || /* eslint-disable no-bitwise */
  26. (code & 65_535) === 65_535 || (code & 65_535) === 65_534 || /* eslint-enable no-bitwise */
  27. // Out of range
  28. code > 1_114_111) {
  29. return "\uFFFD";
  30. }
  31. return String.fromCodePoint(code);
  32. }