-
-
Notifications
You must be signed in to change notification settings - Fork 218
Multi-line text fields corrupted when using custom marshalers #845
Copy link
Copy link
Open
Description
https://go.dev/play/p/zEajxshUE_y
I have a reliable bug from the following YAML snippet, which is output of a custom encoder:
container:
type: generic
config:
message: |-
some test text
second line of the textNote the corrupted text. The inner struct, if marshaled properly should produce output like:
container:
type: generic
config:
message: |-
some test text
second line of the textWhen it hits this line:
Line 911 in 92bc79c
| if e.isMapNode(encoded) { |
e.AddColumn is called, the multiline text field indentation is corrupted.
This only happens when a custom encoder is embedding the output into the key of another struct. The following program reproduces the problem:
package main
import (
"bytes"
"fmt"
"github.com/goccy/go-yaml"
)
type D struct {
Message string
}
type T struct {
Type string
Config interface{}
}
type O struct {
Container interface{}
}
func main() {
marshaler := func(t D) ([]byte, error) {
return yaml.Marshal(&T{
"generic",
t,
})
}
testStruct := &O{&D{
Message: "some test text\nsecond line of the text",
}}
b := bytes.NewBuffer(nil)
err := yaml.NewEncoder(b, yaml.CustomMarshaler(marshaler)).Encode(testStruct)
fmt.Println(err)
fmt.Println(b.String())
}EDIT:
Further investigation seems to indicate this is a general problem with embedded multiline text in version v1.19.2 from any marshalers - https://go.dev/play/p/sH6LhtCIzAB
package main
import (
"bytes"
"fmt"
"github.com/goccy/go-yaml"
)
type D struct {
Message string
}
type X struct {
Type string
Config interface{}
}
func (x *X) MarshalYAML() ([]byte, error) {
return yaml.Marshal(map[string]interface{}{
"type": "generic",
"config": x.Config,
})
}
type O struct {
Container interface{}
}
func main() {
testStruct3 := &O{
&X{
"generic",
&D{"some test text\nsecond line of the text"},
},
}
b3 := bytes.NewBuffer(nil)
err := yaml.NewEncoder(b3).Encode(testStruct3)
fmt.Println(err)
fmt.Println(b3.String())
}container:
config:
message: |-
some test text
second line of the text
type: generic
EDIT 2: Extremizing the example makes it clear what's happening it looks like -
https://go.dev/play/p/KsNas3IMiVw
package main
import (
"bytes"
"fmt"
"github.com/goccy/go-yaml"
)
type D struct {
Message string
}
type X struct {
Type string
Config interface{}
}
func (x *X) MarshalYAML() ([]byte, error) {
return yaml.Marshal(map[string]interface{}{
"type": "generic",
"config": x.Config,
})
}
type O struct {
Container interface{}
}
func main() {
message := "some test text\nsecond line of the text"
testStruct3 := &O{&O{&O{
&O{&O{
&X{
"generic",
&D{message},
},
},
}}},
}
b3 := bytes.NewBuffer(nil)
yaml.NewEncoder(b3).Encode(testStruct3)
fmt.Println(b3.String())
}container:
container:
container:
container:
container:
config:
message: |-
some test text
second line of the text
type: generic
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels