Skip to content

Commit 15ebded

Browse files
committed
fix(runtime-tags): treat bogus comments as comments, not text
A processing instruction or empty end tag left a gap in the scan, so the run after it looked like text and reported as moved out of a table. Both are kept out of the tree by the parser. An unparseable tag really does become text and is still reported.
1 parent 2d61a7a commit 15ebded

2 files changed

Lines changed: 21 additions & 3 deletions

File tree

packages/runtime-tags/src/__tests__/validate-structure.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,22 @@ describe("html structure validation", () => {
207207
html("<table><tbody><!><tr><td>x</td></tr></tbody></table>"),
208208
));
209209

210+
it("a processing instruction is a comment, not text", () =>
211+
assertClean(
212+
html("<table><tbody><?pi?><tr><td>x</td></tr></tbody></table>"),
213+
));
214+
215+
it("an empty end tag is dropped, not text", () =>
216+
assertClean(
217+
html("<table><tbody></><tr><td>x</td></tr></tbody></table>"),
218+
));
219+
220+
it("an unparseable tag really is text and is reported", () =>
221+
assertReports(
222+
[html("<table><tbody><123><tr><td>x</td></tr></tbody></table>")],
223+
"Text is moved out of",
224+
));
225+
210226
it("a bogus declaration is not text", () =>
211227
assertClean(
212228
html("<table><tbody><!bogus><tr><td>x</td></tr></tbody></table>"),

packages/runtime-tags/src/html/validate-structure.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ const closesParagraph = new Set(
110110
// `<!>` and other bogus declarations are comments, not text, so they must not
111111
// look like content the parser would move out of a table.
112112
const tokenSource =
113-
/<!--[\s\S]*?-->|<![^>]*>|<(\/?)([a-zA-Z][^\s/>]*)((?:"[^"]*"|'[^']*'|[^>"'])*)>|([^<]+)/
113+
/<!--[\s\S]*?-->|<[!?][^>]*>|<\/(?![a-zA-Z])[^>]*>|<(\/?)([a-zA-Z][^\s/>]*)((?:"[^"]*"|'[^']*'|[^>"'])*)>|([^<]+)/
114114
.source;
115115

116116
export type StructureSegment =
@@ -146,8 +146,10 @@ export function createStructureValidator() {
146146
tokens.lastIndex = 0;
147147
let match: RegExpExecArray | null;
148148
while ((match = tokens.exec(html))) {
149-
const [raw, closing, rawName, attrs, text] = match;
150-
if (raw[1] === "!") continue;
149+
const [, closing, rawName, attrs, text] = match;
150+
// A bogus comment or declaration matches no group; the parser keeps it
151+
// out of the tree, so it is neither an element nor text.
152+
if (rawName === undefined && text === undefined) continue;
151153
while (
152154
segmentIndex + 1 < starts.length &&
153155
starts[segmentIndex + 1] <= match.index

0 commit comments

Comments
 (0)