Add in Stronger Length Checks (#9758)

* add changes

* radek's review

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
This commit is contained in:
Nishant Das
2021-10-09 01:41:36 +08:00
committed by GitHub
parent 63349d863b
commit 65d2df4609
13 changed files with 121 additions and 38 deletions

View File

@@ -16,6 +16,9 @@ var hexRegex = regexp.MustCompile("^0x[0-9a-fA-F]+$")
// ToBytes returns integer x to bytes in little-endian format at the specified length.
// Spec defines similar method uint_to_bytes(n: uint) -> bytes, which is equivalent to ToBytes(n, 8).
func ToBytes(x uint64, length int) []byte {
if length < 0 {
length = 0
}
makeLength := length
if length < 8 {
makeLength = 8
@@ -70,6 +73,9 @@ func Bytes32(x uint64) []byte {
// FromBytes4 returns an integer which is stored in the little-endian format(4, 'little')
// from a byte array.
func FromBytes4(x []byte) uint64 {
if len(x) < 4 {
return 0
}
empty4bytes := make([]byte, 4)
return binary.LittleEndian.Uint64(append(x[:4], empty4bytes...))
}
@@ -77,6 +83,9 @@ func FromBytes4(x []byte) uint64 {
// FromBytes8 returns an integer which is stored in the little-endian format(8, 'little')
// from a byte array.
func FromBytes8(x []byte) uint64 {
if len(x) < 8 {
return 0
}
return binary.LittleEndian.Uint64(x)
}
@@ -134,6 +143,9 @@ func ToBool(x byte) bool {
// FromBytes2 returns an integer which is stored in the little-endian format(2, 'little')
// from a byte array.
func FromBytes2(x []byte) uint16 {
if len(x) < 2 {
return 0
}
return binary.LittleEndian.Uint16(x[:2])
}
@@ -172,9 +184,11 @@ func Trunc(x []byte) []byte {
// ToLowInt64 returns the lowest 8 bytes interpreted as little endian.
func ToLowInt64(x []byte) int64 {
if len(x) > 8 {
x = x[:8]
if len(x) < 8 {
return 0
}
// Use the first 8 bytes.
x = x[:8]
return int64(binary.LittleEndian.Uint64(x))
}
@@ -249,7 +263,7 @@ func SetBit(b []byte, i int) []byte {
// Returns the original bitlist if the index `i`
// is out of range.
func ClearBit(b []byte, i int) []byte {
if i >= len(b)*8 {
if i >= len(b)*8 || i < 0 {
return b
}
@@ -288,6 +302,9 @@ func HighestBitIndexAt(b []byte, index int) (int, error) {
if b == nil || bLength == 0 {
return 0, errors.New("input list can't be empty or nil")
}
if index < 0 {
return 0, errors.Errorf("index is negative: %d", index)
}
start := index / 8
if start >= bLength {

View File

@@ -471,3 +471,29 @@ func TestSafeCopy2dBytes(t *testing.T) {
})
}
}
func TestBytesInvalidInputs(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("Test panicked: %v", r)
}
}()
rawBytes := bytesutil.ToBytes(100, -10)
assert.DeepEqual(t, []byte{}, rawBytes)
_, err := bytesutil.HighestBitIndexAt([]byte{'A', 'B', 'C'}, -5)
assert.ErrorContains(t, "index is negative", err)
// There should be no panic
_ = bytesutil.ClearBit([]byte{'C', 'D', 'E'}, -7)
res := bytesutil.FromBytes4([]byte{})
assert.Equal(t, res, uint64(0))
newRes := bytesutil.FromBytes2([]byte{})
assert.Equal(t, newRes, uint16(0))
res = bytesutil.FromBytes8([]byte{})
assert.Equal(t, res, uint64(0))
intRes := bytesutil.ToLowInt64([]byte{})
assert.Equal(t, intRes, int64(0))
}