diff --git a/src/Tokenizer.spec.ts b/src/Tokenizer.spec.ts index c817bb37..6a1792e1 100644 --- a/src/Tokenizer.spec.ts +++ b/src/Tokenizer.spec.ts @@ -158,6 +158,15 @@ describe("Tokenizer", () => { ).toMatchSnapshot(); }); + it("should not treat as a complete comment in xmlMode", () => { + expect( + tokenize( + "startshould ignore<-->end", + { xmlMode: true }, + ), + ).toMatchSnapshot(); + }); + it.each([ "script", "style", diff --git a/src/Tokenizer.ts b/src/Tokenizer.ts index 4c631f29..83028a03 100644 --- a/src/Tokenizer.ts +++ b/src/Tokenizer.ts @@ -622,8 +622,11 @@ export default class Tokenizer { if (c === CharCodes.Dash) { this.state = State.InCommentLike; this.currentSequence = Sequences.CommentEnd; - // Allow short comments (eg. ) - this.sequenceIndex = 2; + /* + * In HTML, `` is a valid empty comment. In XML, comments + * must be closed by `-->`, so we require the full sequence. + */ + this.sequenceIndex = this.xmlMode ? 0 : 2; this.sectionStart = this.index + 1; } else { this.state = State.InDeclaration; diff --git a/src/__snapshots__/Tokenizer.spec.ts.snap b/src/__snapshots__/Tokenizer.spec.ts.snap index d81daf97..8ad0e859 100644 --- a/src/__snapshots__/Tokenizer.spec.ts.snap +++ b/src/__snapshots__/Tokenizer.spec.ts.snap @@ -565,6 +565,72 @@ exports[`Tokenizer > should not lose data when pausing 1`] = ` ] `; +exports[`Tokenizer > should not treat as a complete comment in xmlMode 1`] = ` +[ + [ + "onopentagname", + 1, + 5, + ], + [ + "onopentagend", + 5, + ], + [ + "onopentagname", + 7, + 11, + ], + [ + "onopentagend", + 11, + ], + [ + "ontext", + 12, + 17, + ], + [ + "onclosetag", + 19, + 23, + ], + [ + "oncomment", + 28, + 58, + 2, + ], + [ + "onopentagname", + 60, + 64, + ], + [ + "onopentagend", + 64, + ], + [ + "ontext", + 65, + 68, + ], + [ + "onclosetag", + 70, + 74, + ], + [ + "onclosetag", + 77, + 81, + ], + [ + "onend", + ], +] +`; + exports[`Tokenizer > should support self-closing special tags > for self-closing script tag 1`] = ` [ [