mirror of
https://github.com/oven-sh/bun
synced 2026-02-12 03:48:56 +00:00
fix(parser): uncaught mismatch between JSX opening/closing tags (#14528)
This commit is contained in:
@@ -530,7 +530,8 @@ const JSXTag = struct {
|
||||
};
|
||||
data: Data,
|
||||
range: logger.Range,
|
||||
name: string = "",
|
||||
/// Empty string for fragments.
|
||||
name: string,
|
||||
|
||||
pub fn parse(comptime P: type, p: *P) anyerror!JSXTag {
|
||||
const loc = p.lexer.loc();
|
||||
@@ -559,6 +560,7 @@ const JSXTag = struct {
|
||||
.data = name,
|
||||
}, loc) },
|
||||
.range = tag_range,
|
||||
.name = name,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -15778,7 +15780,7 @@ fn NewParser_(
|
||||
const end_tag = try JSXTag.parse(P, p);
|
||||
|
||||
if (!strings.eql(end_tag.name, tag.name)) {
|
||||
try p.log.addRangeErrorFmt(p.source, end_tag.range, p.allocator, "Expected closing tag \\</{s}> to match opening tag \\<{s}>", .{
|
||||
try p.log.addRangeErrorFmt(p.source, end_tag.range, p.allocator, "Expected closing tag \\</{s}\\> to match opening tag \\<{s}\\>", .{
|
||||
end_tag.name,
|
||||
tag.name,
|
||||
});
|
||||
|
||||
23
test/regression/issue/14477/14477.test.ts
Normal file
23
test/regression/issue/14477/14477.test.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { bunEnv, bunExe } from "harness";
|
||||
import { join } from "path";
|
||||
import fs from "fs";
|
||||
|
||||
test("JSXElement with mismatched closing tags produces a syntax error", async () => {
|
||||
const files = await fs.promises.readdir(import.meta.dir);
|
||||
const fixtures = files.filter(file => !file.endsWith(".test.ts")).map(fixture => join(import.meta.dir, fixture));
|
||||
|
||||
const bakery = fixtures.map(
|
||||
fixture =>
|
||||
Bun.spawn({
|
||||
cmd: [bunExe(), fixture],
|
||||
cwd: import.meta.dir,
|
||||
stdio: ["inherit", "inherit", "inherit"],
|
||||
env: bunEnv,
|
||||
}).exited,
|
||||
);
|
||||
|
||||
// all subprocesses should fail.
|
||||
const exited = await Promise.all(bakery);
|
||||
expect(exited).toEqual(Array.from({ length: fixtures.length }, () => 1));
|
||||
});
|
||||
1
test/regression/issue/14477/builtin-mismatch.tsx
Normal file
1
test/regression/issue/14477/builtin-mismatch.tsx
Normal file
@@ -0,0 +1 @@
|
||||
console.log(<div></p>);
|
||||
2
test/regression/issue/14477/component-mismatch.tsx
Normal file
2
test/regression/issue/14477/component-mismatch.tsx
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
console.log(<Foo></Bar>);
|
||||
3
test/regression/issue/14477/non-identifier-mismatch.tsx
Normal file
3
test/regression/issue/14477/non-identifier-mismatch.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
// mismatch where openening tag is not a valid IdentifierName, but is a valid
|
||||
// JSXIdentifierName
|
||||
console.log(<div-:button></p>);
|
||||
Reference in New Issue
Block a user