From 2801cb1f4a18001068d9f98ddde62d2fa77a7280 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Mon, 9 Jun 2025 18:52:30 -0700 Subject: [PATCH] Fix TOML parser to handle inline tables and table arrays correctly (#20291) Co-authored-by: Cursor Agent --- src/toml/toml_parser.zig | 3 +- test-toml-fix.toml | 10 +++++ test/js/bun/resolve/toml/toml.test.js | 63 +++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 test-toml-fix.toml diff --git a/src/toml/toml_parser.zig b/src/toml/toml_parser.zig index 9f95d2b7cf..a483e18c4d 100644 --- a/src/toml/toml_parser.zig +++ b/src/toml/toml_parser.zig @@ -326,6 +326,7 @@ pub const TOML = struct { if (p.lexer.has_newline_before) { is_single_line = false; } + p.lexer.allow_double_bracket = true; try p.lexer.expect(.t_close_brace); return expr; }, @@ -363,8 +364,8 @@ pub const TOML = struct { if (p.lexer.has_newline_before) { is_single_line = false; } - try p.lexer.expect(.t_close_bracket); p.lexer.allow_double_bracket = true; + try p.lexer.expect(.t_close_bracket); return array_; }, else => { diff --git a/test-toml-fix.toml b/test-toml-fix.toml new file mode 100644 index 0000000000..2cad073b58 --- /dev/null +++ b/test-toml-fix.toml @@ -0,0 +1,10 @@ +[global] +inline_table = { q1 = 1 } + +[[items]] +q1 = 1 +q2 = 2 + +[[items]] +q1 = 3 +q2 = 4 \ No newline at end of file diff --git a/test/js/bun/resolve/toml/toml.test.js b/test/js/bun/resolve/toml/toml.test.js index d9fcaaaaf0..c9fa45a831 100644 --- a/test/js/bun/resolve/toml/toml.test.js +++ b/test/js/bun/resolve/toml/toml.test.js @@ -40,3 +40,66 @@ it("via dynamic import with type attribute", async () => { it("empty via import statement", () => { expect(emptyToml).toEqual({}); }); + +it("inline table followed by table array", () => { + const tomlContent = ` +[global] +inline_table = { q1 = 1 } + +[[items]] +q1 = 1 +q2 = 2 + +[[items]] +q1 = 3 +q2 = 4 +`; + + // Test via Bun's internal TOML parser + const Bun = globalThis.Bun; + const parsed = Bun.TOML.parse(tomlContent); + + expect(parsed.global).toEqual({ + inline_table: { q1: 1 }, + }); + expect(parsed.items).toEqual([ + { q1: 1, q2: 2 }, + { q1: 3, q2: 4 }, + ]); +}); + +it("array followed by table array", () => { + const tomlContent = ` +[global] +array = [1, 2, 3] + +[[items]] +q1 = 1 +`; + + const Bun = globalThis.Bun; + const parsed = Bun.TOML.parse(tomlContent); + + expect(parsed.global).toEqual({ + array: [1, 2, 3], + }); + expect(parsed.items).toEqual([{ q1: 1 }]); +}); + +it("nested inline tables", () => { + const tomlContent = ` +[global] +nested = { outer = { inner = 1 } } + +[[items]] +q1 = 1 +`; + + const Bun = globalThis.Bun; + const parsed = Bun.TOML.parse(tomlContent); + + expect(parsed.global).toEqual({ + nested: { outer: { inner: 1 } }, + }); + expect(parsed.items).toEqual([{ q1: 1 }]); +});