mirror of
https://github.com/libp2p/go-libp2p-core.git
synced 2026-08-18 15:03:28 +08:00
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
This commit is contained in:
@@ -3,6 +3,7 @@ package peer
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/internal/catch"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
@@ -12,7 +13,9 @@ type addrInfoJson struct {
|
||||
Addrs []string
|
||||
}
|
||||
|
||||
func (pi AddrInfo) MarshalJSON() ([]byte, error) {
|
||||
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()
|
||||
@@ -23,7 +26,8 @@ func (pi AddrInfo) MarshalJSON() ([]byte, error) {
|
||||
})
|
||||
}
|
||||
|
||||
func (pi *AddrInfo) UnmarshalJSON(b []byte) error {
|
||||
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
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/internal/catch"
|
||||
pb "github.com/libp2p/go-libp2p-core/peer/pb"
|
||||
"github.com/libp2p/go-libp2p-core/record"
|
||||
|
||||
@@ -160,13 +161,15 @@ func (r *PeerRecord) Codec() []byte {
|
||||
// This method is called automatically when consuming a record.Envelope
|
||||
// whose PayloadType indicates that it contains a PeerRecord.
|
||||
// It is generally not necessary or recommended to call this method directly.
|
||||
func (r *PeerRecord) UnmarshalRecord(bytes []byte) error {
|
||||
func (r *PeerRecord) UnmarshalRecord(bytes []byte) (err error) {
|
||||
if r == nil {
|
||||
return fmt.Errorf("cannot unmarshal PeerRecord to nil receiver")
|
||||
}
|
||||
|
||||
defer func() { catch.HandlePanic(recover(), &err, "libp2p peer record unmarshal") }()
|
||||
|
||||
var msg pb.PeerRecord
|
||||
err := proto.Unmarshal(bytes, &msg)
|
||||
err = proto.Unmarshal(bytes, &msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -183,7 +186,9 @@ func (r *PeerRecord) UnmarshalRecord(bytes []byte) error {
|
||||
// MarshalRecord serializes a PeerRecord to a byte slice.
|
||||
// This method is called automatically when constructing a routing.Envelope
|
||||
// using Seal or PeerRecord.Sign.
|
||||
func (r *PeerRecord) MarshalRecord() ([]byte, error) {
|
||||
func (r *PeerRecord) MarshalRecord() (res []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "libp2p peer record marshal") }()
|
||||
|
||||
msg, err := r.ToProtobuf()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user