1
1
package data
2
2
3
3
import (
4
+ "bytes"
4
5
"fmt"
5
6
"math/big"
6
7
@@ -28,6 +29,22 @@ func Decode(b []byte) (PlutusData, error) {
28
29
return decodeRaw (v )
29
30
}
30
31
32
+ // cborUnmarshal acts like cbor.Unmarshal but allows us to set our own decoder options
33
+ func cborUnmarshal (dataBytes []byte , dest any ) error {
34
+ data := bytes .NewReader (dataBytes )
35
+ // Create a custom decoder that returns an error on unknown fields
36
+ decOptions := cbor.DecOptions {
37
+ // This defaults to 32, but there are blocks in the wild using >64 nested levels
38
+ MaxNestedLevels : 256 ,
39
+ }
40
+ decMode , err := decOptions .DecMode ()
41
+ if err != nil {
42
+ return err
43
+ }
44
+ dec := decMode .NewDecoder (data )
45
+ return dec .Decode (dest )
46
+ }
47
+
31
48
// decodeCborRaw is an alternative to cbor.Unmarshal() that converts cbor.Tag to Constr
32
49
// This is needed because cbor.Tag with a slice as the content (such as in a Constr) is
33
50
// not hashable and cannot be used as a map key
@@ -36,7 +53,7 @@ func decodeCborRaw(data []byte) (any, error) {
36
53
switch cborType {
37
54
case CborTypeByteString :
38
55
var tmpData cbor.ByteString
39
- if err := cbor . Unmarshal (data , & tmpData ); err != nil {
56
+ if err := cborUnmarshal (data , & tmpData ); err != nil {
40
57
return nil , err
41
58
}
42
59
return tmpData , nil
@@ -46,14 +63,14 @@ func decodeCborRaw(data []byte) (any, error) {
46
63
return decodeCborRawMap (data )
47
64
case CborTypeTag :
48
65
var tmpTag cbor.RawTag
49
- if err := cbor . Unmarshal (data , & tmpTag ); err != nil {
66
+ if err := cborUnmarshal (data , & tmpTag ); err != nil {
50
67
return nil , err
51
68
}
52
69
return decodeRawTag (tmpTag )
53
70
default :
54
71
// Decode using default representation
55
72
var tmpData any
56
- if err := cbor . Unmarshal (data , & tmpData ); err != nil {
73
+ if err := cborUnmarshal (data , & tmpData ); err != nil {
57
74
return nil , err
58
75
}
59
76
return tmpData , nil
@@ -62,7 +79,7 @@ func decodeCborRaw(data []byte) (any, error) {
62
79
63
80
func decodeCborRawList (data []byte ) (any , error ) {
64
81
var tmpData []cbor.RawMessage
65
- if err := cbor . Unmarshal (data , & tmpData ); err != nil {
82
+ if err := cborUnmarshal (data , & tmpData ); err != nil {
66
83
return nil , err
67
84
}
68
85
tmpItems := make ([]PlutusData , len (tmpData ))
@@ -82,7 +99,7 @@ func decodeCborRawList(data []byte) (any, error) {
82
99
83
100
func decodeCborRawMap (data []byte ) (any , error ) {
84
101
var tmpData map [RawMessageStr ]RawMessageStr
85
- if err := cbor . Unmarshal (data , & tmpData ); err != nil {
102
+ if err := cborUnmarshal (data , & tmpData ); err != nil {
86
103
return nil , err
87
104
}
88
105
pairs := make ([][2 ]PlutusData , 0 , len (tmpData ))
@@ -225,7 +242,7 @@ func decodeRawTag(tag cbor.RawTag) (PlutusData, error) {
225
242
Alternative uint64
226
243
FieldsRaw cbor.RawMessage
227
244
}
228
- if err := cbor . Unmarshal (tag .Content , & tmpData ); err != nil {
245
+ if err := cborUnmarshal (tag .Content , & tmpData ); err != nil {
229
246
return nil , err
230
247
}
231
248
ret , retErr = decodeConstr (tmpData .Alternative , tmpData .FieldsRaw )
0 commit comments