goccy / go-yaml

YAML support for the Go language
MIT License
1.12k stars 129 forks source link

Panic with invalid data #191

Open johejo opened 3 years ago

johejo commented 3 years ago

Found in go-fuzz https://github.com/dvyukov/go-fuzz

Bad inputs have panic. Some may have the same cause.

package yaml_test

import (
    "testing"

    "github.com/goccy/go-yaml"
)

func TestPanic1(t *testing.T) {
    data := []byte("0::")
    var i interface{}
    yaml.Unmarshal(data, &i)
}

func TestPanic2(t *testing.T) {
    data := []byte("{0")
    var i interface{}
    yaml.Unmarshal(data, &i)
}

func TestPanic3(t *testing.T) {
    data := []byte("*-0")
    var i interface{}
    yaml.Unmarshal(data, &i)
}

func TestPanic4(t *testing.T) {
    data := []byte(">\n>")
    var i interface{}
    yaml.Unmarshal(data, &i)
}

func TestPanic5(t *testing.T) {
    data := []byte("&{0")
    var i interface{}
    yaml.Unmarshal(data, &i)
}

func TestPanic6(t *testing.T) {
    data := []byte("0_")
    var i interface{}
    yaml.Unmarshal(data, &i)
}

Output

=== RUN   TestPanic1
--- FAIL: TestPanic1 (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x55354f]

goroutine 19 [running]:
testing.tRunner.func1.1(0x6439c0, 0x80d490)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1072 +0x30d
testing.tRunner.func1(0xc000103500)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1075 +0x41a
panic(0x6439c0, 0x80d490)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/runtime/panic.go:969 +0x1b9
github.com/goccy/go-yaml/parser.(*parser).validateMapValue(0xc00006ec78, 0xc0002f24e0, 0x6dc560, 0xc0002f81a0, 0x0, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:174 +0x4f
github.com/goccy/go-yaml/parser.(*parser).parseMappingValue(0xc00016bc78, 0xc0002f24e0, 0x1, 0xc00006eb90, 0x40fa18, 0x30)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:212 +0x23d
github.com/goccy/go-yaml/parser.(*parser).parseToken(0xc00006ec78, 0xc0002f24e0, 0xc00012cff0, 0x0, 0xc0002f24e0, 0xc0002f8160, 0x3)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:508 +0x554
github.com/goccy/go-yaml/parser.(*parser).parse(0xc00016bc78, 0xc0002f8160, 0x3, 0x4, 0x0, 0x0, 0x0, 0x3)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:549 +0x105
github.com/goccy/go-yaml/parser.Parse(0xc0002f8160, 0x3, 0x4, 0x0, 0x4, 0xc00006ed00, 0x4e04f7)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:585 +0x57
github.com/goccy/go-yaml/parser.ParseBytes(0xc0002e7040, 0x3, 0x40, 0x0, 0xc0002f24b0, 0x3, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:575 +0x8d
github.com/goccy/go-yaml.(*Decoder).parse(0xc0001422c0, 0xc0002e7040, 0x3, 0x40, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1374 +0x55
github.com/goccy/go-yaml.(*Decoder).decodeInit(0xc0001422c0, 0x16, 0x16)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1402 +0xe9
github.com/goccy/go-yaml.(*Decoder).DecodeContext(0xc0001422c0, 0x6daae0, 0xc000124010, 0x62a900, 0xc000241df0, 0x4f0de4, 0x77a2a0)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1450 +0x258
github.com/goccy/go-yaml.UnmarshalWithContext(0x6daae0, 0xc000124010, 0xc0002ebad8, 0x3, 0x3, 0x62a900, 0xc000241df0, 0x0, 0x0, 0x0, ...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:191 +0x1c5
github.com/goccy/go-yaml.UnmarshalWithOptions(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:185
github.com/goccy/go-yaml.Unmarshal(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:179
github.com/goccy/go-yaml_test.TestPanic1(0xc000103500)
    /home/heijo/ghq/github.com/goccy/go-yaml/bugs_test.go:12 +0xb4
testing.tRunner(0xc000103500, 0x695338)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1123 +0xef
created by testing.(*T).Run
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1168 +0x2b3
FAIL    github.com/goccy/go-yaml    0.005s
FAIL
=== RUN   TestPanic2
--- FAIL: TestPanic2 (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x38 pc=0x5533ad]

goroutine 6 [running]:
testing.tRunner.func1.1(0x6439c0, 0x80d490)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1072 +0x30d
testing.tRunner.func1(0xc00018e780)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1075 +0x41a
panic(0x6439c0, 0x80d490)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/runtime/panic.go:969 +0x1b9
github.com/goccy/go-yaml/parser.(*parser).createNullToken(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:132
github.com/goccy/go-yaml/parser.(*parser).parseMapValue(0xc000073c78, 0xc0002e04e0, 0x6dc560, 0xc0002e61a0, 0x0, 0x0, 0x10, 0x10, 0x652d20)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:140 +0x42d
github.com/goccy/go-yaml/parser.(*parser).parseMappingValue(0xc0000e1c78, 0xc0002e04e0, 0x0, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:208 +0x1d4
github.com/goccy/go-yaml/parser.(*parser).parseMapping(0xc0000e1c78, 0xc0002e04e0, 0xc000013090, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:30 +0x1e5
github.com/goccy/go-yaml/parser.(*parser).parseToken(0xc000073c78, 0xc0002e04e0, 0xc000013090, 0x0, 0xc0002e04e0, 0xc00022de20, 0x2)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:526 +0x1b5
github.com/goccy/go-yaml/parser.(*parser).parse(0xc0000e1c78, 0xc00022de20, 0x2, 0x2, 0x0, 0x0, 0x1, 0x3)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:549 +0x105
github.com/goccy/go-yaml/parser.Parse(0xc00022de20, 0x2, 0x2, 0x0, 0x2, 0xc000073d00, 0x4e04f7)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:585 +0x57
github.com/goccy/go-yaml/parser.ParseBytes(0xc0002cd1c0, 0x2, 0x40, 0x0, 0xc0002e04b0, 0x2, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:575 +0x8d
github.com/goccy/go-yaml.(*Decoder).parse(0xc0000b82c0, 0xc0002cd1c0, 0x2, 0x40, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1374 +0x55
github.com/goccy/go-yaml.(*Decoder).decodeInit(0xc0000b82c0, 0x16, 0x16)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1402 +0xe9
github.com/goccy/go-yaml.(*Decoder).DecodeContext(0xc0000b82c0, 0x6daae0, 0xc00001a0f0, 0x62a900, 0xc00022de10, 0x4f0de4, 0x77a2a0)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1450 +0x258
github.com/goccy/go-yaml.UnmarshalWithContext(0x6daae0, 0xc00001a0f0, 0xc0002d7bb8, 0x2, 0x2, 0x62a900, 0xc00022de10, 0x0, 0x0, 0x0, ...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:191 +0x1c5
github.com/goccy/go-yaml.UnmarshalWithOptions(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:185
github.com/goccy/go-yaml.Unmarshal(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:179
github.com/goccy/go-yaml_test.TestPanic2(0xc00018e780)
    /home/heijo/ghq/github.com/goccy/go-yaml/bugs_test.go:18 +0xb0
testing.tRunner(0xc00018e780, 0x695340)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1123 +0xef
created by testing.(*T).Run
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1168 +0x2b3
FAIL    github.com/goccy/go-yaml    0.005s
FAIL
=== RUN   TestPanic3
--- FAIL: TestPanic3 (0.00s)
panic: runtime error: index out of range [2] with length 2 [recovered]
    panic: runtime error: index out of range [2] with length 2

goroutine 19 [running]:
testing.tRunner.func1.1(0x66a600, 0xc0002e9a60)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1072 +0x30d
testing.tRunner.func1(0xc000103500)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1075 +0x41a
panic(0x66a600, 0xc0002e9a60)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/runtime/panic.go:969 +0x1b9
github.com/goccy/go-yaml/ast.Integer(0xc00012d040, 0xa0, 0x203000)
    /home/heijo/ghq/github.com/goccy/go-yaml/ast/ast.go:239 +0xbea
github.com/goccy/go-yaml/parser.(*parser).parseScalarValue(0xc00006ec78, 0xc00012d040, 0x652d20, 0x203000)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:373 +0x44f
github.com/goccy/go-yaml/parser.(*parser).parseScalarValueWithComment(0xc00016dc78, 0xc0002f24e0, 0xc00012d040, 0xc00006eab0, 0x40fa18, 0x10, 0x652d20)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:347 +0x3c
github.com/goccy/go-yaml/parser.(*parser).parseToken(0xc00016dc78, 0xc0002f24e0, 0xc00012d040, 0xc00006ec78, 0xc00012cff0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:511 +0x67
github.com/goccy/go-yaml/parser.(*parser).parseAlias(0xc00006ec78, 0xc0002f24e0, 0xc00012cff0, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:314 +0x107
github.com/goccy/go-yaml/parser.(*parser).parseToken(0xc00006ec78, 0xc0002f24e0, 0xc00012cff0, 0x0, 0xc0002f24e0, 0xc000241e10, 0x2)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:534 +0x2d2
github.com/goccy/go-yaml/parser.(*parser).parse(0xc00016dc78, 0xc000241e10, 0x2, 0x2, 0x0, 0x0, 0x0, 0x3)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:549 +0x105
github.com/goccy/go-yaml/parser.Parse(0xc000241e10, 0x2, 0x2, 0x0, 0x2, 0xc00006ed00, 0x4e04f7)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:585 +0x57
github.com/goccy/go-yaml/parser.ParseBytes(0xc0002e7040, 0x3, 0x40, 0x0, 0xc0002f24b0, 0x3, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:575 +0x8d
github.com/goccy/go-yaml.(*Decoder).parse(0xc0001422c0, 0xc0002e7040, 0x3, 0x40, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1374 +0x55
github.com/goccy/go-yaml.(*Decoder).decodeInit(0xc0001422c0, 0x16, 0x16)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1402 +0xe9
github.com/goccy/go-yaml.(*Decoder).DecodeContext(0xc0001422c0, 0x6daae0, 0xc000124010, 0x62a900, 0xc000241e00, 0x4f0de4, 0x77a2a0)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1450 +0x258
github.com/goccy/go-yaml.UnmarshalWithContext(0x6daae0, 0xc000124010, 0xc0002ebad8, 0x3, 0x3, 0x62a900, 0xc000241e00, 0x0, 0x0, 0x0, ...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:191 +0x1c5
github.com/goccy/go-yaml.UnmarshalWithOptions(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:185
github.com/goccy/go-yaml.Unmarshal(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:179
github.com/goccy/go-yaml_test.TestPanic3(0xc000103500)
    /home/heijo/ghq/github.com/goccy/go-yaml/bugs_test.go:24 +0xb4
testing.tRunner(0xc000103500, 0x695348)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1123 +0xef
created by testing.(*T).Run
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1168 +0x2b3
FAIL    github.com/goccy/go-yaml    0.005s
FAIL
=== RUN   TestPanic4
--- FAIL: TestPanic4 (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x5565c9]

goroutine 6 [running]:
testing.tRunner.func1.1(0x6439c0, 0x80d490)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1072 +0x30d
testing.tRunner.func1(0xc00018e780)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1075 +0x41a
panic(0x6439c0, 0x80d490)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/runtime/panic.go:969 +0x1b9
github.com/goccy/go-yaml/parser.(*parser).parseLiteral(0xc000073c78, 0xc0002e0510, 0xc000013090, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:414 +0x189
github.com/goccy/go-yaml/parser.(*parser).parseToken(0xc000073c78, 0xc0002e0510, 0xc000013090, 0x0, 0xc0002e0510, 0xc0000101d0, 0x1)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:540 +0x435
github.com/goccy/go-yaml/parser.(*parser).parse(0xc0000e1c78, 0xc0000101d0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:549 +0x105
github.com/goccy/go-yaml/parser.Parse(0xc0000101d0, 0x1, 0x1, 0x0, 0x1, 0xc000073d00, 0x4e04f7)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:585 +0x57
github.com/goccy/go-yaml/parser.ParseBytes(0xc0002cd1c0, 0x3, 0x40, 0x0, 0xc0002e04b0, 0x3, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:575 +0x8d
github.com/goccy/go-yaml.(*Decoder).parse(0xc0000b82c0, 0xc0002cd1c0, 0x3, 0x40, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1374 +0x55
github.com/goccy/go-yaml.(*Decoder).decodeInit(0xc0000b82c0, 0x16, 0x16)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1402 +0xe9
github.com/goccy/go-yaml.(*Decoder).DecodeContext(0xc0000b82c0, 0x6daae0, 0xc00001a0f0, 0x62a900, 0xc00022de20, 0x4f0de4, 0x77a2a0)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1450 +0x258
github.com/goccy/go-yaml.UnmarshalWithContext(0x6daae0, 0xc00001a0f0, 0xc0002d7bb8, 0x3, 0x3, 0x62a900, 0xc00022de20, 0x0, 0x0, 0x0, ...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:191 +0x1c5
github.com/goccy/go-yaml.UnmarshalWithOptions(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:185
github.com/goccy/go-yaml.Unmarshal(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:179
github.com/goccy/go-yaml_test.TestPanic4(0xc00018e780)
    /home/heijo/ghq/github.com/goccy/go-yaml/bugs_test.go:30 +0xb4
testing.tRunner(0xc00018e780, 0x695350)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1123 +0xef
created by testing.(*T).Run
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1168 +0x2b3
FAIL    github.com/goccy/go-yaml    0.005s
FAIL
=== RUN   TestPanic5
--- FAIL: TestPanic5 (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x38 pc=0x5533ad]

goroutine 6 [running]:
testing.tRunner.func1.1(0x6439c0, 0x80d490)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1072 +0x30d
testing.tRunner.func1(0xc00018e780)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1075 +0x41a
panic(0x6439c0, 0x80d490)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/runtime/panic.go:969 +0x1b9
github.com/goccy/go-yaml/parser.(*parser).createNullToken(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:132
github.com/goccy/go-yaml/parser.(*parser).parseMapValue(0xc000073c78, 0xc0002e04e0, 0x6dc560, 0xc0002e61c0, 0x0, 0x0, 0x10, 0x10, 0x652d20)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:140 +0x42d
github.com/goccy/go-yaml/parser.(*parser).parseMappingValue(0xc0000e1c78, 0xc0002e04e0, 0x0, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:208 +0x1d4
github.com/goccy/go-yaml/parser.(*parser).parseMapping(0xc0000e1c78, 0xc0002e04e0, 0xc0000130e0, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:30 +0x1e5
github.com/goccy/go-yaml/parser.(*parser).parseToken(0xc000073c78, 0xc0002e04e0, 0xc0000130e0, 0xc000073b38, 0x55575c, 0xc000073c78, 0xc000013090)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:526 +0x1b5
github.com/goccy/go-yaml/parser.(*parser).parseAnchor(0xc0000e1c78, 0xc0002e04e0, 0xc000013090, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:288 +0x127
github.com/goccy/go-yaml/parser.(*parser).parseToken(0xc000073c78, 0xc0002e04e0, 0xc000013090, 0x0, 0xc0002e04e0, 0xc0002e6180, 0x3)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:532 +0x325
github.com/goccy/go-yaml/parser.(*parser).parse(0xc0000e1c78, 0xc0002e6180, 0x3, 0x4, 0x0, 0x0, 0x1, 0x3)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:549 +0x105
github.com/goccy/go-yaml/parser.Parse(0xc0002e6180, 0x3, 0x4, 0x0, 0x4, 0xc000073d00, 0x4e04f7)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:585 +0x57
github.com/goccy/go-yaml/parser.ParseBytes(0xc0002cd1c0, 0x3, 0x40, 0x0, 0xc0002e04b0, 0x3, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:575 +0x8d
github.com/goccy/go-yaml.(*Decoder).parse(0xc0000b82c0, 0xc0002cd1c0, 0x3, 0x40, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1374 +0x55
github.com/goccy/go-yaml.(*Decoder).decodeInit(0xc0000b82c0, 0x16, 0x16)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1402 +0xe9
github.com/goccy/go-yaml.(*Decoder).DecodeContext(0xc0000b82c0, 0x6daae0, 0xc00001a0f0, 0x62a900, 0xc00022de30, 0x4f0de4, 0x77a2a0)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1450 +0x258
github.com/goccy/go-yaml.UnmarshalWithContext(0x6daae0, 0xc00001a0f0, 0xc0002d7bb8, 0x3, 0x3, 0x62a900, 0xc00022de30, 0x0, 0x0, 0x0, ...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:191 +0x1c5
github.com/goccy/go-yaml.UnmarshalWithOptions(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:185
github.com/goccy/go-yaml.Unmarshal(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:179
github.com/goccy/go-yaml_test.TestPanic5(0xc00018e780)
    /home/heijo/ghq/github.com/goccy/go-yaml/bugs_test.go:36 +0xb4
testing.tRunner(0xc00018e780, 0x695358)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1123 +0xef
created by testing.(*T).Run
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1168 +0x2b3
FAIL    github.com/goccy/go-yaml    0.006s
FAIL
=== RUN   TestPanic6
--- FAIL: TestPanic6 (0.00s)
panic: runtime error: index out of range [1] with length 1 [recovered]
    panic: runtime error: index out of range [1] with length 1

goroutine 6 [running]:
testing.tRunner.func1.1(0x66a600, 0xc0002d5ea0)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1072 +0x30d
testing.tRunner.func1(0xc00018e780)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1075 +0x41a
panic(0x66a600, 0xc0002d5ea0)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/runtime/panic.go:969 +0x1b9
github.com/goccy/go-yaml/ast.Integer(0xc000013090, 0xc0002e04e0, 0x203000)
    /home/heijo/ghq/github.com/goccy/go-yaml/ast/ast.go:244 +0xbdd
github.com/goccy/go-yaml/parser.(*parser).parseScalarValue(0xc000073c78, 0xc000013090, 0x652e60, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:373 +0x44f
github.com/goccy/go-yaml/parser.(*parser).parseScalarValueWithComment(0xc0000e3c78, 0xc0002e04e0, 0xc000013090, 0xc000073b90, 0x40fa18, 0x30, 0x652e60)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:347 +0x3c
github.com/goccy/go-yaml/parser.(*parser).parseToken(0xc0000e3c78, 0xc0002e04e0, 0xc000013090, 0x0, 0xc0002e04e0, 0xc0000101c8, 0x1)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:511 +0x67
github.com/goccy/go-yaml/parser.(*parser).parse(0xc0000e3c78, 0xc0000101c8, 0x1, 0x1, 0x0, 0x0, 0x0, 0x3)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:549 +0x105
github.com/goccy/go-yaml/parser.Parse(0xc0000101c8, 0x1, 0x1, 0x0, 0x1, 0xc000073d00, 0x4e04f7)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:585 +0x57
github.com/goccy/go-yaml/parser.ParseBytes(0xc0002cd1c0, 0x2, 0x40, 0x0, 0xc0002e04b0, 0x2, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/parser/parser.go:575 +0x8d
github.com/goccy/go-yaml.(*Decoder).parse(0xc0000b82c0, 0xc0002cd1c0, 0x2, 0x40, 0x0, 0x0, 0x0)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1374 +0x55
github.com/goccy/go-yaml.(*Decoder).decodeInit(0xc0000b82c0, 0x16, 0x16)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1402 +0xe9
github.com/goccy/go-yaml.(*Decoder).DecodeContext(0xc0000b82c0, 0x6daae0, 0xc00001a0f0, 0x62a900, 0xc00022de40, 0x4f0de4, 0x77a2a0)
    /home/heijo/ghq/github.com/goccy/go-yaml/decode.go:1450 +0x258
github.com/goccy/go-yaml.UnmarshalWithContext(0x6daae0, 0xc00001a0f0, 0xc0002d7bb8, 0x2, 0x2, 0x62a900, 0xc00022de40, 0x0, 0x0, 0x0, ...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:191 +0x1c5
github.com/goccy/go-yaml.UnmarshalWithOptions(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:185
github.com/goccy/go-yaml.Unmarshal(...)
    /home/heijo/ghq/github.com/goccy/go-yaml/yaml.go:179
github.com/goccy/go-yaml_test.TestPanic6(0xc00018e780)
    /home/heijo/ghq/github.com/goccy/go-yaml/bugs_test.go:42 +0xb0
testing.tRunner(0xc00018e780, 0x695360)
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1123 +0xef
created by testing.(*T).Run
    /home/linuxbrew/.linuxbrew/Cellar/go/1.15.7/libexec/src/testing/testing.go:1168 +0x2b3
FAIL    github.com/goccy/go-yaml    0.005s
FAIL
justinrush commented 3 years ago

I'm seeing the same thing - oddly enough, it doesn't panic if pass something like []byte("[]wazza wazza woo"), but does panic if I pass slightly invalid json (missing a closing quote on level1.thing1):

{
    "level1": {
      "thing1: {
        "somevalue": []
      },
      "thing2": {
        "usefulthing": "bleh"
      }
    },
    "level2": {
      "widget1": {
        "meh": {}
      }
    }
    }

Its panicing in parser.validateMapValue on this line: valueColumn := value.GetToken().Position.Column

It seems that parser.parseMapValue (called in parser.parseMappingValue) can return nil for value. Should a check be added to parser.parseMapValue to return an error if value is nil? It looks like parser.parseToken can return nil values for several conditions, but looking at other areas of the codebase (such as ast.Integer as is one of the stack traces above), the code assumes the value is not nil. Should parser.parseToken simply return an error if value is nil?

ernado commented 2 years ago

@goccy gentle ping

func TestBadInput(t *testing.T) {
    for _, tt := range []struct{
        Input string
    } {
        {Input: "0::"},
        {Input: "{0"},
        {Input: "*-0"},
        {Input: ">\n>"},
        {Input: "&{0"},
        {Input: "0_"},
    } {
        t.Run(tt.Input, func(t *testing.T) {
            // Should not panic.
            var i interface{}
            _ = yaml.Unmarshal([]byte(tt.Input), &i)
        })
    }
}

Does not panic with such patch:

diff --git a/ast/ast.go b/ast/ast.go
index 83b1ee6..5d528df 100644
--- a/ast/ast.go
+++ b/ast/ast.go
@@ -328,7 +329,7 @@ func Integer(tk *token.Token) Node {
            }
            negativePrefix = "-"
        } else {
-           if value[1] == 'o' {
+           if len(value) > 1 && value[1] == 'o' {
                skipCharacterNum++
            }
        }
diff --git a/parser/parser.go b/parser/parser.go
index fcbd3bd..5ebb822 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -185,6 +186,9 @@ func (p *parser) createMapValueNode(ctx *context, key ast.Node, colonToken *toke
 }

 func (p *parser) validateMapValue(ctx *context, key, value ast.Node) error {
+   if value == nil {
+       return nil
+   }
    keyColumn := key.GetToken().Position.Column
    valueColumn := value.GetToken().Position.Column
    if keyColumn != valueColumn {
@@ -449,6 +453,9 @@ func (p *parser) parseLiteral(ctx *context) (ast.Node, error) {
    ctx.progress(1) // skip literal/folded token

    tk := ctx.currentToken()
+   if tk == nil {
+       return nil, errors.ErrSyntax("expected token, but got none", tk)
+   }
    var comment *ast.CommentGroupNode
    if tk.Type == token.CommentType {
        comment = p.parseCommentOnly(ctx)

But I'm not sure that it is correct because I don't know yaml spec.

This issue concerns me as potential DoS attack vector, I can submit a PR if my patch is ok (but I still think that you know better way to deal with such cases).

mx-psi commented 2 months ago

I can reproduce a similar panic with input data [invalid:,: https://go.dev/play/p/mZ3btWag26C. This makes the library unusable for us.