Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Empty !!null node fails encoding and causes panic #1014

Open
TristanSpeakEasy opened this issue Jan 18, 2024 · 0 comments
Open

Empty !!null node fails encoding and causes panic #1014

TristanSpeakEasy opened this issue Jan 18, 2024 · 0 comments

Comments

@TristanSpeakEasy
Copy link

Consider this reproducible:

package main

import (
	"fmt"

	"gopkg.in/yaml.v3"
)

func createIntNode(str string) *yaml.Node {
	n := &yaml.Node{
		Kind:  yaml.ScalarNode,
		Tag:   "!!int",
		Value: str,
	}
	return n
}

func createEmptyNullNode() *yaml.Node {
	n := &yaml.Node{
		Kind:  yaml.ScalarNode,
		Tag:   "!!null",
		Value: "",
	}
	return n
}

func encodeNode(node *yaml.Node) error {
	var rawNode yaml.Node
	if err := rawNode.Encode(node); err != nil {
		return err
	}

	var v interface{}
	if err := rawNode.Decode(&v); err != nil {
		return err
	}

	fmt.Println(v)

	return nil
}

func main() {
	err := encodeNode(createIntNode("1"))
	if err != nil {
		panic(err)
	}

	yamlDoc := `key:`

	var node yaml.Node
	if err := yaml.Unmarshal([]byte(yamlDoc), &node); err != nil {
		panic(err)
	}

	err = encodeNode(node.Content[0].Content[1])
	if err != nil {
		panic(err)
	}

	err = encodeNode(createEmptyNullNode())
	if err != nil {
		panic(err)
	}

	fmt.Println("done")
}

this causes this panic:

go run main.go
1
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=0x48 pc=0x4ea2f3]

goroutine 1 [running]:
gopkg.in/yaml%2ev3.handleErr(0xc00015dbc8)
        /home/trist/go/pkg/mod/gopkg.in/yaml.v3@v3.0.1/yaml.go:294 +0x6d
panic({0x4fda80?, 0x5ea890?})
        /home/linuxbrew/.linuxbrew/opt/go/libexec/src/runtime/panic.go:914 +0x21f
gopkg.in/yaml%2ev3.(*Node).Encode(0xc000144820, {0x5071a0, 0xc000144780})
        /home/trist/go/pkg/mod/gopkg.in/yaml.v3@v3.0.1/yaml.go:269 +0x593
main.encodeNode(0xc000136598?)
        /home/trist/workspace/scratch/main.go:29 +0x3b
main.main()
        /home/trist/workspace/scratch/main.go:56 +0xdb

as far as I can see a key in a yaml document can have no value and it is meant to be interpreted as a null value. https://stackoverflow.com/a/64462925

Which is fine when unmarshalling the document but I have code that is then also trying to marshal yaml again (and I'm working with yaml.Node instead of go models of the document to control ordering etc of maps)

And it blows up when Encoding this particular type of node.

The reason is pretty clear here: https://github.com/go-yaml/yaml/blob/v3/yaml.go#L269

func (n *Node) Encode(v interface{}) (err error) {
	defer handleErr(&err)
	e := newEncoder()
	defer e.destroy()
	e.marshalDoc("", reflect.ValueOf(v))
	e.finish()
	p := newParser(e.out)
	p.textless = true
	defer p.destroy()
	doc := p.parse()
	*n = *doc.Content[0]
	return nil
}

The value returned from p.parse() is nil and then this is dereferenced without any nil check

@TristanSpeakEasy TristanSpeakEasy changed the title Empty !!null node fails encoding Empty !!null node fails encoding and causes panic Jan 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant