@@ -27,16 +27,16 @@ const (
27
27
// except for the `case tok.TBytes` block,
28
28
// which has dag-cbor's special sauce for detecting schemafree links.
29
29
30
- func Unmarshal (na ipld.NodeAssembler , tokSrc shared.TokenSource ) error {
30
+ func Unmarshal (na ipld.NodeAssembler , tokSrc shared.TokenSource , allowLinks bool ) error {
31
31
// Have a gas budget, which will be decremented as we allocate memory, and an error returned when execeeded (or about to be exceeded).
32
32
// This is a DoS defense mechanism.
33
33
// It's *roughly* in units of bytes (but only very, VERY roughly) -- it also treats words as 1 in many cases.
34
34
// FUTURE: this ought be configurable somehow. (How, and at what granularity though?)
35
35
var gas int = 1048576 * 10
36
- return unmarshal1 (na , tokSrc , & gas )
36
+ return unmarshal1 (na , tokSrc , & gas , allowLinks )
37
37
}
38
38
39
- func unmarshal1 (na ipld.NodeAssembler , tokSrc shared.TokenSource , gas * int ) error {
39
+ func unmarshal1 (na ipld.NodeAssembler , tokSrc shared.TokenSource , gas * int , allowLinks bool ) error {
40
40
var tk tok.Token
41
41
done , err := tokSrc .Step (& tk )
42
42
if err != nil {
@@ -45,12 +45,12 @@ func unmarshal1(na ipld.NodeAssembler, tokSrc shared.TokenSource, gas *int) erro
45
45
if done && ! tk .Type .IsValue () {
46
46
return fmt .Errorf ("unexpected eof" )
47
47
}
48
- return unmarshal2 (na , tokSrc , & tk , gas )
48
+ return unmarshal2 (na , tokSrc , & tk , gas , allowLinks )
49
49
}
50
50
51
51
// starts with the first token already primed. Necessary to get recursion
52
52
// to flow right without a peek+unpeek system.
53
- func unmarshal2 (na ipld.NodeAssembler , tokSrc shared.TokenSource , tk * tok.Token , gas * int ) error {
53
+ func unmarshal2 (na ipld.NodeAssembler , tokSrc shared.TokenSource , tk * tok.Token , gas * int , allowLinks bool ) error {
54
54
// FUTURE: check for schema.TypedNodeBuilder that's going to parse a Link (they can slurp any token kind they want).
55
55
switch tk .Type {
56
56
case tok .TMapOpen :
@@ -97,7 +97,7 @@ func unmarshal2(na ipld.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token,
97
97
if err != nil { // return in error if the key was rejected
98
98
return err
99
99
}
100
- err = unmarshal1 (mva , tokSrc , gas )
100
+ err = unmarshal1 (mva , tokSrc , gas , allowLinks )
101
101
if err != nil { // return in error if some part of the recursion errored
102
102
return err
103
103
}
@@ -140,7 +140,7 @@ func unmarshal2(na ipld.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token,
140
140
if observedLen > expectLen {
141
141
return fmt .Errorf ("unexpected continuation of array elements beyond declared length" )
142
142
}
143
- err := unmarshal2 (la .AssembleValue (), tokSrc , tk , gas )
143
+ err := unmarshal2 (la .AssembleValue (), tokSrc , tk , gas , allowLinks )
144
144
if err != nil { // return in error if some part of the recursion errored
145
145
return err
146
146
}
@@ -166,14 +166,17 @@ func unmarshal2(na ipld.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token,
166
166
}
167
167
switch tk .Tag {
168
168
case linkTag :
169
+ if ! allowLinks {
170
+ return fmt .Errorf ("unhandled cbor tag %d" , tk .Tag )
171
+ }
169
172
if len (tk .Bytes ) < 1 || tk .Bytes [0 ] != 0 {
170
173
return ErrInvalidMultibase
171
174
}
172
175
elCid , err := cid .Cast (tk .Bytes [1 :])
173
176
if err != nil {
174
177
return err
175
178
}
176
- return na .AssignLink (cidlink.Link {elCid })
179
+ return na .AssignLink (cidlink.Link {Cid : elCid })
177
180
default :
178
181
return fmt .Errorf ("unhandled cbor tag %d" , tk .Tag )
179
182
}
0 commit comments