...

Source file src/encoding/binary/varint_test.go

Documentation: encoding/binary

		 1  // Copyright 2011 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  package binary
		 6  
		 7  import (
		 8  	"bytes"
		 9  	"io"
		10  	"math"
		11  	"testing"
		12  )
		13  
		14  func testConstant(t *testing.T, w uint, max int) {
		15  	buf := make([]byte, MaxVarintLen64)
		16  	n := PutUvarint(buf, 1<<w-1)
		17  	if n != max {
		18  		t.Errorf("MaxVarintLen%d = %d; want %d", w, max, n)
		19  	}
		20  }
		21  
		22  func TestConstants(t *testing.T) {
		23  	testConstant(t, 16, MaxVarintLen16)
		24  	testConstant(t, 32, MaxVarintLen32)
		25  	testConstant(t, 64, MaxVarintLen64)
		26  }
		27  
		28  func testVarint(t *testing.T, x int64) {
		29  	buf := make([]byte, MaxVarintLen64)
		30  	n := PutVarint(buf, x)
		31  	y, m := Varint(buf[0:n])
		32  	if x != y {
		33  		t.Errorf("Varint(%d): got %d", x, y)
		34  	}
		35  	if n != m {
		36  		t.Errorf("Varint(%d): got n = %d; want %d", x, m, n)
		37  	}
		38  
		39  	y, err := ReadVarint(bytes.NewReader(buf))
		40  	if err != nil {
		41  		t.Errorf("ReadVarint(%d): %s", x, err)
		42  	}
		43  	if x != y {
		44  		t.Errorf("ReadVarint(%d): got %d", x, y)
		45  	}
		46  }
		47  
		48  func testUvarint(t *testing.T, x uint64) {
		49  	buf := make([]byte, MaxVarintLen64)
		50  	n := PutUvarint(buf, x)
		51  	y, m := Uvarint(buf[0:n])
		52  	if x != y {
		53  		t.Errorf("Uvarint(%d): got %d", x, y)
		54  	}
		55  	if n != m {
		56  		t.Errorf("Uvarint(%d): got n = %d; want %d", x, m, n)
		57  	}
		58  
		59  	y, err := ReadUvarint(bytes.NewReader(buf))
		60  	if err != nil {
		61  		t.Errorf("ReadUvarint(%d): %s", x, err)
		62  	}
		63  	if x != y {
		64  		t.Errorf("ReadUvarint(%d): got %d", x, y)
		65  	}
		66  }
		67  
		68  var tests = []int64{
		69  	-1 << 63,
		70  	-1<<63 + 1,
		71  	-1,
		72  	0,
		73  	1,
		74  	2,
		75  	10,
		76  	20,
		77  	63,
		78  	64,
		79  	65,
		80  	127,
		81  	128,
		82  	129,
		83  	255,
		84  	256,
		85  	257,
		86  	1<<63 - 1,
		87  }
		88  
		89  func TestVarint(t *testing.T) {
		90  	for _, x := range tests {
		91  		testVarint(t, x)
		92  		testVarint(t, -x)
		93  	}
		94  	for x := int64(0x7); x != 0; x <<= 1 {
		95  		testVarint(t, x)
		96  		testVarint(t, -x)
		97  	}
		98  }
		99  
	 100  func TestUvarint(t *testing.T) {
	 101  	for _, x := range tests {
	 102  		testUvarint(t, uint64(x))
	 103  	}
	 104  	for x := uint64(0x7); x != 0; x <<= 1 {
	 105  		testUvarint(t, x)
	 106  	}
	 107  }
	 108  
	 109  func TestBufferTooSmall(t *testing.T) {
	 110  	buf := []byte{0x80, 0x80, 0x80, 0x80}
	 111  	for i := 0; i <= len(buf); i++ {
	 112  		buf := buf[0:i]
	 113  		x, n := Uvarint(buf)
	 114  		if x != 0 || n != 0 {
	 115  			t.Errorf("Uvarint(%v): got x = %d, n = %d", buf, x, n)
	 116  		}
	 117  
	 118  		x, err := ReadUvarint(bytes.NewReader(buf))
	 119  		if x != 0 || err != io.EOF {
	 120  			t.Errorf("ReadUvarint(%v): got x = %d, err = %s", buf, x, err)
	 121  		}
	 122  	}
	 123  }
	 124  
	 125  // Ensure that we catch overflows of bytes going past MaxVarintLen64.
	 126  // See issue https://golang.org/issues/41185
	 127  func TestBufferTooBigWithOverflow(t *testing.T) {
	 128  	tests := []struct {
	 129  		in				[]byte
	 130  		name			string
	 131  		wantN		 int
	 132  		wantValue uint64
	 133  	}{
	 134  		{
	 135  			name: "invalid: 1000 bytes",
	 136  			in: func() []byte {
	 137  				b := make([]byte, 1000)
	 138  				for i := range b {
	 139  					b[i] = 0xff
	 140  				}
	 141  				b[999] = 0
	 142  				return b
	 143  			}(),
	 144  			wantN:		 -11,
	 145  			wantValue: 0,
	 146  		},
	 147  		{
	 148  			name:			"valid: math.MaxUint64-40",
	 149  			in:				[]byte{0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
	 150  			wantValue: math.MaxUint64 - 40,
	 151  			wantN:		 10,
	 152  		},
	 153  		{
	 154  			name:			"invalid: with more than MaxVarintLen64 bytes",
	 155  			in:				[]byte{0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
	 156  			wantN:		 -11,
	 157  			wantValue: 0,
	 158  		},
	 159  		{
	 160  			name:			"invalid: 10th byte",
	 161  			in:				[]byte{0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f},
	 162  			wantN:		 -10,
	 163  			wantValue: 0,
	 164  		},
	 165  	}
	 166  
	 167  	for _, tt := range tests {
	 168  		tt := tt
	 169  		t.Run(tt.name, func(t *testing.T) {
	 170  			value, n := Uvarint(tt.in)
	 171  			if g, w := n, tt.wantN; g != w {
	 172  				t.Errorf("bytes returned=%d, want=%d", g, w)
	 173  			}
	 174  			if g, w := value, tt.wantValue; g != w {
	 175  				t.Errorf("value=%d, want=%d", g, w)
	 176  			}
	 177  		})
	 178  	}
	 179  }
	 180  
	 181  func testOverflow(t *testing.T, buf []byte, x0 uint64, n0 int, err0 error) {
	 182  	x, n := Uvarint(buf)
	 183  	if x != 0 || n != n0 {
	 184  		t.Errorf("Uvarint(% X): got x = %d, n = %d; want 0, %d", buf, x, n, n0)
	 185  	}
	 186  
	 187  	r := bytes.NewReader(buf)
	 188  	len := r.Len()
	 189  	x, err := ReadUvarint(r)
	 190  	if x != x0 || err != err0 {
	 191  		t.Errorf("ReadUvarint(%v): got x = %d, err = %s; want %d, %s", buf, x, err, x0, err0)
	 192  	}
	 193  	if read := len - r.Len(); read > MaxVarintLen64 {
	 194  		t.Errorf("ReadUvarint(%v): read more than MaxVarintLen64 bytes, got %d", buf, read)
	 195  	}
	 196  }
	 197  
	 198  func TestOverflow(t *testing.T) {
	 199  	testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x2}, 0, -10, overflow)
	 200  	testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x1, 0, 0}, 0, -11, overflow)
	 201  	testOverflow(t, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 1<<64-1, -11, overflow) // 11 bytes, should overflow
	 202  }
	 203  
	 204  func TestNonCanonicalZero(t *testing.T) {
	 205  	buf := []byte{0x80, 0x80, 0x80, 0}
	 206  	x, n := Uvarint(buf)
	 207  	if x != 0 || n != 4 {
	 208  		t.Errorf("Uvarint(%v): got x = %d, n = %d; want 0, 4", buf, x, n)
	 209  
	 210  	}
	 211  }
	 212  
	 213  func BenchmarkPutUvarint32(b *testing.B) {
	 214  	buf := make([]byte, MaxVarintLen32)
	 215  	b.SetBytes(4)
	 216  	for i := 0; i < b.N; i++ {
	 217  		for j := uint(0); j < MaxVarintLen32; j++ {
	 218  			PutUvarint(buf, 1<<(j*7))
	 219  		}
	 220  	}
	 221  }
	 222  
	 223  func BenchmarkPutUvarint64(b *testing.B) {
	 224  	buf := make([]byte, MaxVarintLen64)
	 225  	b.SetBytes(8)
	 226  	for i := 0; i < b.N; i++ {
	 227  		for j := uint(0); j < MaxVarintLen64; j++ {
	 228  			PutUvarint(buf, 1<<(j*7))
	 229  		}
	 230  	}
	 231  }
	 232  

View as plain text