You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Array-of-tables header accepted with a single closing bracket at EOF: [[a] parses as {a: [{}]} #65
An array-of-tables header closed by a single ] is accepted when it is the last
thing in the document. [[a] parses as { a: [ {} ] } instead of throwing. One
character of trailing content is also silently discarded, so [[a]x parses the
same way.
TOML 1.1.0's grammar requires two closing brackets:
array-table=array-table-openkeyarray-table-closearray-table-open= %x5B.5Bws; [[ Double left square bracketarray-table-close=ws %x5D.5D; ]] Double right square bracket
array-table-close is %x5D.5D, so [[a] cannot derive from array-table.
Observed behaviour
input
1.8.0
expected
[[a]
accepts → {a:[{}]}
reject
[[a]x
accepts → {a:[{}]}, x discarded
reject
[[a]xyz
rejects
reject
[[a]]x
rejects
reject
[[a] + newline + b = 1
rejects
reject
[a]x
rejects
reject
Likely cause
In parse.js:
letk=parseKey(ctx,']');// consumes through the first ']'if(isTableArray){if(toml.charCodeAt(ctx.p-1)!==0x5d/* ] */){thrownewTomlError('expected end of table declaration',{ ... });}ctx.p++;}
The guard tests ctx.p - 1, which is the ] that parseKey has already
consumed and so is always 0x5d — the condition can never fire. The second
bracket is therefore never required, and ctx.p++ advances past whatever
happens to be there.
That accounts for the whole table: at EOF the increment is a no-op ([[a]), with
exactly one trailing character it swallows it ([[a]x), and with more the
leftovers produce an unrelated error ([[a]xyz).
Testing charCodeAt(ctx.p) for the closing bracket before advancing looks like
the intended check.
Why the test suite doesn't catch it
smol-toml passes all five existing toml-test cases for unclosed table headers
(invalid/table/array-no-close-01..04 and nested-brackets-close). Every one
of them has a line following the header, so none exercises the end-of-input path.
I've opened toml-lang/toml-test#205 with the two EOF cases ([[a] and [[a]x).
Other implementations
All reject [[a]:
BurntSushi/toml (Go) v1.6.0 — expected end of table array name delimiter ']'
CPython tomllib (3.14.7) — raises
Rust toml 1.1.4+spec-1.1.0 — rejects
How this was found
Generated by a conformance-suite generator that derives one test per named error
branch of an executable TOML 1.1.0 semantics.
Activity
fix: bad table array check, allow utf bom