Compare commits

..

10 Commits

Author SHA1 Message Date
gammazero
0ca2bbaeb3 Add SumStream to read data from io.Reader
This provides a way to create a CID without having to read all data into memory before passing it into Sum.  Instead, call SumStream passing in an io.Reader.
2021-04-07 12:45:16 -07:00
dependabot-preview[bot]
e530276a70 Bump github.com/multiformats/go-varint from 0.0.5 to 0.0.6
Bumps [github.com/multiformats/go-varint](https://github.com/multiformats/go-varint) from 0.0.5 to 0.0.6.
- [Release notes](https://github.com/multiformats/go-varint/releases)
- [Commits](https://github.com/multiformats/go-varint/compare/v0.0.5...v0.0.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-15 14:27:46 +11:00
dependabot-preview[bot]
45f4147a06 Bump github.com/multiformats/go-multihash from 0.0.13 to 0.0.14
Bumps [github.com/multiformats/go-multihash](https://github.com/multiformats/go-multihash) from 0.0.13 to 0.0.14.
- [Release notes](https://github.com/multiformats/go-multihash/releases)
- [Commits](https://github.com/multiformats/go-multihash/compare/v0.0.13...v0.0.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-15 14:12:37 +11:00
Rod Vagg
b34ad3cfa5 s/characters/bytes 2020-10-15 14:05:52 +11:00
gammazero
ec089b8a53 Fix inaccurate comment for uvarint
This fixes the comment to be consistent with the code, and fixes spelling.

Fixes Issue #111
2020-10-15 14:05:52 +11:00
Rod Vagg
efe2d2de45 coverage: more tests for cid 2020-10-15 14:00:36 +11:00
Rod Vagg
46aac88838 coverage: more tests for varint 2020-10-15 14:00:36 +11:00
Rod Vagg
f60e346b24 coverage: more tests for builder 2020-10-15 14:00:36 +11:00
Rod Vagg
8647a1d84b fix: make tests run with Go 1.15
> ./cid_test.go:451:52: conversion from uint64 to string yields a string of one rune, not a string of digits (did you mean fmt.Sprint(x)?)
2020-10-15 14:00:36 +11:00
Alex Good
de49849130 Add the dagjose multiformat 2020-10-15 14:00:36 +11:00
9 changed files with 335 additions and 41 deletions

View File

@@ -88,7 +88,7 @@ if c1.Equals(c2) {
```go
// To check if some data matches a given cid,
// Get your CIDs prefix, and use that to sum the data in question:
other, err := c.Prefix().Sum(mydata)
other, err := c.Prefix().SumStream(myFile)
if err != nil {...}
if !c.Equals(other) {

View File

@@ -1,6 +1,8 @@
package cid
import (
"io"
mh "github.com/multiformats/go-multihash"
)
@@ -41,6 +43,14 @@ func (p V0Builder) Sum(data []byte) (Cid, error) {
return Cid{string(hash)}, nil
}
func (p V0Builder) SumStream(r io.Reader) (Cid, error) {
hash, err := mh.SumStream(r, mh.SHA2_256, -1)
if err != nil {
return Undef, err
}
return Cid{string(hash)}, nil
}
func (p V0Builder) GetCodec() uint64 {
return DagProtobuf
}
@@ -64,6 +74,18 @@ func (p V1Builder) Sum(data []byte) (Cid, error) {
return NewCidV1(p.Codec, hash), nil
}
func (p V1Builder) SumStream(r io.Reader) (Cid, error) {
mhLen := p.MhLength
if mhLen <= 0 {
mhLen = -1
}
hash, err := mh.SumStream(r, p.MhType, mhLen)
if err != nil {
return Undef, err
}
return NewCidV1(p.Codec, hash), nil
}
func (p V1Builder) GetCodec() uint64 {
return p.Codec
}

View File

@@ -1,6 +1,7 @@
package cid
import (
"bytes"
"testing"
mh "github.com/multiformats/go-multihash"
@@ -16,6 +17,15 @@ func TestV0Builder(t *testing.T) {
t.Fatal(err)
}
reader := bytes.NewReader(data)
c1a, err := format.SumStream(reader)
if err != nil {
t.Fatal(err)
}
if !c1a.Equals(c1) {
t.Fatal("Sum and SumStream create different cids")
}
// Construct c2
hash, err := mh.Sum(data, mh.SHA2_256, -1)
if err != nil {
@@ -29,6 +39,16 @@ func TestV0Builder(t *testing.T) {
if c1.Prefix() != c2.Prefix() {
t.Fatal("prefixes mismatch")
}
reader.Seek(0, 0)
hash, err = mh.SumStream(reader, mh.SHA2_256, -1)
if err != nil {
t.Fatal(err)
}
c2 = NewCidV0(hash)
if !c1.Equals(c2) {
t.Fatal("Sum and SumStream create different cids")
}
}
func TestV1Builder(t *testing.T) {
@@ -41,6 +61,15 @@ func TestV1Builder(t *testing.T) {
t.Fatal(err)
}
reader := bytes.NewReader(data)
c1a, err := format.SumStream(reader)
if err != nil {
t.Fatal(err)
}
if !c1a.Equals(c1) {
t.Fatal("Sum and SumStream create different cids")
}
// Construct c2
hash, err := mh.Sum(data, mh.SHA2_256, -1)
if err != nil {
@@ -65,9 +94,29 @@ func TestCodecChange(t *testing.T) {
p := Prefix{Version: 1, Codec: DagProtobuf, MhType: mh.SHA2_256, MhLength: mh.DefaultLengths[mh.SHA2_256]}
testCodecChange(t, p)
})
t.Run("Prefix-NoChange", func(t *testing.T) {
p := Prefix{Version: 0, Codec: DagProtobuf, MhType: mh.SHA2_256, MhLength: mh.DefaultLengths[mh.SHA2_256]}
if p.GetCodec() != DagProtobuf {
t.Fatal("original builder not using Protobuf codec")
}
pn := p.WithCodec(DagProtobuf)
if pn != p {
t.Fatal("should have returned same builder")
}
})
t.Run("V0Builder", func(t *testing.T) {
testCodecChange(t, V0Builder{})
})
t.Run("V0Builder-NoChange", func(t *testing.T) {
b := V0Builder{}
if b.GetCodec() != DagProtobuf {
t.Fatal("original builder not using Protobuf codec")
}
bn := b.WithCodec(DagProtobuf)
if bn != b {
t.Fatal("should have returned same builder")
}
})
t.Run("V1Builder", func(t *testing.T) {
testCodecChange(t, V1Builder{Codec: DagProtobuf, MhType: mh.SHA2_256})
})

33
cid.go
View File

@@ -58,6 +58,7 @@ const (
GitRaw = 0x78
DagJOSE = 0x85
EthBlock = 0x90
EthBlockList = 0x91
EthTxTrie = 0x92
@@ -106,6 +107,7 @@ var Codecs = map[string]uint64{
"dash-tx": DashTx,
"fil-commitment-unsealed": FilCommitmentUnsealed,
"fil-commitment-sealed": FilCommitmentSealed,
"dag-jose": DagJOSE,
}
// CodecToStr maps the numeric codec to its name
@@ -133,6 +135,7 @@ var CodecToStr = map[uint64]string{
DashTx: "dash-tx",
FilCommitmentUnsealed: "fil-commitment-unsealed",
FilCommitmentSealed: "fil-commitment-sealed",
DagJOSE: "dag-jose",
}
// tryNewCidV0 tries to convert a multihash into a CIDv0 CID and returns an
@@ -586,6 +589,36 @@ func (p Prefix) Sum(data []byte) (Cid, error) {
}
}
// SumStream uses the information in a prefix, and data read from a io.Reader,
// to perform a multihash.SumStream() and return a newly constructed Cid with
// the resulting multihash.
func (p Prefix) SumStream(r io.Reader) (Cid, error) {
length := p.MhLength
if p.MhType == mh.ID {
length = -1
}
if p.Version == 0 && (p.MhType != mh.SHA2_256 ||
(p.MhLength != 32 && p.MhLength != -1)) {
return Undef, fmt.Errorf("invalid v0 prefix")
}
hash, err := mh.SumStream(r, p.MhType, length)
if err != nil {
return Undef, err
}
switch p.Version {
case 0:
return NewCidV0(hash), nil
case 1:
return NewCidV1(p.Codec, hash), nil
default:
return Undef, fmt.Errorf("invalid cid version")
}
}
// Bytes returns a byte representation of a Prefix. It looks like:
//
// <version><codec><mh-type><mh-length>

View File

@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"math/rand"
"reflect"
"strings"
"testing"
@@ -40,6 +41,7 @@ var tCodecs = map[uint64]string{
DashTx: "dash-tx",
FilCommitmentUnsealed: "fil-commitment-unsealed",
FilCommitmentSealed: "fil-commitment-sealed",
DagJOSE: "dag-jose",
}
func assertEqual(t *testing.T, a, b Cid) {
@@ -184,8 +186,32 @@ func TestBasesMarshaling(t *testing.T) {
}
s2 := cid.Encode(encoder)
if s != s2 {
t.Fatalf("'%s' != '%s'", s, s2)
t.Fatalf("%q != %q", s, s2)
}
ee, err := ExtractEncoding(s)
if err != nil {
t.Fatal(err)
}
if ee != b {
t.Fatalf("could not properly determine base (got %v)", ee)
}
}
ee, err := ExtractEncoding("QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n")
if err != nil {
t.Fatal(err)
}
if ee != mbase.Base58BTC {
t.Fatalf("expected Base58BTC from Qm string (got %v)", ee)
}
ee, err = ExtractEncoding("1")
if err == nil {
t.Fatal("expected too-short error from ExtractEncoding")
}
if ee != -1 {
t.Fatal("expected -1 from too-short ExtractEncoding")
}
}
@@ -194,18 +220,32 @@ func TestBinaryMarshaling(t *testing.T) {
hash, _ := mh.Sum(data, mh.SHA2_256, -1)
c := NewCidV1(DagCBOR, hash)
var c2 Cid
var c3 Cid
data, err := c.MarshalBinary()
if err != nil {
t.Fatal(err)
}
err = c2.UnmarshalBinary(data)
if err != nil {
if err = c2.UnmarshalBinary(data); err != nil {
t.Fatal(err)
}
if !c.Equals(c2) {
t.Errorf("cids should be the same: %s %s", c, c2)
}
var buf bytes.Buffer
wrote, err := c.WriteBytes(&buf)
if err != nil {
t.Fatal(err)
}
if wrote != 36 {
t.Fatalf("expected 36 bytes written (got %d)", wrote)
}
if err = c3.UnmarshalBinary(data); err != nil {
t.Fatal(err)
}
if !c.Equals(c3) {
t.Errorf("cids should be the same: %s %s", c, c3)
}
}
func TestTextMarshaling(t *testing.T) {
@@ -218,13 +258,16 @@ func TestTextMarshaling(t *testing.T) {
if err != nil {
t.Fatal(err)
}
err = c2.UnmarshalText(data)
if err != nil {
if err = c2.UnmarshalText(data); err != nil {
t.Fatal(err)
}
if !c.Equals(c2) {
t.Errorf("cids should be the same: %s %s", c, c2)
}
if c.KeyString() != string(c.Bytes()) {
t.Errorf("got unexpected KeyString() result")
}
}
func TestEmptyString(t *testing.T) {
@@ -254,6 +297,11 @@ func TestV0Handling(t *testing.T) {
t.Fatal("marshaling roundtrip failed")
}
byteLen := cid.ByteLen()
if byteLen != 34 {
t.Fatalf("expected V0 ByteLen to be 34 (got %d)", byteLen)
}
new, err := cid.StringOfBase(mbase.Base58BTC)
if err != nil {
t.Fatal(err)
@@ -269,6 +317,11 @@ func TestV0Handling(t *testing.T) {
if cid.Encode(encoder) != old {
t.Fatal("Encode roundtrip failed")
}
_, err = cid.StringOfBase(mbase.Base32)
if err != ErrInvalidEncoding {
t.Fatalf("expected ErrInvalidEncoding for V0 StringOfBase(Base32) (got %v)", err)
}
}
func TestV0ErrorCases(t *testing.T) {
@@ -369,7 +422,14 @@ func TestInvalidV0Prefix(t *testing.T) {
t.Fatalf("should error (index %d)", i)
}
}
}
func TestBadPrefix(t *testing.T) {
p := Prefix{Version: 3, Codec: DagProtobuf, MhType: mh.SHA2_256, MhLength: 3}
_, err := p.Sum([]byte{0x00, 0x01, 0x03})
if err == nil {
t.Fatalf("expected error on v3 prefix Sum")
}
}
func TestPrefixRoundtrip(t *testing.T) {
@@ -401,6 +461,25 @@ func TestPrefixRoundtrip(t *testing.T) {
}
}
func TestBadPrefixFromBytes(t *testing.T) {
_, err := PrefixFromBytes([]byte{0x80})
if err == nil {
t.Fatal("expected error for bad byte 0")
}
_, err = PrefixFromBytes([]byte{0x01, 0x80})
if err == nil {
t.Fatal("expected error for bad byte 1")
}
_, err = PrefixFromBytes([]byte{0x01, 0x01, 0x80})
if err == nil {
t.Fatal("expected error for bad byte 2")
}
_, err = PrefixFromBytes([]byte{0x01, 0x01, 0x01, 0x80})
if err == nil {
t.Fatal("expected error for bad byte 3")
}
}
func Test16BytesVarint(t *testing.T) {
data := []byte("this is some test content")
hash, _ := mh.Sum(data, mh.SHA2_256, -1)
@@ -448,7 +527,7 @@ func TestParse(t *testing.T) {
return err
}
if cid.Version() != 0 {
return fmt.Errorf("expected version 0, got %s", string(cid.Version()))
return fmt.Errorf("expected version 0, got %d", cid.Version())
}
actual := cid.Hash().B58String()
if actual != expected {
@@ -462,8 +541,7 @@ func TestParse(t *testing.T) {
}
for _, args := range assertions {
err := assert(args[0], args[1].(string))
if err != nil {
if err := assert(args[0], args[1].(string)); err != nil {
t.Fatal(err)
}
}
@@ -497,8 +575,7 @@ func TestFromJson(t *testing.T) {
cval := "bafkreie5qrjvaw64n4tjm6hbnm7fnqvcssfed4whsjqxzslbd3jwhsk3mm"
jsoncid := []byte(`{"/":"` + cval + `"}`)
var c Cid
err := json.Unmarshal(jsoncid, &c)
if err != nil {
if err := json.Unmarshal(jsoncid, &c); err != nil {
t.Fatal(err)
}
@@ -508,6 +585,7 @@ func TestFromJson(t *testing.T) {
}
func TestJsonRoundTrip(t *testing.T) {
expectedJSON := `{"/":"bafkreie5qrjvaw64n4tjm6hbnm7fnqvcssfed4whsjqxzslbd3jwhsk3mm"}`
exp, err := Decode("bafkreie5qrjvaw64n4tjm6hbnm7fnqvcssfed4whsjqxzslbd3jwhsk3mm")
if err != nil {
t.Fatal(err)
@@ -519,21 +597,50 @@ func TestJsonRoundTrip(t *testing.T) {
t.Fatal(err)
}
var actual Cid
err = json.Unmarshal(enc, &actual)
if err = json.Unmarshal(enc, &actual); err != nil {
t.Fatal(err)
}
if !exp.Equals(actual) {
t.Fatal("cids not equal for *Cid")
}
if string(enc) != expectedJSON {
t.Fatalf("did not get expected JSON form (got %q)", string(enc))
}
// Verify it works for a Cid.
enc, err = json.Marshal(exp)
if err != nil {
t.Fatal(err)
}
var actual2 Cid
err = json.Unmarshal(enc, &actual2)
if err = json.Unmarshal(enc, &actual2); err != nil {
t.Fatal(err)
}
if !exp.Equals(actual2) {
t.Fatal("cids not equal for Cid")
}
if err = actual2.UnmarshalJSON([]byte("1")); err == nil {
t.Fatal("expected error for too-short JSON")
}
if err = actual2.UnmarshalJSON([]byte(`{"nope":"nope"}`)); err == nil {
t.Fatal("expected error for bad CID JSON")
}
if err = actual2.UnmarshalJSON([]byte(`bad "" json!`)); err == nil {
t.Fatal("expected error for bad JSON")
}
var actual3 Cid
enc, err = actual3.MarshalJSON()
if err != nil {
t.Fatal(err)
}
if string(enc) != "null" {
t.Fatalf("expected 'null' string for undefined CID (got %q)", string(enc))
}
}
func BenchmarkStringV1(b *testing.B) {
@@ -588,6 +695,52 @@ func TestReadCidsFromBuffer(t *testing.T) {
}
}
func TestBadCidFromBytes(t *testing.T) {
l, c, err := CidFromBytes([]byte{mh.SHA2_256, 32, 0x00})
if err == nil {
t.Fatal("expected not-enough-bytes for V0 CidFromBytes")
}
if l != 0 {
t.Fatal("expected length=0 from bad CidFromBytes")
}
if c != Undef {
t.Fatal("expected Undef CID from bad CidFromBytes")
}
c, err = Decode("bafkreie5qrjvaw64n4tjm6hbnm7fnqvcssfed4whsjqxzslbd3jwhsk3mm")
if err != nil {
t.Fatal(err)
}
byts := make([]byte, c.ByteLen())
copy(byts, c.Bytes())
byts[1] = 0x80 // bad codec varint
byts[2] = 0x00
l, c, err = CidFromBytes(byts)
if err == nil {
t.Fatal("expected not-enough-bytes for V1 CidFromBytes")
}
if l != 0 {
t.Fatal("expected length=0 from bad CidFromBytes")
}
if c != Undef {
t.Fatal("expected Undef CID from bad CidFromBytes")
}
copy(byts, c.Bytes())
byts[2] = 0x80 // bad multihash varint
byts[3] = 0x00
l, c, err = CidFromBytes(byts)
if err == nil {
t.Fatal("expected not-enough-bytes for V1 CidFromBytes")
}
if l != 0 {
t.Fatal("expected length=0 from bad CidFromBytes")
}
if c != Undef {
t.Fatal("expected Undef CID from bad CidFromBytes")
}
}
func TestBadParse(t *testing.T) {
hash, err := mh.Sum([]byte("foobar"), mh.SHA3_256, -1)
if err != nil {
@@ -598,3 +751,16 @@ func TestBadParse(t *testing.T) {
t.Fatal("expected to fail to parse an invalid CIDv1 CID")
}
}
func TestLoggable(t *testing.T) {
c, err := Decode("bafkreie5qrjvaw64n4tjm6hbnm7fnqvcssfed4whsjqxzslbd3jwhsk3mm")
if err != nil {
t.Fatal(err)
}
actual := c.Loggable()
expected := make(map[string]interface{})
expected["cid"] = c
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("did not get expected loggable form (got %v)", actual)
}
}

6
go.mod
View File

@@ -2,8 +2,8 @@ module github.com/ipfs/go-cid
require (
github.com/multiformats/go-multibase v0.0.3
github.com/multiformats/go-multihash v0.0.13
github.com/multiformats/go-varint v0.0.5
github.com/multiformats/go-multihash v0.0.16-0.20210406191223-75ae3688857d
github.com/multiformats/go-varint v0.0.6
)
go 1.13
go 1.15

31
go.sum
View File

@@ -1,28 +1,29 @@
github.com/klauspost/cpuid/v2 v2.0.4 h1:g0I61F2K2DjRHz1cnxlkNSBIaePVoJIjjnHui8QHbiw=
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771 h1:MHkK1uRtFbVqvAgvWxafZe54+5uBxLluGylDiKgdhwo=
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ=
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk=
github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc=
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg=
github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/multiformats/go-multihash v0.0.16-0.20210406191223-75ae3688857d h1:xUl/JcLVtafS0n5X8guAExxDS/mJUGoL31p/FlNtC8o=
github.com/multiformats/go-multihash v0.0.16-0.20210406191223-75ae3688857d/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg=
github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY=
github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY=
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@@ -4,7 +4,7 @@ import (
"github.com/multiformats/go-varint"
)
// Version of varint function that work with a string rather than
// Version of varint function that works with a string rather than
// []byte to avoid unnecessary allocation
// Copyright 2011 The Go Authors. All rights reserved.
@@ -12,23 +12,20 @@ import (
// license as given at https://golang.org/LICENSE
// uvarint decodes a uint64 from buf and returns that value and the
// number of characters read (> 0). If an error occurred, the value is 0
// and the number of bytes n is <= 0 meaning:
//
// n == 0: buf too small
// n < 0: value larger than 64 bits (overflow)
// and -n is the number of bytes read
//
// number of bytes read (> 0). If an error occurred, then 0 is
// returned for both the value and the number of bytes read, and an
// error is returned.
func uvarint(buf string) (uint64, int, error) {
var x uint64
var s uint
// we have a binary string so we can't use a range loope
// we have a binary string so we can't use a range loop
for i := 0; i < len(buf); i++ {
b := buf[i]
if b < 0x80 {
if i > 9 || i == 9 && b > 1 {
return 0, 0, varint.ErrOverflow
} else if b == 0 && i > 0 {
}
if b == 0 && i > 0 {
return 0, 0, varint.ErrNotMinimal
}
return x | uint64(b)<<s, i + 1, nil

View File

@@ -28,3 +28,29 @@ func TestUvarintRoundTrip(t *testing.T) {
}
}
}
func TestUvarintEdges(t *testing.T) {
tests := []struct {
name string
input []byte
want error
}{
{"ErrNotMinimal", []byte{0x01 | 0x80, 0}, varint.ErrNotMinimal},
{"ErrOverflow", []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01}, varint.ErrOverflow},
{"ErrUnderflow", []byte{0x80}, varint.ErrUnderflow},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
v, l1, err := uvarint(string(test.input))
if err != test.want {
t.Fatalf("error case (%v) should return varint.%s (got: %v)", test.input, test.name, err)
}
if v != 0 {
t.Fatalf("error case (%v) should return 0 value (got %d)", test.input, v)
}
if l1 != 0 {
t.Fatalf("error case (%v) should return 0 length (got %d)", test.input, l1)
}
})
}
}