Skip to content

Commit 3674b42

Browse files
authored
feat(ipld): wrap bindnode with panic protection (#368)
* feat(ipld): wrap bindnode with panic protection * fix(src): fiximports
1 parent ed48027 commit 3674b42

16 files changed

+107
-44
lines changed

message/ipldbind/message.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ package ipldbind
22

33
import (
44
cid "github.com/ipfs/go-cid"
5-
"github.com/ipfs/go-graphsync/message"
65
"github.com/ipld/go-ipld-prime/datamodel"
76

87
"github.com/ipfs/go-graphsync"
8+
"github.com/ipfs/go-graphsync/message"
99
)
1010

1111
// GraphSyncExtensions is a container for representing extension data for

message/ipldbind/util.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package ipldbind
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/ipld/go-ipld-prime/datamodel"
7+
"github.com/ipld/go-ipld-prime/node/bindnode"
8+
"github.com/ipld/go-ipld-prime/schema"
9+
)
10+
11+
func SafeUnwrap(node datamodel.Node) (_ interface{}, err error) {
12+
defer func() {
13+
if r := recover(); r != nil {
14+
if rerr, ok := r.(error); ok {
15+
err = rerr
16+
} else {
17+
err = fmt.Errorf("%v", r)
18+
}
19+
}
20+
}()
21+
22+
ptr := bindnode.Unwrap(node)
23+
return ptr, err
24+
}
25+
26+
func SafeWrap(ptr interface{}, typ schema.Type) (_ schema.TypedNode, err error) {
27+
defer func() {
28+
if r := recover(); r != nil {
29+
if rerr, ok := r.(error); ok {
30+
err = rerr
31+
} else {
32+
err = fmt.Errorf("%v", r)
33+
}
34+
}
35+
}()
36+
37+
node := bindnode.Wrap(ptr, typ)
38+
return node, err
39+
}

message/v1/message.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,10 @@ func toEncodedExtensions(part message.MessagePartWithExtensions, linkMetadata gr
275275
linkMetadata.Iterate(func(c cid.Cid, la graphsync.LinkAction) {
276276
md = append(md, metadata.Item{Link: c, BlockPresent: la == graphsync.LinkActionPresent})
277277
})
278-
mdNode := metadata.EncodeMetadata(md)
278+
mdNode, err := metadata.EncodeMetadata(md)
279+
if err != nil {
280+
return nil, err
281+
}
279282
mdByts, err := ipldutil.EncodeNode(mdNode)
280283
if err != nil {
281284
return nil, err

message/v1/metadata/metadata.go

+10-6
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ package metadata
22

33
import (
44
"github.com/ipfs/go-cid"
5+
"github.com/ipld/go-ipld-prime/datamodel"
6+
57
"github.com/ipfs/go-graphsync"
68
"github.com/ipfs/go-graphsync/message"
7-
"github.com/ipld/go-ipld-prime/datamodel"
8-
"github.com/ipld/go-ipld-prime/node/bindnode"
9+
"github.com/ipfs/go-graphsync/message/ipldbind"
910
)
1011

1112
// Item is a single link traversed in a repsonse
@@ -44,11 +45,14 @@ func DecodeMetadata(data datamodel.Node) (Metadata, error) {
4445
if err != nil {
4546
return nil, err
4647
}
47-
metadata := bindnode.Unwrap(builder.Build()).(*Metadata)
48-
return *metadata, nil
48+
metadata, err := ipldbind.SafeUnwrap(builder.Build())
49+
if err != nil {
50+
return nil, err
51+
}
52+
return *(metadata.(*Metadata)), nil
4953
}
5054

5155
// EncodeMetadata encodes metadata to an IPLD node then serializes to raw bytes
52-
func EncodeMetadata(entries Metadata) datamodel.Node {
53-
return bindnode.Wrap(&entries, Prototype.Metadata.Type())
56+
func EncodeMetadata(entries Metadata) (datamodel.Node, error) {
57+
return ipldbind.SafeWrap(&entries, Prototype.Metadata.Type())
5458
}

message/v1/metadata/metadata_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ func TestDecodeEncodeMetadata(t *testing.T) {
2727
})
2828

2929
// verify metadata matches
30-
encoded := EncodeMetadata(initialMetadata)
30+
encoded, err := EncodeMetadata(initialMetadata)
31+
require.NoError(t, err, "encode errored")
3132

3233
decodedMetadata, err := DecodeMetadata(encoded)
3334
require.NoError(t, err, "decode errored")

message/v1/pb_roundtrip_test.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@ import (
55

66
blocks "github.com/ipfs/go-block-format"
77
"github.com/ipfs/go-cid"
8-
"github.com/ipfs/go-graphsync"
9-
"github.com/ipfs/go-graphsync/message"
10-
pb "github.com/ipfs/go-graphsync/message/pb"
11-
"github.com/ipfs/go-graphsync/testutil"
128
"github.com/ipld/go-ipld-prime/datamodel"
139
"github.com/ipld/go-ipld-prime/node/basicnode"
1410
selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse"
1511
"github.com/libp2p/go-libp2p-core/peer"
1612
"github.com/stretchr/testify/require"
1713
"google.golang.org/protobuf/proto"
14+
15+
"github.com/ipfs/go-graphsync"
16+
"github.com/ipfs/go-graphsync/message"
17+
pb "github.com/ipfs/go-graphsync/message/pb"
18+
"github.com/ipfs/go-graphsync/testutil"
1819
)
1920

2021
func TestIPLDRoundTrip(t *testing.T) {

message/v2/ipld_roundtrip_test.go

+10-8
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ import (
66

77
blocks "github.com/ipfs/go-block-format"
88
"github.com/ipfs/go-cid"
9-
"github.com/ipfs/go-graphsync"
10-
"github.com/ipfs/go-graphsync/message"
11-
"github.com/ipfs/go-graphsync/message/ipldbind"
12-
"github.com/ipfs/go-graphsync/testutil"
139
"github.com/ipld/go-ipld-prime/codec/dagcbor"
1410
"github.com/ipld/go-ipld-prime/datamodel"
1511
"github.com/ipld/go-ipld-prime/node/basicnode"
16-
"github.com/ipld/go-ipld-prime/node/bindnode"
1712
selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse"
1813
"github.com/stretchr/testify/require"
14+
15+
"github.com/ipfs/go-graphsync"
16+
"github.com/ipfs/go-graphsync/message"
17+
"github.com/ipfs/go-graphsync/message/ipldbind"
18+
"github.com/ipfs/go-graphsync/testutil"
1919
)
2020

2121
func TestIPLDRoundTrip(t *testing.T) {
@@ -65,7 +65,8 @@ func TestIPLDRoundTrip(t *testing.T) {
6565

6666
// ipld TypedNode format
6767
var buf bytes.Buffer
68-
node := bindnode.Wrap(igsm, ipldbind.Prototype.Message.Type())
68+
node, err := ipldbind.SafeWrap(igsm, ipldbind.Prototype.Message.Type())
69+
require.NoError(t, err)
6970

7071
// dag-cbor binary format
7172
err = dagcbor.Encode(node.Representation(), &buf)
@@ -76,10 +77,11 @@ func TestIPLDRoundTrip(t *testing.T) {
7677
err = dagcbor.Decode(builder, &buf)
7778
require.NoError(t, err)
7879
rtnode := builder.Build()
79-
rtigsm := bindnode.Unwrap(rtnode).(*ipldbind.GraphSyncMessageRoot)
80+
rtigsm, err := ipldbind.SafeUnwrap(rtnode)
81+
require.NoError(t, err)
8082

8183
// back to message format
82-
rtgsm, err := NewMessageHandler().fromIPLD(rtigsm)
84+
rtgsm, err := NewMessageHandler().fromIPLD(rtigsm.(*ipldbind.GraphSyncMessageRoot))
8385
require.NoError(t, err)
8486

8587
rtreq := rtgsm.Requests()

message/v2/message.go

+9-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"github.com/ipfs/go-cid"
1111
"github.com/ipld/go-ipld-prime/codec/dagcbor"
1212
"github.com/ipld/go-ipld-prime/datamodel"
13-
"github.com/ipld/go-ipld-prime/node/bindnode"
1413
"github.com/libp2p/go-libp2p-core/network"
1514
"github.com/libp2p/go-libp2p-core/peer"
1615
"github.com/libp2p/go-msgio"
@@ -49,8 +48,11 @@ func (mh *MessageHandler) FromMsgReader(_ peer.ID, r msgio.Reader) (message.Grap
4948
return message.GraphSyncMessage{}, err
5049
}
5150
node := builder.Build()
52-
ipldGSM := bindnode.Unwrap(node).(*ipldbind.GraphSyncMessageRoot)
53-
return mh.fromIPLD(ipldGSM)
51+
ipldGSM, err := ipldbind.SafeUnwrap(node)
52+
if err != nil {
53+
return message.GraphSyncMessage{}, err
54+
}
55+
return mh.fromIPLD(ipldGSM.(*ipldbind.GraphSyncMessageRoot))
5456
}
5557

5658
// ToProto converts a GraphSyncMessage to its ipldbind.GraphSyncMessageRoot equivalent
@@ -138,7 +140,10 @@ func (mh *MessageHandler) ToNet(_ peer.ID, gsm message.GraphSyncMessage, w io.Wr
138140
buf := new(bytes.Buffer)
139141
buf.Write(lbuf)
140142

141-
node := bindnode.Wrap(msg, ipldbind.Prototype.Message.Type())
143+
node, err := ipldbind.SafeWrap(msg, ipldbind.Prototype.Message.Type())
144+
if err != nil {
145+
return err
146+
}
142147
err = dagcbor.Encode(node.Representation(), buf)
143148
if err != nil {
144149
return err

requestmanager/reconciledloader/injest.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ package reconciledloader
22

33
import (
44
"github.com/ipfs/go-cid"
5-
"github.com/ipfs/go-graphsync"
65
"go.opentelemetry.io/otel/trace"
6+
7+
"github.com/ipfs/go-graphsync"
78
)
89

910
// IngestResponse ingests new remote items into the reconciled loader

requestmanager/reconciledloader/load.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ import (
44
"context"
55
"io/ioutil"
66

7-
"github.com/ipfs/go-graphsync"
8-
"github.com/ipfs/go-graphsync/requestmanager/types"
97
"github.com/ipld/go-ipld-prime/datamodel"
108
"github.com/ipld/go-ipld-prime/linking"
119
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
1210
"go.opentelemetry.io/otel"
1311
"go.opentelemetry.io/otel/attribute"
1412
"go.opentelemetry.io/otel/trace"
13+
14+
"github.com/ipfs/go-graphsync"
15+
"github.com/ipfs/go-graphsync/requestmanager/types"
1516
)
1617

1718
// BlockReadOpener synchronously loads the next block result

requestmanager/reconciledloader/pathtracker.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package reconciledloader
22

33
import (
4-
"github.com/ipfs/go-graphsync"
54
"github.com/ipld/go-ipld-prime/datamodel"
5+
6+
"github.com/ipfs/go-graphsync"
67
)
78

89
// pathTracker is just a simple utility to track whether we're on a missing

requestmanager/reconciledloader/reconciledloader.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@ import (
2727
"errors"
2828
"sync"
2929

30-
"github.com/ipfs/go-graphsync"
31-
"github.com/ipfs/go-graphsync/requestmanager/reconciledloader/traversalrecord"
32-
"github.com/ipfs/go-graphsync/requestmanager/types"
3330
logging "github.com/ipfs/go-log/v2"
3431
"github.com/ipld/go-ipld-prime/datamodel"
3532
"github.com/ipld/go-ipld-prime/linking"
33+
34+
"github.com/ipfs/go-graphsync"
35+
"github.com/ipfs/go-graphsync/requestmanager/reconciledloader/traversalrecord"
36+
"github.com/ipfs/go-graphsync/requestmanager/types"
3637
)
3738

3839
var log = logging.Logger("gs-reconciledlaoder")

requestmanager/reconciledloader/reconciledloader_test.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,19 @@ import (
88

99
blocks "github.com/ipfs/go-block-format"
1010
"github.com/ipfs/go-cid"
11-
"github.com/ipfs/go-graphsync"
12-
"github.com/ipfs/go-graphsync/ipldutil"
13-
"github.com/ipfs/go-graphsync/message"
14-
"github.com/ipfs/go-graphsync/requestmanager/reconciledloader"
15-
"github.com/ipfs/go-graphsync/requestmanager/types"
16-
"github.com/ipfs/go-graphsync/testutil"
1711
"github.com/ipld/go-ipld-prime"
1812
"github.com/ipld/go-ipld-prime/datamodel"
1913
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
2014
selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse"
2115
"github.com/stretchr/testify/require"
2216
"go.opentelemetry.io/otel/trace"
17+
18+
"github.com/ipfs/go-graphsync"
19+
"github.com/ipfs/go-graphsync/ipldutil"
20+
"github.com/ipfs/go-graphsync/message"
21+
"github.com/ipfs/go-graphsync/requestmanager/reconciledloader"
22+
"github.com/ipfs/go-graphsync/requestmanager/types"
23+
"github.com/ipfs/go-graphsync/testutil"
2324
)
2425

2526
func TestReconciledLoader(t *testing.T) {

requestmanager/reconciledloader/remotequeue.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import (
44
"sync"
55

66
"github.com/ipfs/go-cid"
7-
"github.com/ipfs/go-graphsync"
87
"go.opentelemetry.io/otel/trace"
8+
9+
"github.com/ipfs/go-graphsync"
910
)
1011

1112
var linkedRemoteItemPool = sync.Pool{

requestmanager/reconciledloader/traversalrecord/traversalrecord.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import (
44
"errors"
55

66
"github.com/ipfs/go-cid"
7-
"github.com/ipfs/go-graphsync"
87
"github.com/ipld/go-ipld-prime/datamodel"
98
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
9+
10+
"github.com/ipfs/go-graphsync"
1011
)
1112

1213
// TraversalRecord records the links traversed by a selector and their paths in a space efficient manner

requestmanager/reconciledloader/traversalrecord/traversalrecord_test.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@ import (
77
"testing"
88

99
"github.com/ipfs/go-cid"
10-
"github.com/ipfs/go-graphsync"
11-
"github.com/ipfs/go-graphsync/ipldutil"
12-
"github.com/ipfs/go-graphsync/requestmanager/reconciledloader/traversalrecord"
13-
"github.com/ipfs/go-graphsync/testutil"
1410
"github.com/ipld/go-ipld-prime"
1511
"github.com/ipld/go-ipld-prime/datamodel"
1612
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
1713
"github.com/ipld/go-ipld-prime/traversal"
1814
selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse"
1915
"github.com/stretchr/testify/require"
16+
17+
"github.com/ipfs/go-graphsync"
18+
"github.com/ipfs/go-graphsync/ipldutil"
19+
"github.com/ipfs/go-graphsync/requestmanager/reconciledloader/traversalrecord"
20+
"github.com/ipfs/go-graphsync/testutil"
2021
)
2122

2223
func TestTraversalRecord(t *testing.T) {

0 commit comments

Comments
 (0)