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

Different behavior from "encoding/json"

Open hoslo opened this issue 3 years ago • 1 comments

package main

import (
	"encoding/json"
	"fmt"

	gojson "github.com/goccy/go-json"
)

type Media []*Image

type Image struct {
	Pos      Pos    `json:"pos"`
	OldURL   string `json:"old_url"`
	FileName string `json:"file_name"`
	URL      string `json:"url"`
}

type BlockType struct {
	Tag string `json:"tag"`
}

type Blocks struct {
	Points    string    `json:"points"`
	BlockURL  string    `json:"block_url"`
	Result    string    `json:"result"`
	OldResult int       `json:"old_result"`
	Angle     int       `json:"angle"`
	BlockType BlockType `json:"block_type"`
}

type Pos struct {
	Blocks []Blocks `json:"blocks"`
	Angle  int      `json:"angle"`
}

func main() {
	var a Media
	err := gojson.Unmarshal([]byte(`[{"url":"8621_E4B5B8C2A88E456CSR7TX7h6.jpg","old_url":"8621_E4B5B8C2A88E456CSR7TX7h6.jpg","file_name":"8621_E4B5B8C2A88E456CSR7TX7h6.jpg","pos":{"blocks":{}}},{"url":"8621_94AC337652D44DBDDR7rY93K.jpg","old_url":"8621_94AC337652D44DBDDR7rY93K.jpg","file_name":"8621_94AC337652D44DBDDR7rY93K.jpg","pos":{"angle":0,"blocks":[{"angle":0,"old_result":2,"result":"wrong","block_type":{"tag":"1_1_1"},"points":"242,199,322,198,321,296,241,297"}]}}]`), &a)
	fmt.Println(err)  // output:  json: slice unexpected end of JSON input
	fmt.Println(a)    // output:  []


	var a1 Media
	err = json.Unmarshal([]byte(`[{"url":"8621_E4B5B8C2A88E456CSR7TX7h6.jpg","old_url":"8621_E4B5B8C2A88E456CSR7TX7h6.jpg","file_name":"8621_E4B5B8C2A88E456CSR7TX7h6.jpg","pos":{"blocks":{}}},{"url":"8621_94AC337652D44DBDDR7rY93K.jpg","old_url":"8621_94AC337652D44DBDDR7rY93K.jpg","file_name":"8621_94AC337652D44DBDDR7rY93K.jpg","pos":{"angle":0,"blocks":[{"angle":0,"old_result":2,"result":"wrong","block_type":{"tag":"1_1_1"},"points":"242,199,322,198,321,296,241,297"}]}}]`), &a1)
	fmt.Println(err)    // output:    cannot unmarshal object into Go struct field Pos.pos.blocks of type []main.Blocks
	fmt.Println(a1)     // output:    [0xc0000fc460 0xc0000fc500]
}

hoslo avatar Jan 28 '22 06:01 hoslo

Smaller reproducible code:

func TestIssue330(t *testing.T) {
	type T struct {
		A int   `json:"a"`
		B []int `json:"b"`
	}

	in := `[{"a":1},{"a":2,"b":{}},{}]`
	var a []T
	err := json.Unmarshal([]byte(in), &a)
	fmt.Println(err) // output:  json: slice unexpected end of JSON input
	fmt.Println(a)   // output:  []

	var a1 []T
	err = stdjson.Unmarshal([]byte(in), &a1)
	fmt.Println(err) // output:    json: cannot unmarshal object into Go struct field T.b of type []int
	fmt.Println(a1)  // output:    [{1 []} {2 []} {0 []}]
}

The problem is that the behavior is not compatible with encoding/json when the slice contains an object with a property of an unexpected type.

orisano avatar Jan 28 '22 07:01 orisano