Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: no-warning-comments rule escapes special RegEx characters in terms #16090

Merged
merged 7 commits into from Jul 9, 2022

Conversation

lachlanhunt
Copy link
Contributor

@lachlanhunt lachlanhunt commented Jul 3, 2022

Prerequisites checklist

What is the purpose of this pull request? (put an "X" next to an item)

[ ] Documentation update
[x] Bug fix (template)
[ ] New rule (template)
[ ] Changes an existing rule (template)
[ ] Add autofix to a rule
[ ] Add a CLI option
[ ] Add something to the core
[ ] Other, please explain:

Tell us about your environment:

  • ESLint Version: 8.19.0
  • Node Version: v16.15.1
  • npm Version: 8.11.0

What parser (default, @babel/eslint-parser, @typescript-eslint/parser, etc.) are you using?

Please show your full configuration:

Configuration
    rules: {
        "no-warning-comments": ["error", {
            terms: ["[TODO]"],
            location: "anywhere"
        }]
    },

What did you do? Please include the actual source code causing the issue.

Regular expression characters in the terms property are inadvertently being treated as actual regular expression symbols when the location is "anywhere".

// Any comment containing a lone letter like T, O or D will match that regex.

What did you expect to happen?

The terms property is intended to be treated as a string literal.

What actually happened? Please include the actual, raw output from ESLint.

Unexpected '[TODO]' comment: 'Any comment containing a lone letter...'.eslint no-warning-comments

This bug appears to have been inadvertently introduced by pull request #10381 where they were attempting to fix a different bug related to location "anywhere", and accidentally allowed the unescaped term to be injected into the RegExp.

What changes did you make? (Give an overview)

  • I simplified and optimised the conversion of terms to regular expressions based on the specified location.
  • I fixed a test case that appears to have been written to check correct regex escaping of the terms, but which missed the actual bug.
  • I added new tests to ensure edge cases weren't missed by my changes.

Is there anything you'd like reviewers to focus on?

N/A

@eslint-github-bot eslint-github-bot bot added the triage An ESLint team member will look at this issue soon label Jul 3, 2022
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Jul 3, 2022

CLA Signed

The committers listed above are authorized under a signed CLA.

@eslint-github-bot
Copy link

eslint-github-bot bot commented Jul 3, 2022

Hi @lachlanhunt!, thanks for the Pull Request

The pull request title isn't properly formatted. We ask that you update the message to match this format, as we use it to generate changelogs and automate releases.

  • The commit message tag wasn't recognized. Did you mean "docs", "fix", or "feat"?
  • There should be a space following the initial tag and colon, for example 'feat: Message'.
  • The first letter of the tag should be in lowercase
  • The length of the commit message must be less than or equal to 72

To Fix: You can fix this problem by clicking 'Edit' next to the pull request title at the top of this page.

Read more about contributing to ESLint here

@netlify
Copy link

netlify bot commented Jul 3, 2022

Deploy Preview for docs-eslint canceled.

Name Link
🔨 Latest commit 6315060
🔍 Latest deploy log https://app.netlify.com/sites/docs-eslint/deploys/62c97f5c00280f00086c1db1

@lachlanhunt lachlanhunt changed the title The no-warning-comments rule incorrectly handled special RegExp characters within terms fix: no-warning-comments rule correctly escapes special RegExp characters within terms Jul 3, 2022
@eslint-github-bot
Copy link

eslint-github-bot bot commented Jul 3, 2022

Hi @lachlanhunt!, thanks for the Pull Request

The pull request title isn't properly formatted. We ask that you update the message to match this format, as we use it to generate changelogs and automate releases.

  • The length of the commit message must be less than or equal to 72

To Fix: You can fix this problem by clicking 'Edit' next to the pull request title at the top of this page.

Read more about contributing to ESLint here

@lachlanhunt lachlanhunt changed the title fix: no-warning-comments rule correctly escapes special RegExp characters within terms fix: no-warning-comments rule escapes special RegEx characters in terms Jul 3, 2022
@eslint-github-bot eslint-github-bot bot added the bug ESLint is working incorrectly label Jul 3, 2022
@mdjermanovic mdjermanovic added rule Relates to ESLint's core rules accepted There is consensus among the team that this change meets the criteria for inclusion and removed triage An ESLint team member will look at this issue soon labels Jul 3, 2022
@mdjermanovic
Copy link
Member

mdjermanovic commented Jul 3, 2022

Thanks for the PR! I can reproduce this bug in the playground.

lib/rules/no-warning-comments.js Outdated Show resolved Hide resolved
lib/rules/no-warning-comments.js Outdated Show resolved Hide resolved
lib/rules/no-warning-comments.js Outdated Show resolved Hide resolved
@mdjermanovic
Copy link
Member

mdjermanovic commented Jul 3, 2022

This bug appears to have been inadvertently introduced by pull request #10381 where they were attempting to fix a different bug related to location "anywhere", and accidentally allowed the unescaped term to be injected into the RegExp.

This change will basically undo the code change from #10381, which seems fine to me as I don't see what exactly was fixed by #10381. To doublecheck, I tried the version from 640bf07, and when I revert the code changes all tests added in 640bf07 are still passing.

@lachlanhunt lachlanhunt force-pushed the no-warning-comments-matching branch 4 times, most recently from d819fa7 to 8f4eb74 Compare Jul 4, 2022
@lachlanhunt
Copy link
Contributor Author

lachlanhunt commented Jul 4, 2022

I've addressed all comments so far, and rebased and squashed all the commits down to one.

@lachlanhunt lachlanhunt force-pushed the no-warning-comments-matching branch from 8f4eb74 to 132458e Compare Jul 4, 2022
@lachlanhunt lachlanhunt force-pushed the no-warning-comments-matching branch from 132458e to b3de940 Compare Jul 4, 2022
Copy link
Member

@mdjermanovic mdjermanovic left a comment

The code changes and new tests look great, I have just two small suggestions.

lib/rules/no-warning-comments.js Outdated Show resolved Hide resolved
tests/lib/rules/no-warning-comments.js Outdated Show resolved Hide resolved
@mdjermanovic
Copy link
Member

mdjermanovic commented Jul 5, 2022

I've addressed all comments so far, and rebased and squashed all the commits down to one.

No need to squash. It's easier to track changes when new commits are added on top of existing ones, and we'll squash the commits in the end anyway.

@mdjermanovic
Copy link
Member

mdjermanovic commented Jul 8, 2022

Looks good, but the last commit 2a2569a introduced some changes that cause linting to fail (in particular, parentheses around single params of arrow functions and trailing commas). Can you fix that? You can see the lint errors in the "Files changed" tab https://github.com/eslint/eslint/pull/16090/files or when you run npm run lint locally.

@lachlanhunt
Copy link
Contributor Author

lachlanhunt commented Jul 8, 2022

the last commit 2a2569a introduced some changes that cause linting to fail

oh, oops. I did the edit quickly on a different computer, and forgot to disable editor.formatOnSave for this repo. Fixed it.

@mdjermanovic
Copy link
Member

mdjermanovic commented Jul 8, 2022

It seems that this change significantly affects the performance of this rule. I enabled the rule with its default settings in our config (added "no-warning-comments": "error" here), set TIMING=all, and ran npm run lint.

Before this change
Rule                                          | Time (ms) | Relative
:---------------------------------------------|----------:|--------:
indent                                        |  6352.639 |    20.4%
jsdoc/check-line-alignment                    |   975.044 |     3.1%
jsdoc/valid-types                             |   909.344 |     2.9%
node/no-missing-require                       |   869.871 |     2.8%
node/no-extraneous-require                    |   805.183 |     2.6%
jsdoc/check-types                             |   789.524 |     2.5%
jsdoc/check-tag-names                         |   662.268 |     2.1%
node/no-unpublished-require                   |   638.177 |     2.1%
jsdoc/check-values                            |   621.869 |     2.0%
eslint-plugin/no-identical-tests              |   591.532 |     1.9%
jsdoc/empty-tags                              |   525.480 |     1.7%
jsdoc/check-syntax                            |   519.867 |     1.7%
jsdoc/tag-lines                               |   519.095 |     1.7%
jsdoc/check-access                            |   513.507 |     1.7%
jsdoc/newline-after-description               |   510.159 |     1.6%
jsdoc/check-alignment                         |   509.707 |     1.6%
jsdoc/require-property-name                   |   507.660 |     1.6%
jsdoc/require-asterisk-prefix                 |   506.206 |     1.6%
jsdoc/check-property-names                    |   505.975 |     1.6%
jsdoc/require-hyphen-before-param-description |   504.332 |     1.6%
jsdoc/require-property-type                   |   500.774 |     1.6%
jsdoc/require-property-description            |   490.437 |     1.6%
jsdoc/multiline-blocks                        |   490.156 |     1.6%
jsdoc/require-property                        |   486.778 |     1.6%
jsdoc/no-multi-asterisks                      |   483.985 |     1.6%
max-len                                       |   381.558 |     1.2%
node/no-restricted-require                    |   354.761 |     1.1%
comma-style                                   |   346.721 |     1.1%
node/no-unsupported-features/es-syntax        |   211.703 |     0.7%
no-loss-of-precision                          |   206.739 |     0.7%
object-curly-newline                          |   173.203 |     0.6%
jsdoc/require-param                           |   167.193 |     0.5%
jsdoc/require-description                     |   164.036 |     0.5%
comma-spacing                                 |   163.706 |     0.5%
padding-line-between-statements               |   160.630 |     0.5%
no-trailing-spaces                            |   157.362 |     0.5%
keyword-spacing                               |   156.340 |     0.5%
object-shorthand                              |   150.121 |     0.5%
node/no-deprecated-api                        |   143.568 |     0.5%
jsdoc/check-param-names                       |   141.752 |     0.5%
no-dupe-keys                                  |   140.015 |     0.4%
comma-dangle                                  |   138.375 |     0.4%
camelcase                                     |   135.330 |     0.4%
quote-props                                   |   135.158 |     0.4%
internal-rules/multiline-comment-style        |   128.441 |     0.4%
object-curly-spacing                          |   125.831 |     0.4%
space-in-parens                               |   116.378 |     0.4%
space-infix-ops                               |   115.056 |     0.4%
no-useless-return                             |   111.408 |     0.4%
no-unused-vars                                |   110.321 |     0.4%
node/no-unsupported-features/es-builtins      |   107.686 |     0.3%
key-spacing                                   |   106.940 |     0.3%
jsdoc/require-returns-check                   |   105.508 |     0.3%
jsdoc/require-returns                         |   104.415 |     0.3%
jsdoc/require-throws                          |   104.306 |     0.3%
no-whitespace-before-property                 |   101.987 |     0.3%
function-paren-newline                        |   100.914 |     0.3%
no-alert                                      |    90.627 |     0.3%
no-multi-spaces                               |    90.122 |     0.3%
jsdoc/require-yields-check                    |    89.557 |     0.3%
no-redeclare                                  |    88.526 |     0.3%
no-script-url                                 |    84.720 |     0.3%
lines-around-comment                          |    84.244 |     0.3%
func-call-spacing                             |    83.626 |     0.3%
no-useless-escape                             |    83.594 |     0.3%
no-multiple-empty-lines                       |    82.142 |     0.3%
jsdoc/require-param-description               |    79.337 |     0.3%
jsdoc/require-returns-type                    |    78.673 |     0.3%
jsdoc/implements-on-classes                   |    78.616 |     0.3%
jsdoc/require-returns-description             |    78.034 |     0.3%
no-underscore-dangle                          |    77.460 |     0.2%
jsdoc/require-param-name                      |    75.470 |     0.2%
grouped-accessor-pairs                        |    75.106 |     0.2%
array-bracket-spacing                         |    74.207 |     0.2%
max-statements-per-line                       |    73.911 |     0.2%
semi-spacing                                  |    71.707 |     0.2%
jsdoc/require-param-type                      |    69.662 |     0.2%
no-control-regex                              |    69.594 |     0.2%
operator-linebreak                            |    68.795 |     0.2%
no-regex-spaces                               |    67.992 |     0.2%
no-unexpected-multiline                       |    66.553 |     0.2%
no-unmodified-loop-condition                  |    63.089 |     0.2%
unicorn/prefer-array-flat                     |    62.759 |     0.2%
no-octal-escape                               |    57.565 |     0.2%
no-mixed-spaces-and-tabs                      |    54.179 |     0.2%
node/no-unpublished-import                    |    50.636 |     0.2%
consistent-return                             |    48.871 |     0.2%
spaced-comment                                |    47.538 |     0.2%
new-cap                                       |    47.240 |     0.2%
node/no-unsupported-features/node-builtins    |    46.811 |     0.2%
no-misleading-character-class                 |    46.060 |     0.1%
no-tabs                                       |    45.842 |     0.1%
computed-property-spacing                     |    45.634 |     0.1%
eslint-plugin/no-missing-message-ids          |    45.179 |     0.1%
no-multi-str                                  |    44.156 |     0.1%
quotes                                        |    43.988 |     0.1%
object-property-newline                       |    43.432 |     0.1%
function-call-argument-newline                |    41.555 |     0.1%
no-use-before-define                          |    40.850 |     0.1%
jsdoc/no-bad-blocks                           |    40.047 |     0.1%
semi-style                                    |    40.040 |     0.1%
no-unsafe-optional-chaining                   |    39.942 |     0.1%
block-spacing                                 |    38.386 |     0.1%
constructor-super                             |    38.243 |     0.1%
brace-style                                   |    37.952 |     0.1%
prefer-template                               |    37.795 |     0.1%
no-restricted-properties                      |    37.005 |     0.1%
array-callback-return                         |    36.693 |     0.1%
dot-location                                  |    36.561 |     0.1%
no-undef-init                                 |    36.382 |     0.1%
semi                                          |    36.105 |     0.1%
no-nonoctal-decimal-escape                    |    36.029 |     0.1%
no-this-before-super                          |    35.667 |     0.1%
no-floating-decimal                           |    35.127 |     0.1%
no-unreachable                                |    35.053 |     0.1%
jsdoc/require-jsdoc                           |    34.993 |     0.1%
no-invalid-this                               |    33.733 |     0.1%
node/no-extraneous-import                     |    32.503 |     0.1%
no-extend-native                              |    32.419 |     0.1%
no-warning-comments                           |    32.399 |     0.1%
node/no-mixed-requires                        |    30.174 |     0.1%
no-eval                                       |    29.866 |     0.1%
no-lone-blocks                                |    29.504 |     0.1%
no-shadow                                     |    29.115 |     0.1%
space-before-blocks                           |    28.450 |     0.1%
no-unreachable-loop                           |    27.933 |     0.1%
node/handle-callback-err                      |    27.917 |     0.1%
eslint-plugin/prefer-output-null              |    27.262 |     0.1%
no-unused-expressions                         |    26.265 |     0.1%
arrow-spacing                                 |    25.585 |     0.1%
no-octal                                      |    25.017 |     0.1%
no-useless-computed-key                       |    24.398 |     0.1%
no-useless-backreference                      |    24.391 |     0.1%
node/callback-return                          |    23.517 |     0.1%
no-constant-binary-expression                 |    23.126 |     0.1%
no-param-reassign                             |    22.996 |     0.1%
space-before-function-paren                   |    22.642 |     0.1%
no-self-compare                               |    22.489 |     0.1%
no-setter-return                              |    22.409 |     0.1%
getter-return                                 |    22.399 |     0.1%
no-const-assign                               |    22.243 |     0.1%
no-irregular-whitespace                       |    22.122 |     0.1%
node/shebang                                  |    21.764 |     0.1%
strict                                        |    21.709 |     0.1%
eslint-plugin/test-case-property-ordering     |    20.623 |     0.1%
space-unary-ops                               |    20.520 |     0.1%
eslint-comments/disable-enable-pair           |    19.932 |     0.1%
prefer-promise-reject-errors                  |    19.218 |     0.1%
node/no-unpublished-bin                       |    19.069 |     0.1%
no-implied-eval                               |    19.032 |     0.1%
eslint-plugin/no-unused-message-ids           |    18.803 |     0.1%
class-methods-use-this                        |    18.413 |     0.1%
curly                                         |    18.379 |     0.1%
no-useless-call                               |    18.285 |     0.1%
no-dupe-else-if                               |    18.026 |     0.1%
eslint-plugin/no-only-tests                   |    17.549 |     0.1%
dot-notation                                  |    16.928 |     0.1%
node/no-path-concat                           |    16.882 |     0.1%
prefer-const                                  |    16.829 |     0.1%
eslint-plugin/prefer-replace-text             |    16.626 |     0.1%
no-constructor-return                         |    16.438 |     0.1%
prefer-exponentiation-operator                |    16.414 |     0.1%
no-constant-condition                         |    16.315 |     0.1%
unicorn/prefer-includes                       |    16.271 |     0.1%
no-prototype-builtins                         |    16.220 |     0.1%
prefer-spread                                 |    16.205 |     0.1%
no-shadow-restricted-names                    |    16.000 |     0.1%
func-style                                    |    15.590 |     0.1%
no-iterator                                   |    15.292 |     0.0%
eslint-plugin/require-meta-docs-url           |    15.229 |     0.0%
arrow-body-style                              |    14.774 |     0.0%
eslint-plugin/fixer-return                    |    14.327 |     0.0%
prefer-numeric-literals                       |    14.068 |     0.0%
wrap-iife                                     |    13.726 |     0.0%
no-extra-boolean-cast                         |    13.533 |     0.0%
no-extra-bind                                 |    13.411 |     0.0%
prefer-arrow-callback                         |    13.403 |     0.0%
eslint-plugin/prefer-message-ids              |    13.105 |     0.0%
no-caller                                     |    12.731 |     0.0%
no-loop-func                                  |    12.693 |     0.0%
no-obj-calls                                  |    12.052 |     0.0%
unicorn/prefer-set-has                        |    11.419 |     0.0%
no-invalid-regexp                             |    11.398 |     0.0%
no-unsafe-finally                             |    11.393 |     0.0%
template-curly-spacing                        |    11.179 |     0.0%
eslint-plugin/test-case-shorthand-strings     |    11.130 |     0.0%
no-proto                                      |    11.053 |     0.0%
use-isnan                                     |    10.909 |     0.0%
eslint-plugin/report-message-format           |    10.710 |     0.0%
no-return-assign                              |    10.028 |     0.0%
no-inner-declarations                         |     9.640 |     0.0%
unicorn/prefer-array-find                     |     9.591 |     0.0%
yoda                                          |     9.568 |     0.0%
prefer-regex-literals                         |     9.539 |     0.0%
eslint-comments/require-description           |     9.429 |     0.0%
no-dupe-args                                  |     9.364 |     0.0%
no-self-assign                                |     9.039 |     0.0%
eslint-plugin/require-meta-fixable            |     8.973 |     0.0%
no-array-constructor                          |     8.774 |     0.0%
eslint-plugin/require-meta-schema             |     8.714 |     0.0%
no-fallthrough                                |     8.660 |     0.0%
no-sparse-arrays                              |     8.549 |     0.0%
eslint-plugin/no-useless-token-range          |     8.451 |     0.0%
eslint-plugin/prefer-placeholders             |     8.367 |     0.0%
unicorn/prefer-array-some                     |     8.353 |     0.0%
eqeqeq                                        |     8.255 |     0.0%
no-undefined                                  |     8.185 |     0.0%
no-func-assign                                |     7.864 |     0.0%
eslint-comments/no-unlimited-disable          |     7.463 |     0.0%
eslint-plugin/no-deprecated-context-methods   |     7.198 |     0.0%
eslint-plugin/consistent-output               |     7.103 |     0.0%
default-param-last                            |     7.087 |     0.0%
eslint-plugin/no-missing-placeholders         |     7.026 |     0.0%
one-var-declaration-per-line                  |     6.799 |     0.0%
no-console                                    |     6.586 |     0.0%
prefer-rest-params                            |     6.382 |     0.0%
generator-star-spacing                        |     6.379 |     0.0%
no-useless-concat                             |     6.187 |     0.0%
valid-typeof                                  |     6.146 |     0.0%
no-compare-neg-zero                           |     6.129 |     0.0%
eslint-plugin/require-meta-has-suggestions    |     6.124 |     0.0%
no-empty                                      |     6.109 |     0.0%
no-new-object                                 |     5.975 |     0.0%
no-global-assign                              |     5.973 |     0.0%
eslint-plugin/no-unused-placeholders          |     5.860 |     0.0%
node/no-exports-assign                        |     5.757 |     0.0%
no-else-return                                |     5.676 |     0.0%
eslint-plugin/require-meta-docs-description   |     5.663 |     0.0%
no-restricted-syntax                          |     5.636 |     0.0%
arrow-parens                                  |     4.924 |     0.0%
no-confusing-arrow                            |     4.869 |     0.0%
require-unicode-regexp                        |     4.868 |     0.0%
node/no-missing-import                        |     4.859 |     0.0%
eslint-plugin/no-deprecated-report-api        |     4.849 |     0.0%
require-yield                                 |     4.667 |     0.0%
no-unsafe-negation                            |     4.666 |     0.0%
no-var                                        |     4.615 |     0.0%
no-cond-assign                                |     4.419 |     0.0%
no-dupe-class-members                         |     4.126 |     0.0%
no-duplicate-case                             |     4.087 |     0.0%
eol-last                                      |     3.964 |     0.0%
template-tag-spacing                          |     3.927 |     0.0%
internal-rules/no-invalid-meta                |     3.892 |     0.0%
eslint-comments/no-aggregating-enable         |     3.758 |     0.0%
radix                                         |     3.207 |     0.0%
yield-star-spacing                            |     3.118 |     0.0%
no-useless-rename                             |     2.989 |     0.0%
operator-assignment                           |     2.913 |     0.0%
switch-colon-spacing                          |     2.753 |     0.0%
new-parens                                    |     2.672 |     0.0%
unicorn/prefer-string-starts-ends-with        |     2.621 |     0.0%
no-new-wrappers                               |     2.560 |     0.0%
no-sequences                                  |     2.475 |     0.0%
eslint-plugin/require-meta-type               |     2.208 |     0.0%
unicorn/prefer-array-index-of                 |     2.105 |     0.0%
no-extra-semi                                 |     2.052 |     0.0%
no-unneeded-ternary                           |     1.991 |     0.0%
default-case                                  |     1.956 |     0.0%
no-new-symbol                                 |     1.913 |     0.0%
symbol-description                            |     1.911 |     0.0%
no-new-func                                   |     1.884 |     0.0%
unicode-bom                                   |     1.831 |     0.0%
eslint-comments/no-duplicate-disable          |     1.694 |     0.0%
no-empty-character-class                      |     1.671 |     0.0%
unicorn/prefer-array-flat-map                 |     1.657 |     0.0%
rest-spread-spacing                           |     1.649 |     0.0%
no-labels                                     |     1.507 |     0.0%
node/no-new-require                           |     1.468 |     0.0%
no-delete-var                                 |     1.465 |     0.0%
unicorn/prefer-string-slice                   |     1.393 |     0.0%
eslint-comments/no-unused-enable              |     1.372 |     0.0%
no-empty-pattern                              |     1.305 |     0.0%
unicorn/prefer-string-trim-start-end          |     1.258 |     0.0%
no-undef                                      |     1.211 |     0.0%
for-direction                                 |     1.165 |     0.0%
no-case-declarations                          |     1.090 |     0.0%
eslint-plugin/prefer-object-rule              |     1.085 |     0.0%
no-throw-literal                              |     1.030 |     0.0%
no-nested-ternary                             |     1.017 |     0.0%
no-ex-assign                                  |     0.939 |     0.0%
sort-keys                                     |     0.920 |     0.0%
no-useless-constructor                        |     0.894 |     0.0%
no-class-assign                               |     0.853 |     0.0%
no-unused-labels                              |     0.851 |     0.0%
no-new                                        |     0.758 |     0.0%
no-useless-catch                              |     0.638 |     0.0%
default-case-last                             |     0.555 |     0.0%
no-import-assign                              |     0.504 |     0.0%
no-label-var                                  |     0.488 |     0.0%
no-with                                       |     0.463 |     0.0%
guard-for-in                                  |     0.445 |     0.0%
no-debugger                                   |     0.412 |     0.0%
no-async-promise-executor                     |     0.406 |     0.0%
node/process-exit-as-throw                    |     0.285 |     0.0%
eslint-comments/no-unused-disable             |     0.238 |     0.0%
After this change
Rule                                          | Time (ms) | Relative
:---------------------------------------------|----------:|--------:
indent                                        |  6361.793 |    20.0%
jsdoc/check-line-alignment                    |   983.779 |     3.1%
jsdoc/valid-types                             |   916.307 |     2.9%
node/no-missing-require                       |   862.846 |     2.7%
node/no-extraneous-require                    |   800.417 |     2.5%
jsdoc/check-types                             |   779.598 |     2.5%
jsdoc/check-tag-names                         |   661.369 |     2.1%
jsdoc/check-values                            |   645.977 |     2.0%
node/no-unpublished-require                   |   628.997 |     2.0%
eslint-plugin/no-identical-tests              |   598.169 |     1.9%
jsdoc/newline-after-description               |   545.069 |     1.7%
jsdoc/check-syntax                            |   530.523 |     1.7%
jsdoc/require-hyphen-before-param-description |   523.219 |     1.6%
jsdoc/check-alignment                         |   522.667 |     1.6%
jsdoc/require-property-description            |   522.041 |     1.6%
jsdoc/check-property-names                    |   520.463 |     1.6%
jsdoc/empty-tags                              |   516.517 |     1.6%
jsdoc/check-access                            |   515.754 |     1.6%
jsdoc/tag-lines                               |   512.492 |     1.6%
jsdoc/require-asterisk-prefix                 |   507.888 |     1.6%
jsdoc/require-property-type                   |   493.515 |     1.6%
jsdoc/require-property-name                   |   492.234 |     1.5%
jsdoc/no-multi-asterisks                      |   492.160 |     1.5%
jsdoc/multiline-blocks                        |   488.386 |     1.5%
jsdoc/require-property                        |   482.232 |     1.5%
max-len                                       |   383.157 |     1.2%
node/no-restricted-require                    |   357.475 |     1.1%
comma-style                                   |   357.046 |     1.1%
no-warning-comments                           |   341.815 |     1.1%
node/no-unsupported-features/es-syntax        |   224.696 |     0.7%
no-loss-of-precision                          |   209.543 |     0.7%
padding-line-between-statements               |   181.891 |     0.6%
object-curly-newline                          |   176.966 |     0.6%
jsdoc/require-param                           |   164.314 |     0.5%
keyword-spacing                               |   162.936 |     0.5%
comma-spacing                                 |   159.067 |     0.5%
no-trailing-spaces                            |   158.947 |     0.5%
camelcase                                     |   157.893 |     0.5%
comma-dangle                                  |   157.420 |     0.5%
no-dupe-keys                                  |   154.671 |     0.5%
jsdoc/require-description                     |   152.927 |     0.5%
jsdoc/check-param-names                       |   147.233 |     0.5%
object-shorthand                              |   145.473 |     0.5%
node/no-deprecated-api                        |   143.114 |     0.5%
space-in-parens                               |   135.590 |     0.4%
quote-props                                   |   133.988 |     0.4%
object-curly-spacing                          |   132.066 |     0.4%
internal-rules/multiline-comment-style        |   123.361 |     0.4%
no-useless-return                             |   121.644 |     0.4%
space-infix-ops                               |   116.126 |     0.4%
key-spacing                                   |   114.970 |     0.4%
no-multi-spaces                               |   114.537 |     0.4%
function-paren-newline                        |   108.879 |     0.3%
jsdoc/require-returns                         |   108.806 |     0.3%
node/no-unsupported-features/es-builtins      |   108.581 |     0.3%
jsdoc/require-throws                          |   108.362 |     0.3%
no-whitespace-before-property                 |   101.495 |     0.3%
jsdoc/require-returns-check                   |    95.679 |     0.3%
func-call-spacing                             |    92.031 |     0.3%
jsdoc/implements-on-classes                   |    90.314 |     0.3%
no-script-url                                 |    90.231 |     0.3%
no-alert                                      |    90.210 |     0.3%
no-unused-vars                                |    87.138 |     0.3%
jsdoc/require-yields-check                    |    86.336 |     0.3%
no-multiple-empty-lines                       |    83.569 |     0.3%
no-redeclare                                  |    83.563 |     0.3%
semi-spacing                                  |    83.069 |     0.3%
no-underscore-dangle                          |    79.693 |     0.3%
jsdoc/require-param-description               |    79.041 |     0.2%
lines-around-comment                          |    78.939 |     0.2%
jsdoc/require-returns-description             |    77.330 |     0.2%
max-statements-per-line                       |    76.897 |     0.2%
operator-linebreak                            |    75.982 |     0.2%
no-useless-escape                             |    75.906 |     0.2%
jsdoc/require-returns-type                    |    75.137 |     0.2%
jsdoc/require-param-name                      |    72.451 |     0.2%
array-bracket-spacing                         |    71.107 |     0.2%
no-regex-spaces                               |    69.271 |     0.2%
no-unexpected-multiline                       |    68.916 |     0.2%
no-control-regex                              |    67.179 |     0.2%
grouped-accessor-pairs                        |    65.871 |     0.2%
jsdoc/require-param-type                      |    64.030 |     0.2%
unicorn/prefer-array-flat                     |    63.841 |     0.2%
no-octal-escape                               |    61.643 |     0.2%
no-unmodified-loop-condition                  |    60.617 |     0.2%
no-mixed-spaces-and-tabs                      |    54.810 |     0.2%
node/no-unsupported-features/node-builtins    |    50.433 |     0.2%
semi-style                                    |    50.287 |     0.2%
no-multi-str                                  |    49.396 |     0.2%
spaced-comment                                |    49.167 |     0.2%
node/no-unpublished-import                    |    48.616 |     0.2%
quotes                                        |    48.100 |     0.2%
object-property-newline                       |    47.837 |     0.2%
computed-property-spacing                     |    47.622 |     0.1%
new-cap                                       |    47.229 |     0.1%
consistent-return                             |    47.117 |     0.1%
no-misleading-character-class                 |    44.422 |     0.1%
eslint-plugin/no-missing-message-ids          |    44.371 |     0.1%
function-call-argument-newline                |    43.694 |     0.1%
no-unsafe-optional-chaining                   |    43.207 |     0.1%
no-use-before-define                          |    42.609 |     0.1%
no-tabs                                       |    42.382 |     0.1%
brace-style                                   |    40.770 |     0.1%
block-spacing                                 |    40.613 |     0.1%
no-restricted-properties                      |    40.199 |     0.1%
prefer-template                               |    40.072 |     0.1%
dot-location                                  |    38.742 |     0.1%
no-unreachable                                |    38.626 |     0.1%
no-this-before-super                          |    37.796 |     0.1%
constructor-super                             |    37.706 |     0.1%
semi                                          |    37.164 |     0.1%
node/no-mixed-requires                        |    36.436 |     0.1%
array-callback-return                         |    35.633 |     0.1%
no-nonoctal-decimal-escape                    |    35.285 |     0.1%
jsdoc/no-bad-blocks                           |    34.443 |     0.1%
no-undef-init                                 |    33.939 |     0.1%
no-invalid-this                               |    33.720 |     0.1%
jsdoc/require-jsdoc                           |    33.513 |     0.1%
no-floating-decimal                           |    33.492 |     0.1%
space-before-blocks                           |    32.542 |     0.1%
node/no-extraneous-import                     |    32.313 |     0.1%
no-extend-native                              |    31.390 |     0.1%
no-eval                                       |    29.276 |     0.1%
no-unreachable-loop                           |    29.158 |     0.1%
node/handle-callback-err                      |    28.388 |     0.1%
no-lone-blocks                                |    27.420 |     0.1%
no-shadow                                     |    27.018 |     0.1%
eslint-plugin/prefer-output-null              |    26.806 |     0.1%
no-useless-backreference                      |    26.541 |     0.1%
no-useless-computed-key                       |    26.270 |     0.1%
no-constant-binary-expression                 |    26.207 |     0.1%
arrow-spacing                                 |    26.169 |     0.1%
node/callback-return                          |    25.017 |     0.1%
no-octal                                      |    24.853 |     0.1%
no-unused-expressions                         |    24.414 |     0.1%
getter-return                                 |    24.032 |     0.1%
no-param-reassign                             |    23.512 |     0.1%
no-self-compare                               |    23.433 |     0.1%
eslint-plugin/test-case-property-ordering     |    23.280 |     0.1%
eslint-comments/disable-enable-pair           |    23.142 |     0.1%
space-before-function-paren                   |    22.281 |     0.1%
no-dupe-else-if                               |    22.169 |     0.1%
no-irregular-whitespace                       |    21.554 |     0.1%
node/shebang                                  |    21.273 |     0.1%
no-const-assign                               |    20.937 |     0.1%
prefer-promise-reject-errors                  |    20.376 |     0.1%
space-unary-ops                               |    20.307 |     0.1%
no-implied-eval                               |    19.713 |     0.1%
no-setter-return                              |    19.690 |     0.1%
class-methods-use-this                        |    19.294 |     0.1%
eslint-plugin/no-only-tests                   |    19.293 |     0.1%
eslint-plugin/no-unused-message-ids           |    19.053 |     0.1%
node/no-unpublished-bin                       |    18.850 |     0.1%
no-useless-call                               |    18.461 |     0.1%
strict                                        |    18.204 |     0.1%
curly                                         |    17.668 |     0.1%
eslint-plugin/prefer-replace-text             |    17.486 |     0.1%
no-shadow-restricted-names                    |    17.399 |     0.1%
no-prototype-builtins                         |    17.219 |     0.1%
node/no-path-concat                           |    16.921 |     0.1%
prefer-spread                                 |    16.751 |     0.1%
dot-notation                                  |    16.303 |     0.1%
no-constant-condition                         |    16.144 |     0.1%
prefer-const                                  |    16.054 |     0.1%
prefer-exponentiation-operator                |    16.009 |     0.1%
arrow-body-style                              |    15.427 |     0.0%
no-iterator                                   |    15.399 |     0.0%
no-loop-func                                  |    15.346 |     0.0%
func-style                                    |    15.061 |     0.0%
eslint-plugin/require-meta-docs-url           |    15.039 |     0.0%
no-unsafe-finally                             |    14.297 |     0.0%
no-caller                                     |    14.004 |     0.0%
eslint-plugin/fixer-return                    |    13.815 |     0.0%
no-constructor-return                         |    13.593 |     0.0%
wrap-iife                                     |    13.516 |     0.0%
prefer-numeric-literals                       |    13.258 |     0.0%
prefer-arrow-callback                         |    13.179 |     0.0%
no-extra-bind                                 |    13.178 |     0.0%
eslint-plugin/prefer-message-ids              |    13.037 |     0.0%
unicorn/prefer-includes                       |    13.036 |     0.0%
use-isnan                                     |    12.236 |     0.0%
no-proto                                      |    12.120 |     0.0%
unicorn/prefer-set-has                        |    11.469 |     0.0%
no-extra-boolean-cast                         |    11.429 |     0.0%
template-curly-spacing                        |    11.300 |     0.0%
eslint-plugin/report-message-format           |    10.894 |     0.0%
no-invalid-regexp                             |    10.819 |     0.0%
eslint-plugin/test-case-shorthand-strings     |    10.700 |     0.0%
no-inner-declarations                         |    10.153 |     0.0%
yoda                                          |     9.843 |     0.0%
one-var-declaration-per-line                  |     9.804 |     0.0%
no-array-constructor                          |     9.777 |     0.0%
prefer-regex-literals                         |     9.694 |     0.0%
no-self-assign                                |     9.601 |     0.0%
unicorn/prefer-array-find                     |     9.559 |     0.0%
eslint-comments/require-description           |     9.465 |     0.0%
no-undefined                                  |     9.260 |     0.0%
no-obj-calls                                  |     9.243 |     0.0%
no-return-assign                              |     9.166 |     0.0%
eslint-plugin/no-deprecated-context-methods   |     9.137 |     0.0%
no-sparse-arrays                              |     9.044 |     0.0%
eqeqeq                                        |     9.042 |     0.0%
no-dupe-args                                  |     8.855 |     0.0%
eslint-plugin/require-meta-fixable            |     8.730 |     0.0%
eslint-plugin/require-meta-schema             |     8.590 |     0.0%
eslint-plugin/no-missing-placeholders         |     7.818 |     0.0%
no-fallthrough                                |     7.624 |     0.0%
eslint-plugin/prefer-placeholders             |     7.407 |     0.0%
eslint-comments/no-unlimited-disable          |     7.295 |     0.0%
default-param-last                            |     7.239 |     0.0%
eslint-plugin/consistent-output               |     7.225 |     0.0%
no-func-assign                                |     7.173 |     0.0%
eslint-plugin/no-unused-placeholders          |     6.988 |     0.0%
eslint-plugin/no-useless-token-range          |     6.914 |     0.0%
node/no-missing-import                        |     6.532 |     0.0%
eslint-plugin/require-meta-has-suggestions    |     6.431 |     0.0%
prefer-rest-params                            |     6.374 |     0.0%
no-empty                                      |     6.357 |     0.0%
no-console                                    |     6.219 |     0.0%
generator-star-spacing                        |     6.215 |     0.0%
valid-typeof                                  |     6.183 |     0.0%
no-global-assign                              |     6.141 |     0.0%
no-compare-neg-zero                           |     6.080 |     0.0%
no-useless-concat                             |     5.939 |     0.0%
node/no-exports-assign                        |     5.890 |     0.0%
no-restricted-syntax                          |     5.537 |     0.0%
unicorn/prefer-array-some                     |     5.458 |     0.0%
no-else-return                                |     5.393 |     0.0%
no-confusing-arrow                            |     5.241 |     0.0%
eslint-plugin/no-deprecated-report-api        |     5.096 |     0.0%
eslint-plugin/require-meta-docs-description   |     5.053 |     0.0%
no-new-object                                 |     4.933 |     0.0%
require-unicode-regexp                        |     4.899 |     0.0%
arrow-parens                                  |     4.815 |     0.0%
no-unsafe-negation                            |     4.572 |     0.0%
no-cond-assign                                |     4.508 |     0.0%
no-var                                        |     4.385 |     0.0%
require-yield                                 |     4.151 |     0.0%
no-duplicate-case                             |     4.145 |     0.0%
template-tag-spacing                          |     4.093 |     0.0%
no-dupe-class-members                         |     4.067 |     0.0%
unicorn/prefer-array-flat-map                 |     4.048 |     0.0%
internal-rules/no-invalid-meta                |     3.986 |     0.0%
eol-last                                      |     3.875 |     0.0%
eslint-comments/no-aggregating-enable         |     3.583 |     0.0%
radix                                         |     3.317 |     0.0%
no-useless-rename                             |     2.996 |     0.0%
operator-assignment                           |     2.992 |     0.0%
yield-star-spacing                            |     2.906 |     0.0%
switch-colon-spacing                          |     2.718 |     0.0%
new-parens                                    |     2.709 |     0.0%
unicorn/prefer-array-index-of                 |     2.603 |     0.0%
unicorn/prefer-string-starts-ends-with        |     2.588 |     0.0%
no-new-wrappers                               |     2.387 |     0.0%
default-case                                  |     2.177 |     0.0%
no-sequences                                  |     2.153 |     0.0%
eslint-plugin/require-meta-type               |     2.117 |     0.0%
no-extra-semi                                 |     2.111 |     0.0%
unicode-bom                                   |     1.969 |     0.0%
rest-spread-spacing                           |     1.929 |     0.0%
symbol-description                            |     1.898 |     0.0%
no-unneeded-ternary                           |     1.867 |     0.0%
eslint-comments/no-duplicate-disable          |     1.744 |     0.0%
no-new-func                                   |     1.661 |     0.0%
no-empty-character-class                      |     1.657 |     0.0%
no-new-symbol                                 |     1.653 |     0.0%
unicorn/prefer-string-trim-start-end          |     1.607 |     0.0%
no-delete-var                                 |     1.514 |     0.0%
no-labels                                     |     1.509 |     0.0%
eslint-comments/no-unused-enable              |     1.481 |     0.0%
unicorn/prefer-string-slice                   |     1.476 |     0.0%
node/no-new-require                           |     1.468 |     0.0%
eslint-plugin/prefer-object-rule              |     1.429 |     0.0%
no-undef                                      |     1.296 |     0.0%
no-empty-pattern                              |     1.279 |     0.0%
no-throw-literal                              |     1.253 |     0.0%
for-direction                                 |     1.187 |     0.0%
no-nested-ternary                             |     1.120 |     0.0%
no-useless-constructor                        |     1.065 |     0.0%
sort-keys                                     |     0.970 |     0.0%
no-case-declarations                          |     0.960 |     0.0%
no-ex-assign                                  |     0.913 |     0.0%
no-class-assign                               |     0.900 |     0.0%
no-unused-labels                              |     0.748 |     0.0%
no-new                                        |     0.693 |     0.0%
no-useless-catch                              |     0.598 |     0.0%
default-case-last                             |     0.565 |     0.0%
guard-for-in                                  |     0.508 |     0.0%
no-with                                       |     0.484 |     0.0%
no-async-promise-executor                     |     0.466 |     0.0%
no-import-assign                              |     0.425 |     0.0%
no-debugger                                   |     0.407 |     0.0%
no-label-var                                  |     0.386 |     0.0%
node/process-exit-as-throw                    |     0.305 |     0.0%
eslint-comments/no-unused-disable             |     0.265 |     0.0%

After this change, the rule takes 10x more time. This is somewhat surprising because for the default "location": "start" the only change is in the suffix, and the culprit seems to be \W.

@lachlanhunt what do you think about reverting the refactoring part of this change, and just fixing the bug? I believe the bug is in generating this alternative part of the regex, the pattern should be just prefix + escaped + suffix regardless of the location value.

@lachlanhunt
Copy link
Contributor Author

lachlanhunt commented Jul 9, 2022

I was able to reproduce the performance issue, and verify it is the \W that causes it.

In the original code, for a simple term like "TODO", the RegExp is generated as \bTODO\b|\bTODO\b, which redundantly repeats the whole thing. If I simply replace the non-escaped term with escaped, then it's still just \bESCAPED_TERM\b|\bESCAPED_TERM\b, which is equally redundant.

The \W is really only needed in either the prefix or suffix when the term starts or ends with a non-word character, respectively. (e.g. "!TODO" or "TODO!"). So we can conditionally include \W in prefix/suffix only when these conditions are true.

The performance on my computer with this branch before my latest fix:

Rule                                          | Time (ms) | Relative
:---------------------------------------------|----------:|--------:
no-warning-comments                           |   247.955 |     1.7%

With my latest fix for this issue, the result is back down to:

Rule                                          | Time (ms) | Relative
:---------------------------------------------|----------:|--------:
no-warning-comments                           |    14.031 |     0.1%

(This matches what I get when I run the same test on the main branch.)

nzakas
nzakas approved these changes Jul 9, 2022
Copy link
Member

@nzakas nzakas left a comment

LGTM. Would like another set of eyes before merging.

Nice work on this!

const prefix = location === "start" ? "^\\s*" : `(?:^|\\b${/^\W/u.test(escaped) ? "|\\W" : ""})`;
const suffix = `(?:\\b${/\W$/u.test(escaped) ? "|\\W" : ""}|$)`;
Copy link
Member

@mdjermanovic mdjermanovic Jul 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There will be the same performance issues with terms that end with non-word characters, like:

"no-warning-comments": ["error", { terms: ["foo!", "bar!", "baz!"] }]

This takes a lot more time (10-20x) with the new version.

I believe the complexity in the process of generating regular expressions is pretty much the same as it was, but the generated regular expressions are more complex.

For example, instead of a simpler /^\s*foo!/iu, this will generate /^\s*foo!(?:\b|\W|$)/iu, which apparently has a much worse performance (I'm not sure why).

I'd suggest that we just remove the useless (and buggy) + eitherOrWordBoundary + term + wordBoundary part.

@lachlanhunt
Copy link
Contributor Author

lachlanhunt commented Jul 9, 2022

It looks like \W is very slow when used with the u flag. [^A-Za-z0-9_] is orders of magnitude faster. I'm working on a fix.

@mdjermanovic
Copy link
Member

mdjermanovic commented Jul 9, 2022

It looks like \W is very slow when used with the u flag. [^A-Za-z0-9_] is orders of magnitude faster. I'm working on a fix

I'd still rather keep the code from the current main branch minus the part that causes bug with unescaped characters, because that code does have a bug but it doesn't have known performance issues. Or, split the bug fix and refactor into two separate PRs (if we think that refactor would be useful). That way, if it turns out that refactor introduced performance issues or unwanted changes in the behavior, we could easily revert it.

In particular, this code looks good so we could keep it for now:

const suffix = /\w$/u.test(term) ? "\\b" : "";
if (location === "start") {
/*
* When matching at the start, ignore leading whitespace, and
* there's no need to worry about word boundaries.
*/
prefix = "^\\s*";
} else if (/^\w/u.test(term)) {
prefix = wordBoundary;
} else {
prefix = "";
}

but this code doesn't look good:

if (location === "start") {
/*
* For location "start" the regex should be
* ^\s*TERM\b. This checks the word boundary
* at the beginning of the comment.
*/
return new RegExp(prefix + escaped + suffix, "iu");
}
/*
* For location "anywhere" the regex should be
* \bTERM\b|\bTERM\b, this checks the entire comment
* for the term.
*/
return new RegExp(
prefix +
escaped +
suffix +
eitherOrWordBoundary +
term +
wordBoundary,
"iu"
);
}

because it inserts unescaped term in the pattern, for no apparent reason. We can replace this with return new RegExp(prefix + escaped + suffix, "iu"); regardless of the value in location.

@lachlanhunt
Copy link
Contributor Author

lachlanhunt commented Jul 9, 2022

Alright, done. Performance is consistently around 12-13ms on my computer now for all kinds of terms.

Copy link
Member

@mdjermanovic mdjermanovic left a comment

LGTM, thanks!

@mdjermanovic mdjermanovic merged commit 30be0ed into eslint:main Jul 9, 2022
20 checks passed
@mdjermanovic
Copy link
Member

mdjermanovic commented Jul 9, 2022

It looks like \W is very slow when used with the u flag. [^A-Za-z0-9_] is orders of magnitude faster. I'm working on a fix

If you have a benchmark that shows a big difference in performance between equivalent regexes, it might be worth reporting the problem to https://bugs.chromium.org/p/v8/issues/list.

There were some inconsistencies around \W, specifically with iu combination of flags (tc39/ecma262#525), so it could be that some special-casing in the implementation breaks normal flow and optimizations.

@lachlanhunt
Copy link
Contributor Author

lachlanhunt commented Jul 10, 2022

I actually tried to write a separate perf test just for that and some other regexes that were performing weirdly slow within eslint, but I couldn't reproduce the performance issues outside of eslint.

I just found that if I either removed the u flag or swapped \W for [^A-Za-z0-9_] in this code, then the performance issue disappeared in eslint's reporting.

I suspect the problem with my simple perf tests were that some compiler optimisations were being applied for them, which for some reason weren't being applied within eslint code. Writing perf tests is hard.

crapStone pushed a commit to Calciumdibromid/CaBr2 that referenced this issue Jul 18, 2022
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [eslint](https://eslint.org) ([source](https://github.com/eslint/eslint)) | devDependencies | minor | [`8.19.0` -> `8.20.0`](https://renovatebot.com/diffs/npm/eslint/8.19.0/8.20.0) |

---

### Release Notes

<details>
<summary>eslint/eslint</summary>

### [`v8.20.0`](https://github.com/eslint/eslint/releases/tag/v8.20.0)

[Compare Source](eslint/eslint@v8.19.0...v8.20.0)

#### Features

-   [`ca83178`](eslint/eslint@ca83178) feat: catch preprocess errors ([#&#8203;16105](eslint/eslint#16105)) (JounQin)

#### Bug Fixes

-   [`30be0ed`](eslint/eslint@30be0ed) fix: no-warning-comments rule escapes special RegEx characters in terms ([#&#8203;16090](eslint/eslint#16090)) (Lachlan Hunt)
-   [`bfe5e88`](eslint/eslint@bfe5e88) fix: ignore spacing before `]` and `}` in comma-spacing ([#&#8203;16113](eslint/eslint#16113)) (Milos Djermanovic)

#### Documentation

-   [`845c4f4`](eslint/eslint@845c4f4) docs: Add website team details ([#&#8203;16115](eslint/eslint#16115)) (Nicholas C. Zakas)
-   [`5a0dfdb`](eslint/eslint@5a0dfdb) docs: Link to blog post in no-constant-binary-expression ([#&#8203;16112](eslint/eslint#16112)) (Jordan Eldredge)
-   [`bc692a9`](eslint/eslint@bc692a9) docs: remove install command ([#&#8203;16084](eslint/eslint#16084)) (Strek)
-   [`49ca3f0`](eslint/eslint@49ca3f0) docs: don't show toc when content not found ([#&#8203;16095](eslint/eslint#16095)) (Amaresh  S M)
-   [`ba19e3f`](eslint/eslint@ba19e3f) docs: enhance 404 page UI ([#&#8203;16097](eslint/eslint#16097)) (Amaresh  S M)
-   [`a75d3b4`](eslint/eslint@a75d3b4) docs: remove unused meta.docs.category field in working-with-rules page ([#&#8203;16109](eslint/eslint#16109)) (Brandon Scott)
-   [`cdc0206`](eslint/eslint@cdc0206) docs: add formatters page edit link ([#&#8203;16094](eslint/eslint#16094)) (Amaresh  S M)
-   [`4d1ed22`](eslint/eslint@4d1ed22) docs: preselect default theme ([#&#8203;16098](eslint/eslint#16098)) (Strek)
-   [`4b79612`](eslint/eslint@4b79612) docs: add missing correct/incorrect containers ([#&#8203;16087](eslint/eslint#16087)) (Milos Djermanovic)
-   [`09f6acb`](eslint/eslint@09f6acb) docs: fix UI bug on rules index and details pages ([#&#8203;16082](eslint/eslint#16082)) (Deepshika S)
-   [`f5db264`](eslint/eslint@f5db264) docs: remove remaining duplicate rule descriptions ([#&#8203;16093](eslint/eslint#16093)) (Milos Djermanovic)
-   [`32a6b2a`](eslint/eslint@32a6b2a) docs: Add scroll behaviour smooth ([#&#8203;16056](eslint/eslint#16056)) (Amaresh  S M)

#### Chores

-   [`bbf8df4`](eslint/eslint@bbf8df4) chore: Mark autogenerated release blog post as draft ([#&#8203;16130](eslint/eslint#16130)) (Nicholas C. Zakas)
-   [`eee4306`](eslint/eslint@eee4306) chore: update internal lint dependencies ([#&#8203;16088](eslint/eslint#16088)) (Bryan Mishkin)
-   [`9615a42`](eslint/eslint@9615a42) chore: update formatter examples template to avoid markdown lint error ([#&#8203;16085](eslint/eslint#16085)) (Milos Djermanovic)
-   [`62541ed`](eslint/eslint@62541ed) chore: fix markdown linting error ([#&#8203;16083](eslint/eslint#16083)) (唯然)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

 **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzMi4xMTcuMSIsInVwZGF0ZWRJblZlciI6IjMyLjExNy4xIn0=-->

Co-authored-by: cabr2-bot <cabr2.help@gmail.com>
Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1466
Reviewed-by: Epsilon_02 <epsilon_02@noreply.codeberg.org>
Co-authored-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org>
Co-committed-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion bug ESLint is working incorrectly rule Relates to ESLint's core rules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants