-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Open
Description
There are some cases jsoniter
behaves incorrectly when marshaling map/object with indention.
- Nested map/obj/slice inside map encoding using
sortedKeysMapEncoder
have incorrect indentions.
func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
// ...
subStream := stream.cfg.BorrowStream(nil)
subStream.Attachment = stream.Attachment
// ...
stream.cfg.ReturnStream(subStream)
}
The stream
borrowed from sync.Pool
always has 0 initial indention and returned with 0 indention. So when processing nested elements if SortMapKeys: true
is configured inside the Config
, the encoding will always have a single unit of indention step. eg.
var json = jsoniter.ConfigCompatibleWithStandardLibrary
var obj interface{}
var x []byte
obj = map[int]map[int]int{1: {1: 2}}
x, _ = json.MarshalIndent(obj, "", " ")
fmt.Println(string(x))
obj = map[int]map[int]int{1: {1: 2}}
x, _ = json.MarshalIndent(obj, "", " ")
fmt.Println(string(x))
obj = map[int]struct{ F int }{1: {F: 2}}
x, _ = json.MarshalIndent(obj, "", " ")
fmt.Println(string(x))
Results:
{
"1": [
1,
2
]
}
{
"1": {
"1": 2
}
}
{
"1": {
"F": 2
}
}
Expects:
{
"1": [
1,
2
]
}
{
"1": {
"1": 2
}
}
{
"1": {
"F": 2
}
}
- Empty map or object with no fields to be marshaled has redundant indention introduced by
(*Stream).WriteObjectStart
.- Empty map is not recognized as an empty object to be written by a Stream.
- Object that all fields with
omitempty
tag will have redundant indention if these exported fields are all empty.
var json = jsoniter.ConfigCompatibleWithStandardLibrary
var obj interface{}
var x []byte
obj = map[int]int{}
x, _ = json.MarshalIndent(obj, "", " ")
fmt.Println(string(x))
obj = struct {
Empty int `json:"empty,omitempty"`
}{}
x, _ = json.MarshalIndent(obj, "", " ")
fmt.Println(string(x))
Results:
{
}
{
}
Expects:
{}
{}
Metadata
Metadata
Assignees
Labels
No labels