go-libp2p-core/peer/addrinfo_serde.go
Steven Allen 648dc3fba2
feat: harden encoding/decoding functions against panics (#243)
* feat: harden encoding/decoding functions against panics

Part of https://github.com/libp2p/go-libp2p/issues/1389

These kinds of functions:

1. Handle user input.
2. Often have out-of-bounds, null pointer, etc bugs.
3. Have completely isolated logic where local panics are unlikely to
   cause memory corruption elsewhere.

* test: add a panic catcher test
2022-04-18 12:40:37 -07:00

48 lines
1.0 KiB
Go

package peer
import (
"encoding/json"
"github.com/libp2p/go-libp2p-core/internal/catch"
ma "github.com/multiformats/go-multiaddr"
)
// Helper struct for decoding as we can't unmarshal into an interface (Multiaddr).
type addrInfoJson struct {
ID ID
Addrs []string
}
func (pi AddrInfo) MarshalJSON() (res []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "libp2p addr info marshal") }()
addrs := make([]string, len(pi.Addrs))
for i, addr := range pi.Addrs {
addrs[i] = addr.String()
}
return json.Marshal(&addrInfoJson{
ID: pi.ID,
Addrs: addrs,
})
}
func (pi *AddrInfo) UnmarshalJSON(b []byte) (err error) {
defer func() { catch.HandlePanic(recover(), &err, "libp2p addr info unmarshal") }()
var data addrInfoJson
if err := json.Unmarshal(b, &data); err != nil {
return err
}
addrs := make([]ma.Multiaddr, len(data.Addrs))
for i, addr := range data.Addrs {
maddr, err := ma.NewMultiaddr(addr)
if err != nil {
return err
}
addrs[i] = maddr
}
pi.ID = data.ID
pi.Addrs = addrs
return nil
}