Fix stream parser to handle contiguous opening brackets correctly#59
Merged
Conversation
…ing brackets When the HTMLStreamParser encounters << before a tag name, the first < should be treated as plain text while the second < starts tag detection. Previously both < characters were flushed together, causing the subsequent valid tag to be treated as plain text. Closes #17 Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
fix(stream-parser): flush previous < as plain text on contiguous opening brackets
…E_TAG_NAME modes The fix from #17 only covered the DECISION_OPEN_TAG_NAME_OR_CLOSE_TAG_NAME mode. The same bug existed in OPEN_TAG_NAME and CLOSE_TAG_NAME modes where an unexpected < would get flushed as plain text instead of restarting tag detection. The CLOSE_TAG_SEEK_END case is deferred to #22. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…and-close-tag-name-modes fix(stream-parser): handle < as tag restart in OPEN_TAG_NAME and CLOSE_TAG_NAME modes
Contributor
There was a problem hiding this comment.
Pull request overview
This PR strengthens HTMLStreamParser’s streaming robustness by treating consecutive < characters encountered mid-tag-detection as plain text and restarting tag detection, and it adds regression tests for these malformed/ambiguous sequences.
Changes:
- Restart tag detection when a new
<appears while parsing an open tag name, close tag name, or the initial<decision state—flushing the partial tag buffer into plain text. - Add new stream-focused tests covering contiguous
<, partial tag fragments, and chunk-boundary edge cases.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/stream-html-to-format.ts |
Adds “flush partial tag + restart on <” logic in tag-name/decision modes to avoid mis-parsing malformed sequences. |
test/stream-html-to-format.test.ts |
Adds regression tests to validate correct plain-text flushing and entity offsets when malformed tag openings/closings occur. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
469
to
+479
| private addCharInCloseTagNameMode(char: string): void { | ||
| // If we encounter another `<`, the current partial close tag was plain text. | ||
| // Flush it and restart tag detection with this new `<`. | ||
| if (char === "<") { | ||
| this.text += this.fullTagOrEntityBufferText; | ||
| this.fullTagOrEntityBufferText = char; | ||
| this.workingBufferText = ""; | ||
| this.mode = | ||
| HTML_STREAM_PARSER_MODE.DECISION_OPEN_TAG_NAME_OR_CLOSE_TAG_NAME; | ||
| return; | ||
| } |
Comment on lines
+134
to
+146
| it("evaluates contiguous opening brackets as plain text", () => { | ||
| const parser = new HTMLStreamParser(); | ||
| parser.add("<<b"); | ||
| parser.add(">bold</b>"); | ||
|
|
||
| const formatted = parser.toFormattedString(); | ||
|
|
||
| assertEquals(formatted.rawText, "<bold"); | ||
| assertEquals(formatted.rawEntities.length, 1); | ||
| assertEquals(formatted.rawEntities[0]?.type, "bold"); | ||
| assertEquals(formatted.rawEntities[0]?.offset, 1); | ||
| assertEquals(formatted.rawEntities[0]?.length, 4); | ||
| }); |
Comment on lines
+148
to
+153
| it("flushes partial open tag and restarts on <: <b<b>bold</b>", () => { | ||
| const parser = new HTMLStreamParser(); | ||
| parser.add("<b<b>bold</b>"); | ||
|
|
||
| const formatted = parser.toFormattedString(); | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request improves the robustness of the
HTMLStreamParserby handling cases where multiple consecutive<characters appear in the input, ensuring that malformed or ambiguous tag openings/closings are treated as plain text. It also adds comprehensive tests to cover these edge cases.Parser robustness improvements
src/stream-html-to-format.tsto detect when a<character appears while already parsing a potential tag (open, close, or ambiguous), treating the previous partial tag as plain text and restarting tag detection with the new<. This prevents malformed tags from being incorrectly parsed as valid HTML entities. [1] [2] [3]Test coverage enhancements
test/stream-html-to-format.test.tsto verify correct handling of contiguous<characters, partial open/close tags, and edge cases where tag boundaries occur across input chunks. These tests ensure the parser correctly flushes partial tags as plain text and maintains accurate entity extraction.