Skip to content

Commit 6dcc6dd

Browse files
authored
Release 0.14.0 (#240)
* minimal changes to ensure proto3 compat. for unsigned ints (int, int32, int64) * Add changes to decode ints, too * Fix example that contains an int * Add changelog entry * Delete outdated tests (covered by new table driven test) * Add overflow checks for int & int32 * unum -> u64 * prep release: update changelog
1 parent cb07448 commit 6dcc6dd

File tree

9 files changed

+195
-155
lines changed

9 files changed

+195
-155
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 0.14.0 (October 26, 2018)
4+
5+
BREAKING CHANGE:
6+
- Switch default encoding of unsigned ints (`int`, `int32`, `int64`) to be on par with [proto3's] variable length
7+
encoding (of `int32`, `int64`) ([#237])
8+
9+
[proto3's]: https://developers.google.com/protocol-buffers/docs/proto#scalar
10+
[#237]: https://github.com/tendermint/go-amino/issues/237
11+
312
## 0.13.0 (October 15, 2018)
413

514
BREAKING CHANGE:

binary-decode.go

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package amino
33
import (
44
"errors"
55
"fmt"
6+
"math"
67
"reflect"
78
"time"
89

@@ -12,6 +13,16 @@ import (
1213
//----------------------------------------
1314
// cdc.decodeReflectBinary
1415

16+
var (
17+
ErrOverflowInt = errors.New("encoded integer value overflows int(32)")
18+
)
19+
20+
const (
21+
// architecture dependent int limits:
22+
maxInt = int(^uint(0) >> 1)
23+
minInt = -maxInt - 1
24+
)
25+
1526
// This is the main entrypoint for decoding all types from binary form. This
1627
// function calls decodeReflectBinary*, and generally those functions should
1728
// only call this one, for the prefix bytes are consumed here when present.
@@ -115,11 +126,12 @@ func (cdc *Codec) decodeReflectBinary(bz []byte, info *TypeInfo, rv reflect.Valu
115126
}
116127
rv.SetInt(num)
117128
} else {
118-
num, _n, err = DecodeVarint(bz)
129+
var u64 uint64
130+
u64, _n, err = DecodeUvarint(bz)
119131
if slide(&bz, &n, _n) && err != nil {
120132
return
121133
}
122-
rv.SetInt(num)
134+
rv.SetInt(int64(u64))
123135
}
124136
return
125137

@@ -132,11 +144,15 @@ func (cdc *Codec) decodeReflectBinary(bz []byte, info *TypeInfo, rv reflect.Valu
132144
}
133145
rv.SetInt(int64(num))
134146
} else {
135-
var num int64
136-
num, _n, err = DecodeVarint(bz)
147+
var num uint64
148+
num, _n, err = DecodeUvarint(bz)
137149
if slide(&bz, &n, _n) && err != nil {
138150
return
139151
}
152+
if int64(num) > math.MaxInt32 || int64(num) < math.MinInt32 {
153+
err = ErrOverflowInt
154+
return
155+
}
140156
rv.SetInt(int64(num))
141157
}
142158
return
@@ -160,12 +176,16 @@ func (cdc *Codec) decodeReflectBinary(bz []byte, info *TypeInfo, rv reflect.Valu
160176
return
161177

162178
case reflect.Int:
163-
var num int64
164-
num, _n, err = DecodeVarint(bz)
179+
var num uint64
180+
num, _n, err = DecodeUvarint(bz)
165181
if slide(&bz, &n, _n) && err != nil {
166182
return
167183
}
168-
rv.SetInt(num)
184+
if int64(num) > int64(maxInt) || int64(num) < int64(minInt) {
185+
err = ErrOverflowInt
186+
return
187+
}
188+
rv.SetInt(int64(num))
169189
return
170190

171191
//----------------------------------------

binary-encode.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,14 @@ func (cdc *Codec) encodeReflectBinary(w io.Writer, info *TypeInfo, rv reflect.Va
8686
if fopts.BinFixed64 {
8787
err = EncodeInt64(w, rv.Int())
8888
} else {
89-
err = EncodeVarint(w, rv.Int())
89+
err = EncodeUvarint(w, uint64(rv.Int()))
9090
}
9191

9292
case reflect.Int32:
9393
if fopts.BinFixed32 {
9494
err = EncodeInt32(w, int32(rv.Int()))
9595
} else {
96-
err = EncodeVarint(w, rv.Int())
96+
err = EncodeUvarint(w, uint64(rv.Int()))
9797
}
9898

9999
case reflect.Int16:
@@ -103,7 +103,7 @@ func (cdc *Codec) encodeReflectBinary(w io.Writer, info *TypeInfo, rv reflect.Va
103103
err = EncodeInt8(w, int8(rv.Int()))
104104

105105
case reflect.Int:
106-
err = EncodeVarint(w, rv.Int())
106+
err = EncodeUvarint(w, uint64(rv.Int()))
107107

108108
//----------------------------------------
109109
// Unsigned

binary_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func TestStructSlice(t *testing.T) {
168168

169169
bz, err := cdc.MarshalBinaryBare(f)
170170
assert.NoError(t, err)
171-
assert.Equal(t, "0A0608C80110CA010A0608CC0110CE01", fmt.Sprintf("%X", bz))
171+
assert.Equal(t, "0A04086410650A0408661067", fmt.Sprintf("%X", bz))
172172
t.Log(bz)
173173
var f2 Foos
174174
cdc.UnmarshalBinaryBare(bz, &f2)

encoder.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ func EncodeUint64(w io.Writer, u uint64) (err error) {
7676
return
7777
}
7878

79+
// EncodeUvarint is used to encode golang's int, int32, int64 by default. unless specified differently by the
80+
// `binary:"fixed32"`, `binary:"fixed64"`, or `binary:"zigzag32"` `binary:"zigzag64"` tags.
81+
// It matches protobufs varint encoding.
7982
func EncodeUvarint(w io.Writer, u uint64) (err error) {
8083
var buf [10]byte
8184
n := binary.PutUvarint(buf[:], u)

example_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func Example() {
6565
fmt.Printf("Decoded successfully: %v\n", *bm == *bm2)
6666

6767
// Output:
68-
// Encoded: 0C740613650A0341424310C801 (err: <nil>)
68+
// Encoded: 0B740613650A034142431064 (err: <nil>)
6969
// Decoded: &{ABC 100} (err: <nil>)
7070
// Decoded successfully: true
7171
}

tests/proto3/proto/compat.pb.go

Lines changed: 64 additions & 55 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/proto3/proto/compat.proto

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ message TestInt32 {
4242
int32 Int32 = 1;
4343
}
4444

45-
message TestInt64 {
46-
int64 Int64 = 1;
45+
46+
message TestInts {
47+
int32 Int32 = 1;
48+
int64 Int64 = 2;
4749
}

0 commit comments

Comments
 (0)