Skip to content

fix(lexer): ignore stale callbacks after reuse - #722

Merged
jeswr merged 2 commits into
rdfjs:mainfrom
jeswr:codex/fix-lexer-stale-stream-events
Sep 5, 2026
Merged

fix(lexer): ignore stale callbacks after reuse#722
jeswr merged 2 commits into
rdfjs:mainfrom
jeswr:codex/fix-lexer-stale-stream-events

Conversation

@jeswr

@jeswr jeswr commented Sep 5, 2026

Copy link
Copy Markdown
Member

Reusing a Lexer can leave old stream handlers or a queued string tokenizer referring to shared lexer state. If either runs after a later tokenize call, it can deliver the new input's tokens to the previous callback or crash when the queued tokenizer encounters a null input.

Give each tokenization an identity and ignore callbacks belonging to earlier invocations. The guard covers stream data, end, and error events as well as the microtask used for callback-based string tokenization. Eleven regression cases cover late stream events after failure or completion, and queued string tokenization superseded by either synchronous or callback-based string input.

The stale-stream bug reproduces on 30c108e, before #721, so this fix is submitted independently of the lexer coordinate changes.

Validation:

  • 6,887 Jest tests pass with 100% statement, branch, function, and line coverage.
  • ESLint, Node and browser builds, and git diff --check pass.
  • Regression tests reproduce the output corruption and null-input crashes before the corresponding guards are added.

Copilot AI lite review requested due to automatic review settings September 5, 2026 10:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The new tokenization identity is not applied to the queued queueMicrotask path for string tokenization, which can still allow an earlier callback to run after a later tokenize call.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR makes N3Lexer reuse safer by preventing late data/end/error events from a previous stream tokenization from interfering with a subsequent tokenization on the same lexer instance.

Changes:

  • Introduces a per-tokenization identity on the lexer instance and ignores stream events from older invocations.
  • Adds a 3×3 regression matrix covering late stream events after syntax error, stream error, and normal completion.
File summaries
File Description
src/N3Lexer.js Adds tokenization identity tracking and gates stream event handlers to ignore stale events after reuse.
test/N3Lexer-test.js Adds regression tests ensuring late events from a prior stream do not affect the next tokenization callback or crash.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/N3Lexer.js Outdated
@jeswr jeswr changed the title fix(lexer): ignore stale stream events after reuse fix(lexer): ignore stale callbacks after reuse Sep 5, 2026
@jeswr
jeswr merged commit 10eafd3 into rdfjs:main Sep 5, 2026
55 checks passed
@jeswr
jeswr deleted the codex/fix-lexer-stale-stream-events branch September 5, 2026 12:53
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 2.7.5 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants