项目原始demo,不改动
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
Dieses Repo ist archiviert. Du kannst Dateien sehen und es klonen, kannst aber nicht pushen oder Issues/Pull-Requests öffnen.
 
 
 
 

112 Zeilen
3.1 KiB

  1. /**
  2. * @fileoverview Rule to forbid control charactes from regular expressions.
  3. * @author Nicholas C. Zakas
  4. */
  5. "use strict";
  6. const RegExpValidator = require("regexpp").RegExpValidator;
  7. const collector = new class {
  8. constructor() {
  9. this.ecmaVersion = 2018;
  10. this._source = "";
  11. this._controlChars = [];
  12. this._validator = new RegExpValidator(this);
  13. }
  14. onPatternEnter() {
  15. this._controlChars = [];
  16. }
  17. onCharacter(start, end, cp) {
  18. if (cp >= 0x00 &&
  19. cp <= 0x1F &&
  20. (
  21. this._source.codePointAt(start) === cp ||
  22. this._source.slice(start, end).startsWith("\\x") ||
  23. this._source.slice(start, end).startsWith("\\u")
  24. )
  25. ) {
  26. this._controlChars.push(`\\x${`0${cp.toString(16)}`.slice(-2)}`);
  27. }
  28. }
  29. collectControlChars(regexpStr) {
  30. try {
  31. this._source = regexpStr;
  32. this._validator.validatePattern(regexpStr); // Call onCharacter hook
  33. } catch (err) {
  34. // Ignore syntax errors in RegExp.
  35. }
  36. return this._controlChars;
  37. }
  38. }();
  39. //------------------------------------------------------------------------------
  40. // Rule Definition
  41. //------------------------------------------------------------------------------
  42. module.exports = {
  43. meta: {
  44. docs: {
  45. description: "disallow control characters in regular expressions",
  46. category: "Possible Errors",
  47. recommended: true,
  48. url: "https://eslint.org/docs/rules/no-control-regex"
  49. },
  50. schema: [],
  51. messages: {
  52. unexpected: "Unexpected control character(s) in regular expression: {{controlChars}}."
  53. }
  54. },
  55. create(context) {
  56. /**
  57. * Get the regex expression
  58. * @param {ASTNode} node node to evaluate
  59. * @returns {RegExp|null} Regex if found else null
  60. * @private
  61. */
  62. function getRegExpPattern(node) {
  63. if (node.regex) {
  64. return node.regex.pattern;
  65. }
  66. if (typeof node.value === "string" &&
  67. (node.parent.type === "NewExpression" || node.parent.type === "CallExpression") &&
  68. node.parent.callee.type === "Identifier" &&
  69. node.parent.callee.name === "RegExp" &&
  70. node.parent.arguments[0] === node
  71. ) {
  72. return node.value;
  73. }
  74. return null;
  75. }
  76. return {
  77. Literal(node) {
  78. const pattern = getRegExpPattern(node);
  79. if (pattern) {
  80. const controlCharacters = collector.collectControlChars(pattern);
  81. if (controlCharacters.length > 0) {
  82. context.report({
  83. node,
  84. messageId: "unexpected",
  85. data: {
  86. controlChars: controlCharacters.join(", ")
  87. }
  88. });
  89. }
  90. }
  91. }
  92. };
  93. }
  94. };