BurntSushi / toml

TOML parser for Golang with reflection.
MIT License
4.53k stars 527 forks source link

metadata.Keys (and thus metadata.Undecoded) is invalid in some cases #417

Open maroux opened 2 months ago

maroux commented 2 months ago

Sample code:

package main

import (
    "fmt"

    "github.com/BurntSushi/toml"
)

func main() {
    content := `[table.subtable.subsubtable]
a = 1
b = 2
`
    var v interface{}
    metadata, err := toml.Decode(content, &v)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%#v\n", metadata.Keys())
}

Playground: https://go.dev/play/p/Rr5bm5DbEql

Output:

[]toml.Key{toml.Key{"table", "subtable", "subsubtable"}, toml.Key{"table", "subtable", "subsubtable", "b"}, toml.Key{"table", "subtable", "subsubtable", "b"}}

Notice how the second and third value in that slice both point to b.

Expected output:

[]toml.Key{toml.Key{"table", "subtable", "subsubtable"}, toml.Key{"table", "subtable", "subsubtable", "a"}, toml.Key{"table", "subtable", "subsubtable", "b"}}

The root cause seems to be somewhere near this append call. The result of append can return a slice backed by the same array if the capacity is available. See Go example code: https://go.dev/play/p/2FGKuCvCUKz.

maroux commented 2 months ago

I've opened 2 PRs with 2 possible fixes for this bug.

im-alex07 commented 1 month ago

Output:

[]toml.Key{toml.Key{"table", "subtable", "subsubtable"}, toml.Key{"table", "subtable", "subsubtable", "b"}, toml.Key{"table", "subtable", "subsubtable", "b"}}

Notice how the second and third value in that slice both point to b.

I also encountered this bug. Please fix it.