go-yaml icon indicating copy to clipboard operation
go-yaml copied to clipboard

Panic with invalid data

Open johejo opened this issue 4 years ago • 3 comments

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

johejo avatar Jan 25 '21 17:01 johejo

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?

justinrush avatar Jun 09 '21 17:06 justinrush

@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).

ernado avatar Sep 29 '21 05:09 ernado