mirror of
https://github.com/logos-messaging/go-multiaddr.git
synced 2026-01-02 13:03:11 +00:00
Merge pull request #112 from multiformats/fix/deterministic
fix: minimal varint decoding
This commit is contained in:
commit
64e3415480
6
codec.go
6
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:]
|
||||
|
||||
@ -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
|
||||
|
||||
7
go.mod
7
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
|
||||
|
||||
2
go.sum
2
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=
|
||||
|
||||
45
varint.go
45
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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user