From ee67b32c335cecab3d5f27bf672d5b3bdcf0258a Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 12 Feb 2021 15:53:38 +0800 Subject: [PATCH 1/3] fix JSON deserialization of peer.AddrInfo --- peer/addrinfo_serde.go | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/peer/addrinfo_serde.go b/peer/addrinfo_serde.go index 1df24e2b..3ff6b28a 100644 --- a/peer/addrinfo_serde.go +++ b/peer/addrinfo_serde.go @@ -19,19 +19,23 @@ func (pi AddrInfo) MarshalJSON() ([]byte, error) { func (pi *AddrInfo) UnmarshalJSON(b []byte) error { var data map[string]interface{} - err := json.Unmarshal(b, &data) - if err != nil { + if err := json.Unmarshal(b, &data); err != nil { return err } - pid, err := IDB58Decode(data["ID"].(string)) - if err != nil { - return err + if id, ok := data["ID"]; ok { + if idString, ok := id.(string); ok { + pid, err := IDB58Decode(idString) + if err != nil { + return err + } + pi.ID = pid + } } - pi.ID = pid - addrs, ok := data["Addrs"].([]interface{}) - if ok { - for _, a := range addrs { - pi.Addrs = append(pi.Addrs, ma.StringCast(a.(string))) + if addrsEntry, ok := data["Addrs"]; ok { + if addrs, ok := addrsEntry.([]interface{}); ok { + for _, a := range addrs { + pi.Addrs = append(pi.Addrs, ma.StringCast(a.(string))) + } } } return nil From 9f33b0e288023fc1c85a1145355f7ad5287b5e25 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 12 Feb 2021 21:41:09 +0800 Subject: [PATCH 2/3] add a test case for JSON encoding / decoding of AddrInfo --- peer/addrinfo_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/peer/addrinfo_test.go b/peer/addrinfo_test.go index b902fdf3..5d1ce0a9 100644 --- a/peer/addrinfo_test.go +++ b/peer/addrinfo_test.go @@ -133,3 +133,21 @@ func TestAddrInfosFromP2pAddrs(t *testing.T) { delete(expected, info.ID.Pretty()) } } + +func TestAddrInfoJSON(t *testing.T) { + ai := AddrInfo{ID: testID, Addrs: []ma.Multiaddr{maddrFull}} + out, err := ai.MarshalJSON() + if err != nil { + t.Fatal(err) + } + var addrInfo AddrInfo + if err := addrInfo.UnmarshalJSON(out); err != nil { + t.Fatal(err) + } + if addrInfo.ID != testID { + t.Fatalf("expected ID to equal %s, got %s", testID.Pretty(), addrInfo.ID.Pretty()) + } + if len(addrInfo.Addrs) != 1 || !addrInfo.Addrs[0].Equal(maddrFull) { + t.Fatalf("expected addrs to match %v, got %v", maddrFull, addrInfo.Addrs) + } +} From 43d94f1f0753b1e32fd5da38e0065ba9442e539c Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 12 Feb 2021 22:38:07 +0800 Subject: [PATCH 3/3] reject JSON serialized AddrInfo if the ID is missing --- peer/addrinfo_serde.go | 17 ++++++++++------- peer/addrinfo_test.go | 39 ++++++++++++++++++++++++--------------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/peer/addrinfo_serde.go b/peer/addrinfo_serde.go index 3ff6b28a..1afeddfb 100644 --- a/peer/addrinfo_serde.go +++ b/peer/addrinfo_serde.go @@ -2,6 +2,7 @@ package peer import ( "encoding/json" + "errors" ma "github.com/multiformats/go-multiaddr" ) @@ -22,14 +23,16 @@ func (pi *AddrInfo) UnmarshalJSON(b []byte) error { if err := json.Unmarshal(b, &data); err != nil { return err } - if id, ok := data["ID"]; ok { - if idString, ok := id.(string); ok { - pid, err := IDB58Decode(idString) - if err != nil { - return err - } - pi.ID = pid + id, ok := data["ID"] + if !ok { + return errors.New("no peer ID") + } + if idString, ok := id.(string); ok { + pid, err := IDB58Decode(idString) + if err != nil { + return err } + pi.ID = pid } if addrsEntry, ok := data["Addrs"]; ok { if addrs, ok := addrsEntry.([]interface{}); ok { diff --git a/peer/addrinfo_test.go b/peer/addrinfo_test.go index 5d1ce0a9..ef2cf50c 100644 --- a/peer/addrinfo_test.go +++ b/peer/addrinfo_test.go @@ -135,19 +135,28 @@ func TestAddrInfosFromP2pAddrs(t *testing.T) { } func TestAddrInfoJSON(t *testing.T) { - ai := AddrInfo{ID: testID, Addrs: []ma.Multiaddr{maddrFull}} - out, err := ai.MarshalJSON() - if err != nil { - t.Fatal(err) - } - var addrInfo AddrInfo - if err := addrInfo.UnmarshalJSON(out); err != nil { - t.Fatal(err) - } - if addrInfo.ID != testID { - t.Fatalf("expected ID to equal %s, got %s", testID.Pretty(), addrInfo.ID.Pretty()) - } - if len(addrInfo.Addrs) != 1 || !addrInfo.Addrs[0].Equal(maddrFull) { - t.Fatalf("expected addrs to match %v, got %v", maddrFull, addrInfo.Addrs) - } + t.Run("valid AddrInfo", func(t *testing.T) { + ai := AddrInfo{ID: testID, Addrs: []ma.Multiaddr{maddrFull}} + out, err := ai.MarshalJSON() + if err != nil { + t.Fatal(err) + } + var addrInfo AddrInfo + if err := addrInfo.UnmarshalJSON(out); err != nil { + t.Fatal(err) + } + if addrInfo.ID != testID { + t.Fatalf("expected ID to equal %s, got %s", testID.Pretty(), addrInfo.ID.Pretty()) + } + if len(addrInfo.Addrs) != 1 || !addrInfo.Addrs[0].Equal(maddrFull) { + t.Fatalf("expected addrs to match %v, got %v", maddrFull, addrInfo.Addrs) + } + }) + t.Run("missing ID", func(t *testing.T) { + s := []byte(`{"Addrs":["/ip4/127.0.0.1/tcp/1234/p2p/QmS3zcG7LhYZYSJMhyRZvTddvbNUqtt8BJpaSs6mi1K5Va"]}`) + var addrInfo AddrInfo + if err := addrInfo.UnmarshalJSON(s); err == nil || err.Error() != "no peer ID" { + t.Fatalf("expected no peer ID error, got %v", err) + } + }) }