diff --git a/src/parse.ts b/src/parse.ts index 66cae84..583b8cc 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -147,10 +147,12 @@ export function parse(toml: string, { maxDepth = 1000, integersAsBigInt }: Parse let k = parseKey(ctx, ']') if (isTableArray) { - if (toml.charCodeAt(ctx.p - 1) !== 0x5d /* ] */) { + // `ctx.p - 1` rejects anything between the two brackets (parseKey + // skips trailing whitespace), `ctx.p` requires the second one. + if (toml.charCodeAt(ctx.p - 1) !== 0x5d /* ] */ || toml.charCodeAt(ctx.p) !== 0x5d /* ] */) { throw new TomlError('expected end of table declaration', { toml: toml, - ptr: ctx.p - 1, + ptr: ctx.p, }) } diff --git a/test/parse.test.ts b/test/parse.test.ts index 534abe2..0e38d0b 100644 --- a/test/parse.test.ts +++ b/test/parse.test.ts @@ -210,6 +210,13 @@ it('rejects invalid arrays of table', () => { expect(() => parse('[[uwu] ]')).toThrow(TomlError) }) +it('rejects an array of tables header closed by a single bracket', () => { + expect(() => parse('[[uwu]')).toThrow(TomlError) + expect(() => parse('[[uwu]x')).toThrow(TomlError) + expect(() => parse('[[uwu]\nowo = 1')).toThrow(TomlError) + expect(() => parse('[[uwu] ')).toThrow(TomlError) +}) + it('parses arrays of tables with subtables', () => { const doc = ` [[fruits]]