项目原始demo,不改动
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
このリポジトリはアーカイブされています。 ファイルの閲覧とクローンは可能ですが、プッシュや、課題・プルリクエストのオープンはできません。
 
 
 
 

125 行
4.0 KiB

  1. /**
  2. * @fileoverview Validate strings passed to the RegExp constructor
  3. * @author Michael Ficarra
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Requirements
  8. //------------------------------------------------------------------------------
  9. const RegExpValidator = require("regexpp").RegExpValidator;
  10. const validator = new RegExpValidator({ ecmaVersion: 2018 });
  11. const validFlags = /[gimuys]/g;
  12. const undefined1 = void 0;
  13. //------------------------------------------------------------------------------
  14. // Rule Definition
  15. //------------------------------------------------------------------------------
  16. module.exports = {
  17. meta: {
  18. docs: {
  19. description: "disallow invalid regular expression strings in `RegExp` constructors",
  20. category: "Possible Errors",
  21. recommended: true,
  22. url: "https://eslint.org/docs/rules/no-invalid-regexp"
  23. },
  24. schema: [{
  25. type: "object",
  26. properties: {
  27. allowConstructorFlags: {
  28. type: "array",
  29. items: {
  30. type: "string"
  31. }
  32. }
  33. },
  34. additionalProperties: false
  35. }]
  36. },
  37. create(context) {
  38. const options = context.options[0];
  39. let allowedFlags = null;
  40. if (options && options.allowConstructorFlags) {
  41. const temp = options.allowConstructorFlags.join("").replace(validFlags, "");
  42. if (temp) {
  43. allowedFlags = new RegExp(`[${temp}]`, "gi");
  44. }
  45. }
  46. /**
  47. * Check if node is a string
  48. * @param {ASTNode} node node to evaluate
  49. * @returns {boolean} True if its a string
  50. * @private
  51. */
  52. function isString(node) {
  53. return node && node.type === "Literal" && typeof node.value === "string";
  54. }
  55. /**
  56. * Check syntax error in a given pattern.
  57. * @param {string} pattern The RegExp pattern to validate.
  58. * @param {boolean} uFlag The Unicode flag.
  59. * @returns {string|null} The syntax error.
  60. */
  61. function validateRegExpPattern(pattern, uFlag) {
  62. try {
  63. validator.validatePattern(pattern, undefined1, undefined1, uFlag);
  64. return null;
  65. } catch (err) {
  66. return err.message;
  67. }
  68. }
  69. /**
  70. * Check syntax error in a given flags.
  71. * @param {string} flags The RegExp flags to validate.
  72. * @returns {string|null} The syntax error.
  73. */
  74. function validateRegExpFlags(flags) {
  75. try {
  76. validator.validateFlags(flags);
  77. return null;
  78. } catch (err) {
  79. return `Invalid flags supplied to RegExp constructor '${flags}'`;
  80. }
  81. }
  82. return {
  83. "CallExpression, NewExpression"(node) {
  84. if (node.callee.type !== "Identifier" || node.callee.name !== "RegExp" || !isString(node.arguments[0])) {
  85. return;
  86. }
  87. const pattern = node.arguments[0].value;
  88. let flags = isString(node.arguments[1]) ? node.arguments[1].value : "";
  89. if (allowedFlags) {
  90. flags = flags.replace(allowedFlags, "");
  91. }
  92. // If flags are unknown, check both are errored or not.
  93. const message = validateRegExpFlags(flags) || (
  94. flags
  95. ? validateRegExpPattern(pattern, flags.indexOf("u") !== -1)
  96. : validateRegExpPattern(pattern, true) && validateRegExpPattern(pattern, false)
  97. );
  98. if (message) {
  99. context.report({
  100. node,
  101. message: "{{message}}.",
  102. data: { message }
  103. });
  104. }
  105. }
  106. };
  107. }
  108. };