Skip to content

Commit 4e6a58d

Browse files
authored
Merge pull request #361 from blinklabs-io/feat/cbor-value-tags
feat: support for CBOR tags for arbitrarily large ints
2 parents 64cc17f + 2d70a30 commit 4e6a58d

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

cbor/value.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"encoding/hex"
1919
"encoding/json"
2020
"fmt"
21+
"math/big"
2122
"sort"
2223
"strings"
2324
)
@@ -94,7 +95,17 @@ func (v *Value) UnmarshalCBOR(data []byte) error {
9495
value: &newValue,
9596
}
9697
} else {
97-
return fmt.Errorf("unsupported CBOR tag: %d", tmpTag.Number)
98+
// Fall back to standard CBOR tag parsing for our supported types
99+
var tmpTagDecode interface{}
100+
if _, err := Decode(data, &tmpTagDecode); err != nil {
101+
return err
102+
}
103+
switch tmpTagDecode.(type) {
104+
case int, uint, int64, uint64, bool, big.Int:
105+
v.value = tmpTagDecode
106+
default:
107+
return fmt.Errorf("unsupported CBOR tag number: %d", tmpTag.Number)
108+
}
98109
}
99110
}
100111
default:
@@ -218,6 +229,12 @@ func generateAstJson(obj interface{}) ([]byte, error) {
218229
return []byte(tmpJson), nil
219230
case Constructor:
220231
return json.Marshal(obj)
232+
case big.Int:
233+
tmpJson := fmt.Sprintf(
234+
`{"int":%s}`,
235+
v.String(),
236+
)
237+
return []byte(tmpJson), nil
221238
case int, uint, uint64, int64:
222239
tmpJsonObj["int"] = v
223240
case bool:

cbor/value_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"encoding/hex"
1919
"encoding/json"
2020
"fmt"
21+
"math/big"
2122
"reflect"
2223
"strings"
2324
"testing"
@@ -70,6 +71,15 @@ var testDefs = []struct {
7071
},
7172
expectedAstJson: `{"map":[{"k":{"int":1},"v":{"list":[{"int":2}]}},{"k":{"int":3},"v":{"list":[{"int":4}]}}]}`,
7273
},
74+
// [22318265904693663008365, 8535038193994223137511702528]
75+
{
76+
cborHex: "82C24A04B9E028911409DC866DC24C1B9404A39BD8000000000000",
77+
expectedObject: []any{
78+
*(new(big.Int).SetBytes(test.DecodeHexString("04B9E028911409DC866D"))),
79+
*(new(big.Int).SetBytes(test.DecodeHexString("1B9404A39BD8000000000000"))),
80+
},
81+
expectedAstJson: `{"list":[{"int":22318265904693663008365},{"int":8535038193994223137511702528}]}`,
82+
},
7383
}
7484

7585
func TestValueDecode(t *testing.T) {
@@ -198,6 +208,12 @@ func TestLazyValueMarshalJSON(t *testing.T) {
198208
strings.ToLower(testDef.cborHex),
199209
testDef.expectedAstJson,
200210
)
211+
if testDef.expectedObject == nil {
212+
fullExpectedJson = fmt.Sprintf(
213+
`{"cbor":"%s"}`,
214+
strings.ToLower(testDef.cborHex),
215+
)
216+
}
201217
if !test.JsonStringsEqual(jsonData, []byte(fullExpectedJson)) {
202218
t.Fatalf("CBOR did not marshal to expected JSON\n got: %s\n wanted: %s", jsonData, fullExpectedJson)
203219
}

0 commit comments

Comments
 (0)