Skip to content

Commit

Permalink
fix: enhance table clashes handling
Browse files Browse the repository at this point in the history
closes #10
  • Loading branch information
cyyynthia committed Oct 18, 2023
1 parent 3d0d419 commit 9b024b2
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 7 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "smol-toml",
"version": "1.1.2",
"version": "1.1.3",
"keywords": [
"toml",
"parser",
Expand Down
14 changes: 13 additions & 1 deletion src/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,19 @@ export function extractValue (str: string, ptr: number, end?: string): [ TomlPri
if (c === '"' || c === "'") {
endPtr = getStringEnd(str, ptr)
let parsed = parseString(str, ptr, endPtr)
if (end) endPtr = skipUntil(str, endPtr, ',', end,end !== ']')
if (end) {
endPtr = skipVoid(str, endPtr, end !== ']')

if (str[endPtr] && str[endPtr] !== ',' && str[endPtr] !== end && str[endPtr] !== '\n' && str[endPtr] !== '\r') {
throw new TomlError('unexpected character encountered', {
toml: str,
ptr: endPtr,
})
}

endPtr += (+(str[endPtr] === ','))
}

return [ parsed, endPtr ]
}

Expand Down
8 changes: 4 additions & 4 deletions src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { extractValue } from './extract.js'
import { type TomlPrimitive, skipVoid } from './util.js'
import TomlError from './error.js'

const enum Type { DOTTED, EXPLICIT, ARRAY }
const enum Type { DOTTED, EXPLICIT, ARRAY, ARRAY_DOTTED }

type MetaState = { t: Type, d: boolean, i: number, c: MetaRecord }
type MetaRecord = { [k: string]: MetaState }
Expand All @@ -49,7 +49,7 @@ function peekTable (key: string[], table: Record<string, TomlPrimitive>, meta: M
t = hasOwn! ? t[k!] : (t[k!] = {})
m = (state = m[k!]!).c

if (type === Type.DOTTED && state.t === Type.EXPLICIT) {
if (type === Type.DOTTED && (state.t === Type.EXPLICIT || state.t === Type.ARRAY)) {
return null
}

Expand All @@ -73,7 +73,7 @@ function peekTable (key: string[], table: Record<string, TomlPrimitive>, meta: M

m[k] = {
t: i < key.length - 1 && type === Type.ARRAY
? Type.DOTTED
? Type.ARRAY_DOTTED
: type,
d: false,
i: 0,
Expand All @@ -83,7 +83,7 @@ function peekTable (key: string[], table: Record<string, TomlPrimitive>, meta: M
}

state = m[k!]!
if (state.t !== type) {
if (state.t !== type && !(type === Type.EXPLICIT && state.t === Type.ARRAY_DOTTED)) {
// Bad key type!
return null
}
Expand Down
1 change: 1 addition & 0 deletions test/array.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ it('is not bothered by comments', () => {
it('rejects invalid arrays', () => {
expect(() => parseArray('[ 1,, 2]', 0)).toThrowError(TomlError)
expect(() => parseArray('[ 1, 2, 3 ', 0)).toThrowError(TomlError)
expect(() => parseArray('[ 1, "2" a, 3 ]', 0)).toThrowError(TomlError)
})

it('consumes only an array and aborts', () => {
Expand Down
3 changes: 2 additions & 1 deletion test/inlineTable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ it('parses inline tables', () => {
expect(parseInlineTable('{}', 0))
.toStrictEqual([ {}, 2 ])
})
it('parse inline tables with non traditional spaces',()=>{

it('parse inline tables with non traditional spaces',() => {
expect(parseInlineTable('{ first = "Tom" ,last = "Preston-Werner" }', 0))
.toStrictEqual([ { first: 'Tom', last: 'Preston-Werner' }, 42 ])
expect(parseInlineTable('{ first = "Tom" , last = "Preston-Werner" }', 0))
Expand Down
34 changes: 34 additions & 0 deletions test/parse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,17 @@ kind = "granny smith"
expect(() => parse(doc)).toThrowError(TomlError)
})

it('does not allow clashes between [[table.a]] and a dotted key within [table]', () => {
const doc = `
[[uwu.owo]]
[uwu]
owo.hehe = "meow!"
`.trim()

expect(() => parse(doc)).toThrowError(TomlError)
})

it('does not allow clashes between [table] and [[table]]', () => {
const doc = `
[uwu]
Expand Down Expand Up @@ -396,4 +407,27 @@ hehe = true
]
})
})

it('does NOT reject duplicate [tables] when the table was originally defined as an array', () => {
const doc = `
[[uwu.owo]]
hehe = true
[[uwu.owo]]
hehe = false
[uwu]
meow = "nya"
`.trim()

expect(parse(doc)).toStrictEqual({
uwu: {
owo: [
{ hehe: true },
{ hehe: false },
],
meow: "nya",
},
})
})
})
4 changes: 4 additions & 0 deletions toml-test-encode.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ function untagObject (obj) {
if (obj.value === 'inf') return Infinity
if (obj.value === '+inf') return Infinity
if (obj.value === '-inf') return -Infinity

if (obj.value === 'Inf') return Infinity
if (obj.value === '+Inf') return Infinity
if (obj.value === '-Inf') return -Infinity
return Number(obj.value)
case 'datetime':
case 'datetime-local':
Expand Down

0 comments on commit 9b024b2

Please sign in to comment.