Skip to content

fix: stop doctest regex overrun in constructor-name example#11906

Draft
Planeshifter wants to merge 1 commit intodevelopfrom
philipp/ci-fix-constructor-name-doctest-2026-05-03
Draft

fix: stop doctest regex overrun in constructor-name example#11906
Planeshifter wants to merge 1 commit intodevelopfrom
philipp/ci-fix-constructor-name-doctest-2026-05-03

Conversation

@Planeshifter
Copy link
Copy Markdown
Member

Failing run: https://github.com/stdlib-js/stdlib/actions/runs/25195861572 (issue #11867, 2026-05-01)

Symptom:

lib/node_modules/@stdlib/utils/constructor-name/examples/index.js
   39:1   error  Displayed return value is `'String'`, but expected `undefined` instead  stdlib/doctest
  151:57  error  Unused eslint-disable directive (no problems were reported from 'no-buffer-constructor')

Root cause:

Error 1 (stdlib/doctest): The rule's RE_ANNOTATION regex contains a greedy [^;]* segment that matches newlines. Before the fix, noop() had a comment-only body with no semicolons. The regex anchored at \nfunction noop() {, its [^;]*; segment spanned across the function body and the trailing blank line, terminating at the ; of console.log( constructorName( 'a' ) );. The subsequent \n// token then matched \n// => 'String', so the rule fed the combined span to its VM sandbox as a single expression. A function declaration evaluates to undefined, not 'String', producing the observed mismatch.

Error 2 (unused eslint-disable): no-buffer-constructor is absent from all project ESLint rule files (etc/eslint/rules/). The inline disable directive on the Buffer line was stale.

Fix:

Two minimal edits to lib/node_modules/@stdlib/utils/constructor-name/examples/index.js:

  1. Add return void 0; inside noop(). This places a ; inside the function body. The greedy [^;]* now terminates at return void 0;; the following \n} does not match \n//, so the false-association attempt fails and the regex advances correctly to console.log( constructorName( 'a' ) );.

  2. Remove // eslint-disable-line no-buffer-constructor from the new Buffer(...) line. The rule is inactive; the directive serves no purpose.

Neither change affects runtime behavior. noop is passed to constructorName(noop) only to demonstrate a 'Function' result; its return value is never used. The test suite defines its own independent noop and is unaffected.

Validation:

  • Regex trace confirmed by Reviewer A: RE_ESLINT_INLINE strips the eslint-disable-line comment before RE_ANNOTATION runs, leaving return; → the ; survives and terminates the match inside the function body. (Note: cycle 1 proposed return; with a disable comment; cycle 2 revised to return void 0;no-useless-return only flags bare return;, not return expr;, so no suppression directive is needed.)
  • no-void is set to 'off' in etc/eslint/rules/best_practices.js (line 1418); void 0 is permitted.
  • Confirmed no-buffer-constructor absent from all etc/eslint/rules/ files.
  • Two review cycles. Cycle 1: Reviewer C (style) requested changes — commit message too long (83 chars) and return; + disable comment idiom objected to. Cycle 2: all three reviewers approved.

Reviewer notes:

  • Reviewer C (cycle 2) noted that the most idiomatic stdlib approach for an example noop would be require('@stdlib/utils/noop') rather than a local declaration with return void 0;. This is non-blocking: the current fix is correct and minimal. A maintainer may choose to apply the idiomatic refactor separately.
  • Several other // eslint-disable-line no-buffer-constructor directives exist elsewhere in the repo (e.g., buffer/from-buffer, buffer/from-array). Those are out of scope for this PR but may warrant a follow-up sweep.

Related: issue #11867 (cluster 1 of that issue — symbol/async-iterator — is addressed separately in draft PR #11905)

Contributing Guidelines


Generated by Claude Code

The CI JavaScript lint job on develop has been failing since 2026-05-01
with two errors in utils/constructor-name/examples/index.js:

  39:1   error  Displayed return value is `'String'`, but expected
                `undefined` instead  stdlib/doctest
  151:57 error  Unused eslint-disable directive (no problems were
                reported from 'no-buffer-constructor')

Error 1: The stdlib/doctest rule's RE_ANNOTATION regex contains a
greedy [^;]* segment that matches newlines. Starting at `\nfunction
noop() {`, the regex spans across the comment-only body (no `;`) to
`console.log( constructorName( 'a' ) );`, falsely associating
`// => 'String'` with the function expression, which evaluates to
`undefined` in the VM sandbox. Adding `return void 0;` inside noop()
places a semicolon in the body, causing the greedy match to terminate
there. The following `\n}` does not match `\n//`, so the false
association attempt fails and the regex correctly matches the
console.log call on the next attempt.

Error 2: `no-buffer-constructor` is not configured in any of the
project's ESLint rule files; the inline disable directive was stale.

Failing run: https://github.com/stdlib-js/stdlib/actions/runs/25195861572
@stdlib-bot stdlib-bot added the Good First PR A pull request resolving a Good First Issue. label May 3, 2026
@stdlib-bot
Copy link
Copy Markdown
Contributor

Coverage Report

Package Statements Branches Functions Lines
utils/constructor-name $\color{green}126/126$
$\color{green}+100.00%$
$\color{green}12/12$
$\color{green}+100.00%$
$\color{green}1/1$
$\color{green}+100.00%$
$\color{green}126/126$
$\color{green}+100.00%$

The above coverage report was generated for the changes in this PR.

@kgryte
Copy link
Copy Markdown
Member

kgryte commented May 5, 2026

@Planeshifter Seems like we need to make a more general fix here and not paper over by updating the example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Good First PR A pull request resolving a Good First Issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants