escape.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. 'use strict';
  2. // Declare internals
  3. const internals = {};
  4. exports.escapeHtml = function (input) {
  5. if (!input) {
  6. return '';
  7. }
  8. let escaped = '';
  9. for (let i = 0; i < input.length; ++i) {
  10. const charCode = input.charCodeAt(i);
  11. if (internals.isSafe(charCode)) {
  12. escaped += input[i];
  13. }
  14. else {
  15. escaped += internals.escapeHtmlChar(charCode);
  16. }
  17. }
  18. return escaped;
  19. };
  20. exports.escapeJson = function (input) {
  21. if (!input) {
  22. return '';
  23. }
  24. const lessThan = 0x3C;
  25. const greaterThan = 0x3E;
  26. const andSymbol = 0x26;
  27. const lineSeperator = 0x2028;
  28. // replace method
  29. let charCode;
  30. return input.replace(/[<>&\u2028\u2029]/g, (match) => {
  31. charCode = match.charCodeAt(0);
  32. if (charCode === lessThan) {
  33. return '\\u003c';
  34. }
  35. if (charCode === greaterThan) {
  36. return '\\u003e';
  37. }
  38. if (charCode === andSymbol) {
  39. return '\\u0026';
  40. }
  41. if (charCode === lineSeperator) {
  42. return '\\u2028';
  43. }
  44. return '\\u2029';
  45. });
  46. };
  47. internals.escapeHtmlChar = function (charCode) {
  48. const namedEscape = internals.namedHtml[charCode];
  49. if (typeof namedEscape !== 'undefined') {
  50. return namedEscape;
  51. }
  52. if (charCode >= 256) {
  53. return '&#' + charCode + ';';
  54. }
  55. const hexValue = Buffer.from(String.fromCharCode(charCode), 'ascii').toString('hex');
  56. return `&#x${hexValue};`;
  57. };
  58. internals.isSafe = function (charCode) {
  59. return (typeof internals.safeCharCodes[charCode] !== 'undefined');
  60. };
  61. internals.namedHtml = {
  62. '38': '&amp;',
  63. '60': '&lt;',
  64. '62': '&gt;',
  65. '34': '&quot;',
  66. '160': '&nbsp;',
  67. '162': '&cent;',
  68. '163': '&pound;',
  69. '164': '&curren;',
  70. '169': '&copy;',
  71. '174': '&reg;'
  72. };
  73. internals.safeCharCodes = (function () {
  74. const safe = {};
  75. for (let i = 32; i < 123; ++i) {
  76. if ((i >= 97) || // a-z
  77. (i >= 65 && i <= 90) || // A-Z
  78. (i >= 48 && i <= 57) || // 0-9
  79. i === 32 || // space
  80. i === 46 || // .
  81. i === 44 || // ,
  82. i === 45 || // -
  83. i === 58 || // :
  84. i === 95) { // _
  85. safe[i] = null;
  86. }
  87. }
  88. return safe;
  89. }());