Unverified Commit 64e34154 authored by bigs's avatar bigs Committed by GitHub

Merge pull request #112 from multiformats/fix/deterministic

fix: minimal varint decoding
parents f96df18b 8af58b28
......@@ -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
......
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
}
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)
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment