Skip to content

Commit 64e3415

Browse files
authored
Merge pull request #112 from multiformats/fix/deterministic
fix: minimal varint decoding
2 parents f96df18 + 8af58b2 commit 64e3415

File tree

6 files changed

+28
-59
lines changed

6 files changed

+28
-59
lines changed

codec.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"bytes"
55
"fmt"
66
"strings"
7+
8+
"github.com/multiformats/go-varint"
79
)
810

911
func stringToBytes(s string) ([]byte, error) {
@@ -30,7 +32,7 @@ func stringToBytes(s string) ([]byte, error) {
3032
if p.Code == 0 {
3133
return nil, fmt.Errorf("failed to parse multiaddr %q: unknown protocol %s", s, sp[0])
3234
}
33-
_, _ = b.Write(CodeToVarint(p.Code))
35+
_, _ = b.Write(p.VCode)
3436
sp = sp[1:]
3537

3638
if p.Size == 0 { // no length.
@@ -52,7 +54,7 @@ func stringToBytes(s string) ([]byte, error) {
5254
return nil, fmt.Errorf("failed to parse multiaddr %q: invalid value %q for protocol %s: %s", s, sp[0], p.Name, err)
5355
}
5456
if p.Size < 0 { // varint size.
55-
_, _ = b.Write(CodeToVarint(len(a)))
57+
_, _ = b.Write(varint.ToUvarint(uint64(len(a))))
5658
}
5759
b.Write(a)
5860
sp = sp[1:]

component.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"encoding/json"
77
"fmt"
88
"strings"
9+
10+
"github.com/multiformats/go-varint"
911
)
1012

1113
// Component is a single multiaddr Component.
@@ -158,7 +160,7 @@ func newComponent(protocol Protocol, bvalue []byte) *Component {
158160
size := len(bvalue)
159161
size += len(protocol.VCode)
160162
if protocol.Size < 0 {
161-
size += VarintSize(len(bvalue))
163+
size += varint.UvarintSize(uint64(len(bvalue)))
162164
}
163165
maddr := make([]byte, size)
164166
var offset int

go.mod

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
module github.com/multiformats/go-multiaddr
22

3-
require github.com/multiformats/go-multihash v0.0.8
3+
require (
4+
github.com/multiformats/go-multihash v0.0.8
5+
github.com/multiformats/go-varint v0.0.1
6+
)
47

5-
go 1.12
8+
go 1.13

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78=
66
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
77
github.com/multiformats/go-multihash v0.0.8 h1:wrYcW5yxSi3dU07n5jnuS5PrNwyHy0zRHGVoUugWvXg=
88
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
9+
github.com/multiformats/go-varint v0.0.1 h1:TR/0rdQtnNxuN2IhiB639xC3tWM4IUi7DkTBVTdGW/M=
10+
github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
911
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
1012
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
1113
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=

varint.go

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,27 @@
11
package multiaddr
22

33
import (
4-
"encoding/binary"
5-
"fmt"
6-
"math/bits"
7-
)
4+
"math"
85

9-
// VarintSize returns the size (in bytes) of `num` encoded as a varint.
10-
func VarintSize(num int) int {
11-
bits := bits.Len(uint(num))
12-
q, r := bits/7, bits%7
13-
size := q
14-
if r > 0 || size == 0 {
15-
size++
16-
}
17-
return size
18-
}
6+
"github.com/multiformats/go-varint"
7+
)
198

209
// CodeToVarint converts an integer to a varint-encoded []byte
2110
func CodeToVarint(num int) []byte {
22-
buf := make([]byte, VarintSize(num))
23-
n := binary.PutUvarint(buf, uint64(num))
24-
return buf[:n]
11+
if num < 0 || num > math.MaxInt32 {
12+
panic("invalid code")
13+
}
14+
return varint.ToUvarint(uint64(num))
2515
}
2616

27-
// VarintToCode converts a varint-encoded []byte to an integer protocol code
28-
func VarintToCode(buf []byte) int {
29-
num, _, err := ReadVarintCode(buf)
17+
func ReadVarintCode(b []byte) (int, int, error) {
18+
code, n, err := varint.FromUvarint(b)
3019
if err != nil {
31-
panic(err)
20+
return 0, 0, err
3221
}
33-
return num
34-
}
35-
36-
// ReadVarintCode reads a varint code from the beginning of buf.
37-
// returns the code, and the number of bytes read.
38-
func ReadVarintCode(buf []byte) (int, int, error) {
39-
num, n := binary.Uvarint(buf)
40-
if n < 0 {
41-
return 0, 0, fmt.Errorf("varints larger than uint64 not yet supported")
22+
if code > math.MaxInt32 {
23+
// we only allow 32bit codes.
24+
return 0, 0, varint.ErrOverflow
4225
}
43-
return int(num), n, nil
26+
return int(code), n, err
4427
}

varint_test.go

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)