diff --git a/codec.go b/codec.go index 35b50c14d95d96763da9a8ff874d52e5cd4ca71e..e6b74479cc257cc8bfac05fb380f311e57f30204 100644 --- a/codec.go +++ b/codec.go @@ -4,6 +4,8 @@ import ( "bytes" "fmt" "strings" + + "github.com/multiformats/go-varint" ) func stringToBytes(s string) ([]byte, error) { @@ -30,7 +32,7 @@ func stringToBytes(s string) ([]byte, error) { if p.Code == 0 { return nil, fmt.Errorf("failed to parse multiaddr %q: unknown protocol %s", s, sp[0]) } - _, _ = b.Write(CodeToVarint(p.Code)) + _, _ = b.Write(p.VCode) sp = sp[1:] if p.Size == 0 { // no length. @@ -52,7 +54,7 @@ func stringToBytes(s string) ([]byte, error) { return nil, fmt.Errorf("failed to parse multiaddr %q: invalid value %q for protocol %s: %s", s, sp[0], p.Name, err) } if p.Size < 0 { // varint size. - _, _ = b.Write(CodeToVarint(len(a))) + _, _ = b.Write(varint.ToUvarint(uint64(len(a)))) } b.Write(a) sp = sp[1:] diff --git a/component.go b/component.go index 69baf7a1bd0579811a028a51537eb635ffcd1bee..490b8ac90ecdafa2d30b29e3aab9849e47c359bd 100644 --- a/component.go +++ b/component.go @@ -6,6 +6,8 @@ import ( "encoding/json" "fmt" "strings" + + "github.com/multiformats/go-varint" ) // Component is a single multiaddr Component. @@ -158,7 +160,7 @@ func newComponent(protocol Protocol, bvalue []byte) *Component { size := len(bvalue) size += len(protocol.VCode) if protocol.Size < 0 { - size += VarintSize(len(bvalue)) + size += varint.UvarintSize(uint64(len(bvalue))) } maddr := make([]byte, size) var offset int diff --git a/go.mod b/go.mod index 07d7017e83f26b4057a4b24c2b9f7395adfa1c24..b66f961bcb0c5c89cb2b007ca45cd851311ace66 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,8 @@ module github.com/multiformats/go-multiaddr -require github.com/multiformats/go-multihash v0.0.8 +require ( + github.com/multiformats/go-multihash v0.0.8 + github.com/multiformats/go-varint v0.0.1 +) -go 1.12 +go 1.13 diff --git a/go.sum b/go.sum index 2df8a78f16399b091164a16cdef97d2befbfa169..eb51b69bb7b3feccaf668314ab03a3eeb553bdcd 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-multihash v0.0.8 h1:wrYcW5yxSi3dU07n5jnuS5PrNwyHy0zRHGVoUugWvXg= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-varint v0.0.1 h1:TR/0rdQtnNxuN2IhiB639xC3tWM4IUi7DkTBVTdGW/M= +github.com/multiformats/go-varint v0.0.1/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= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/varint.go b/varint.go index b8b1507bbcccf587b04b75e301d3ded91e886dc8..d1ea7fc4fc76c57ecf6752cfd979973fb7178d80 100644 --- a/varint.go +++ b/varint.go @@ -1,44 +1,27 @@ package multiaddr import ( - "encoding/binary" - "fmt" - "math/bits" -) + "math" -// VarintSize returns the size (in bytes) of `num` encoded as a varint. -func VarintSize(num int) int { - bits := bits.Len(uint(num)) - q, r := bits/7, bits%7 - size := q - if r > 0 || size == 0 { - size++ - } - return size -} + "github.com/multiformats/go-varint" +) // CodeToVarint converts an integer to a varint-encoded []byte func CodeToVarint(num int) []byte { - buf := make([]byte, VarintSize(num)) - n := binary.PutUvarint(buf, uint64(num)) - return buf[:n] + if num < 0 || num > math.MaxInt32 { + panic("invalid code") + } + return varint.ToUvarint(uint64(num)) } -// VarintToCode converts a varint-encoded []byte to an integer protocol code -func VarintToCode(buf []byte) int { - num, _, err := ReadVarintCode(buf) +func ReadVarintCode(b []byte) (int, int, error) { + code, n, err := varint.FromUvarint(b) if err != nil { - panic(err) + return 0, 0, err } - return num -} - -// ReadVarintCode reads a varint code from the beginning of buf. -// returns the code, and the number of bytes read. -func ReadVarintCode(buf []byte) (int, int, error) { - num, n := binary.Uvarint(buf) - if n < 0 { - return 0, 0, fmt.Errorf("varints larger than uint64 not yet supported") + if code > math.MaxInt32 { + // we only allow 32bit codes. + return 0, 0, varint.ErrOverflow } - return int(num), n, nil + return int(code), n, err } diff --git a/varint_test.go b/varint_test.go deleted file mode 100644 index 817b3dd8b9715ac60f27cb91064d5d09f1030601..0000000000000000000000000000000000000000 --- a/varint_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package multiaddr - -import ( - "encoding/binary" - "testing" -) - -func checkVarint(t *testing.T, x int) { - buf := make([]byte, binary.MaxVarintLen64) - expected := binary.PutUvarint(buf, uint64(x)) - - size := VarintSize(x) - if size != expected { - t.Fatalf("expected varintsize of %d to be %d, got %d", x, expected, size) - } -} - -func TestVarintSize(t *testing.T) { - max := 1 << 16 - for x := 0; x < max; x++ { - checkVarint(t, x) - } -}