sjs.js 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. 'use strict';
  2. /**
  3. * Escape JavaScript to \xHH format
  4. */
  5. // escape \x00-\x7f
  6. // except 0-9,A-Z,a-z(\x2f-\x3a \x40-\x5b \x60-\x7b)
  7. // eslint-disable-next-line
  8. const MATCH_VULNERABLE_REGEXP = /[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]/;
  9. // eslint-enable-next-line
  10. const BASIC_ALPHABETS = new Set('abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''));
  11. const map = {
  12. '\t': '\\t',
  13. '\n': '\\n',
  14. '\r': '\\r',
  15. };
  16. function escapeJavaScript(string) {
  17. const str = '' + string;
  18. const match = MATCH_VULNERABLE_REGEXP.exec(str);
  19. if (!match) {
  20. return str;
  21. }
  22. let res = '';
  23. let index = 0;
  24. let lastIndex = 0;
  25. let ascii;
  26. for (index = match.index; index < str.length; index++) {
  27. ascii = str[index];
  28. if (BASIC_ALPHABETS.has(ascii)) {
  29. continue;
  30. } else {
  31. if (map[ascii] === undefined) {
  32. const code = ascii.charCodeAt(0);
  33. if (code > 127) {
  34. continue;
  35. } else {
  36. map[ascii] = '\\x' + code.toString(16);
  37. }
  38. }
  39. }
  40. if (lastIndex !== index) {
  41. res += str.substring(lastIndex, index);
  42. }
  43. lastIndex = index + 1;
  44. res += map[ascii];
  45. }
  46. return lastIndex !== index ? res + str.substring(lastIndex, index) : res;
  47. }
  48. module.exports = escapeJavaScript;