diff --git a/utils/wrappers/packing.go b/utils/wrappers/packing.go index da9bfc7..cd00f98 100644 --- a/utils/wrappers/packing.go +++ b/utils/wrappers/packing.go @@ -24,6 +24,8 @@ const ( IntLen = 4 // LongLen is the number of bytes per long LongLen = 8 + // BoolLen is the number of bytes per bool + BoolLen = 1 ) var ( @@ -242,7 +244,9 @@ func (p *Packer) PackFixedByteSlices(byteSlices [][]byte) { } } -// UnpackFixedByteSlices unpack a byte slice slice to the byte array +// UnpackFixedByteSlices returns a byte slice slice from the byte array. +// Each byte slice has the specified size. The number of byte slices is +// read from the byte array. func (p *Packer) UnpackFixedByteSlices(size int) [][]byte { sliceSize := p.UnpackInt() bytes := [][]byte(nil) diff --git a/utils/wrappers/packing_test.go b/utils/wrappers/packing_test.go index a97463f..6937d27 100644 --- a/utils/wrappers/packing_test.go +++ b/utils/wrappers/packing_test.go @@ -5,10 +5,61 @@ package wrappers import ( "bytes" + "reflect" "testing" ) -func TestPackerByte(t *testing.T) { +const ( + ByteSentinal = 0 + ShortSentinal = 0 + IntSentinal = 0 + LongSentinal = 0 + BoolSentinal = false +) + +func TestPackerCheckSpace(t *testing.T) { + p := Packer{Offset: -1} + p.CheckSpace(1) + if !p.Errored() { + t.Fatal("Expected errNegativeOffset") + } + + p = Packer{} + p.CheckSpace(-1) + if !p.Errored() { + t.Fatal("Expected errInvalidInput") + } + + p = Packer{Bytes: []byte{0x01}, Offset: 1} + p.CheckSpace(1) + if !p.Errored() { + t.Fatal("Expected errBadLength") + } + + p = Packer{Bytes: []byte{0x01}, Offset: 2} + p.CheckSpace(0) + if !p.Errored() { + t.Fatal("Expected errBadLength, due to out of bounds offset") + } +} + +func TestPackerExpand(t *testing.T) { + p := Packer{Bytes: []byte{0x01}, Offset: 2} + p.Expand(1) + if !p.Errored() { + t.Fatal("packer.Expand didn't notice packer had out of bounds offset") + } + + p = Packer{Bytes: []byte{0x01, 0x02, 0x03}, Offset: 0} + p.Expand(1) + if p.Errored() { + t.Fatalf("packer.Expand unexpectedly had error %s", p.Err) + } else if len(p.Bytes) != 3 { + t.Fatalf("packer.Expand modified byte array, when it didn't need to") + } +} + +func TestPackerPackByte(t *testing.T) { p := Packer{MaxSize: 1} p.PackByte(0x01) @@ -25,9 +76,37 @@ func TestPackerByte(t *testing.T) { if !bytes.Equal(p.Bytes, expected) { t.Fatalf("Packer.PackByte wrote:\n%v\nExpected:\n%v", p.Bytes, expected) } + + p.PackByte(0x02) + if !p.Errored() { + t.Fatal("Packer.PackByte did not fail when attempt was beyond p.MaxSize") + } } -func TestPackerShort(t *testing.T) { +func TestPackerUnpackByte(t *testing.T) { + var ( + p = Packer{Bytes: []byte{0x01}, Offset: 0} + actual = p.UnpackByte() + expected byte = 1 + expectedLen = ByteLen + ) + if p.Errored() { + t.Fatalf("Packer.UnpackByte unexpectedly raised %s", p.Err) + } else if actual != expected { + t.Fatalf("Packer.UnpackByte returned %d, but expected %d", actual, expected) + } else if p.Offset != expectedLen { + t.Fatalf("Packer.UnpackByte left Offset %d, expected %d", p.Offset, expectedLen) + } + + actual = p.UnpackByte() + if !p.Errored() { + t.Fatalf("Packer.UnpackByte should have set error, due to attempted out of bounds read") + } else if actual != ByteSentinal { + t.Fatalf("Packer.UnpackByte returned %d, expected sentinal value %d", actual, ByteSentinal) + } +} + +func TestPackerPackShort(t *testing.T) { p := Packer{MaxSize: 2} p.PackShort(0x0102) @@ -46,7 +125,30 @@ func TestPackerShort(t *testing.T) { } } -func TestPackerInt(t *testing.T) { +func TestPackerUnpackShort(t *testing.T) { + var ( + p = Packer{Bytes: []byte{0x01, 0x02}, Offset: 0} + actual = p.UnpackShort() + expected uint16 = 0x0102 + expectedLen = ShortLen + ) + if p.Errored() { + t.Fatalf("Packer.UnpackShort unexpectedly raised %s", p.Err) + } else if actual != expected { + t.Fatalf("Packer.UnpackShort returned %d, but expected %d", actual, expected) + } else if p.Offset != expectedLen { + t.Fatalf("Packer.UnpackShort left Offset %d, expected %d", p.Offset, expectedLen) + } + + actual = p.UnpackShort() + if !p.Errored() { + t.Fatalf("Packer.UnpackShort should have set error, due to attempted out of bounds read") + } else if actual != ShortSentinal { + t.Fatalf("Packer.UnpackShort returned %d, expected sentinal value %d", actual, ShortSentinal) + } +} + +func TestPackerPackInt(t *testing.T) { p := Packer{MaxSize: 4} p.PackInt(0x01020304) @@ -63,9 +165,37 @@ func TestPackerInt(t *testing.T) { if !bytes.Equal(p.Bytes, expected) { t.Fatalf("Packer.PackInt wrote:\n%v\nExpected:\n%v", p.Bytes, expected) } + + p.PackInt(0x05060708) + if !p.Errored() { + t.Fatal("Packer.PackInt did not fail when attempt was beyond p.MaxSize") + } } -func TestPackerLong(t *testing.T) { +func TestPackerUnpackInt(t *testing.T) { + var ( + p = Packer{Bytes: []byte{0x01, 0x02, 0x03, 0x04}, Offset: 0} + actual = p.UnpackInt() + expected uint32 = 0x01020304 + expectedLen = IntLen + ) + if p.Errored() { + t.Fatalf("Packer.UnpackInt unexpectedly raised %s", p.Err) + } else if actual != expected { + t.Fatalf("Packer.UnpackInt returned %d, but expected %d", actual, expected) + } else if p.Offset != expectedLen { + t.Fatalf("Packer.UnpackInt left Offset %d, expected %d", p.Offset, expectedLen) + } + + actual = p.UnpackInt() + if !p.Errored() { + t.Fatalf("Packer.UnpackInt should have set error, due to attempted out of bounds read") + } else if actual != IntSentinal { + t.Fatalf("Packer.UnpackInt returned %d, expected sentinal value %d", actual, IntSentinal) + } +} + +func TestPackerPackLong(t *testing.T) { p := Packer{MaxSize: 8} p.PackLong(0x0102030405060708) @@ -82,6 +212,175 @@ func TestPackerLong(t *testing.T) { if !bytes.Equal(p.Bytes, expected) { t.Fatalf("Packer.PackLong wrote:\n%v\nExpected:\n%v", p.Bytes, expected) } + + p.PackLong(0x090a0b0c0d0e0f00) + if !p.Errored() { + t.Fatal("Packer.PackLong did not fail when attempt was beyond p.MaxSize") + } +} + +func TestPackerUnpackLong(t *testing.T) { + var ( + p = Packer{Bytes: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, Offset: 0} + actual = p.UnpackLong() + expected uint64 = 0x0102030405060708 + expectedLen = LongLen + ) + if p.Errored() { + t.Fatalf("Packer.UnpackLong unexpectedly raised %s", p.Err) + } else if actual != expected { + t.Fatalf("Packer.UnpackLong returned %d, but expected %d", actual, expected) + } else if p.Offset != expectedLen { + t.Fatalf("Packer.UnpackLong left Offset %d, expected %d", p.Offset, expectedLen) + } + + actual = p.UnpackLong() + if !p.Errored() { + t.Fatalf("Packer.UnpackLong should have set error, due to attempted out of bounds read") + } else if actual != LongSentinal { + t.Fatalf("Packer.UnpackLong returned %d, expected sentinal value %d", actual, LongSentinal) + } +} + +func TestPackerPackFixedBytes(t *testing.T) { + p := Packer{MaxSize: 3} + + p.PackFixedBytes([]byte("Ava")) + + if p.Errored() { + t.Fatal(p.Err) + } + + if size := len(p.Bytes); size != 3 { + t.Fatalf("Packer.PackFixedBytes wrote %d byte(s) but expected %d byte(s)", size, 3) + } + + expected := []byte("Ava") + if !bytes.Equal(p.Bytes, expected) { + t.Fatalf("Packer.PackFixedBytes wrote:\n%v\nExpected:\n%v", p.Bytes, expected) + } + + p.PackFixedBytes([]byte("Ava")) + if !p.Errored() { + t.Fatal("Packer.PackFixedBytes did not fail when attempt was beyond p.MaxSize") + } +} + +func TestPackerUnpackFixedBytes(t *testing.T) { + var ( + p = Packer{Bytes: []byte("Ava")} + actual = p.UnpackFixedBytes(3) + expected = []byte("Ava") + expectedLen = 3 + ) + if p.Errored() { + t.Fatalf("Packer.UnpackFixedBytes unexpectedly raised %s", p.Err) + } else if !bytes.Equal(actual, expected) { + t.Fatalf("Packer.UnpackFixedBytes returned %d, but expected %d", actual, expected) + } else if p.Offset != expectedLen { + t.Fatalf("Packer.UnpackFixedBytes left Offset %d, expected %d", p.Offset, expectedLen) + } + + actual = p.UnpackFixedBytes(3) + if !p.Errored() { + t.Fatalf("Packer.UnpackFixedBytes should have set error, due to attempted out of bounds read") + } else if actual != nil { + t.Fatalf("Packer.UnpackFixedBytes returned %v, expected sentinal value %v", actual, nil) + } +} + +func TestPackerPackBytes(t *testing.T) { + p := Packer{MaxSize: 7} + + p.PackBytes([]byte("Ava")) + + if p.Errored() { + t.Fatal(p.Err) + } + + if size := len(p.Bytes); size != 7 { + t.Fatalf("Packer.PackBytes wrote %d byte(s) but expected %d byte(s)", size, 7) + } + + expected := []byte("\x00\x00\x00\x03Ava") + if !bytes.Equal(p.Bytes, expected) { + t.Fatalf("Packer.PackBytes wrote:\n%v\nExpected:\n%v", p.Bytes, expected) + } + + p.PackBytes([]byte("Ava")) + if !p.Errored() { + t.Fatal("Packer.PackBytes did not fail when attempt was beyond p.MaxSize") + } +} + +func TestPackerUnpackBytes(t *testing.T) { + var ( + p = Packer{Bytes: []byte("\x00\x00\x00\x03Ava")} + actual = p.UnpackBytes() + expected = []byte("Ava") + expectedLen = 7 + ) + if p.Errored() { + t.Fatalf("Packer.UnpackBytes unexpectedly raised %s", p.Err) + } else if !bytes.Equal(actual, expected) { + t.Fatalf("Packer.UnpackBytes returned %d, but expected %d", actual, expected) + } else if p.Offset != expectedLen { + t.Fatalf("Packer.UnpackBytes left Offset %d, expected %d", p.Offset, expectedLen) + } + + actual = p.UnpackBytes() + if !p.Errored() { + t.Fatalf("Packer.UnpackBytes should have set error, due to attempted out of bounds read") + } else if actual != nil { + t.Fatalf("Packer.UnpackBytes returned %v, expected sentinal value %v", actual, nil) + } +} + +func TestPackerPackFixedByteSlices(t *testing.T) { + p := Packer{MaxSize: 10} + + p.PackFixedByteSlices([][]byte{[]byte("Ava"), []byte("Eva")}) + + if p.Errored() { + t.Fatal(p.Err) + } + + if size := len(p.Bytes); size != 10 { + t.Fatalf("Packer.PackFixedByteSlices wrote %d byte(s) but expected %d byte(s)", size, 13) + } + + expected := []byte("\x00\x00\x00\x02AvaEva") + if !bytes.Equal(p.Bytes, expected) { + t.Fatalf("Packer.PackPackFixedByteSlicesBytes wrote:\n%v\nExpected:\n%v", p.Bytes, expected) + } + + p.PackFixedByteSlices([][]byte{[]byte("Ava"), []byte("Eva")}) + if !p.Errored() { + t.Fatal("Packer.PackFixedByteSlices did not fail when attempt was beyond p.MaxSize") + } +} + +func TestPackerUnpackFixedByteSlices(t *testing.T) { + var ( + p = Packer{Bytes: []byte("\x00\x00\x00\x02AvaEva")} + actual = p.UnpackFixedByteSlices(3) + expected = [][]byte{[]byte("Ava"), []byte("Eva")} + expectedLen = 10 + ) + if p.Errored() { + t.Fatalf("Packer.UnpackFixedByteSlices unexpectedly raised %s", p.Err) + } else if !reflect.DeepEqual(actual, expected) { + t.Fatalf("Packer.UnpackFixedByteSlices returned %d, but expected %d", actual, expected) + } else if p.Offset != expectedLen { + t.Fatalf("Packer.UnpackFixedByteSlices left Offset %d, expected %d", p.Offset, expectedLen) + } + + actual = p.UnpackFixedByteSlices(3) + if !p.Errored() { + t.Fatalf("Packer.UnpackFixedByteSlices should have set error, due to attempted out of bounds read") + } else if actual != nil { + t.Fatalf("Packer.UnpackFixedByteSlices returned %v, expected sentinal value %v", actual, nil) + } } func TestPackerString(t *testing.T) { @@ -151,3 +450,59 @@ func TestPackBool(t *testing.T) { t.Fatal("got back wrong values") } } + +func TestPackerPackBool(t *testing.T) { + p := Packer{MaxSize: 1} + + p.PackBool(true) + + if p.Errored() { + t.Fatal(p.Err) + } + + if size := len(p.Bytes); size != 1 { + t.Fatalf("Packer.PackBool wrote %d byte(s) but expected %d byte(s)", size, 1) + } + + expected := []byte{0x01} + if !bytes.Equal(p.Bytes, expected) { + t.Fatalf("Packer.PackBool wrote:\n%v\nExpected:\n%v", p.Bytes, expected) + } + + p.PackBool(false) + if !p.Errored() { + t.Fatal("Packer.PackLong did not fail when attempt was beyond p.MaxSize") + } +} + +func TestPackerUnpackBool(t *testing.T) { + var ( + p = Packer{Bytes: []byte{0x01}, Offset: 0} + actual = p.UnpackBool() + expected bool = true + expectedLen = BoolLen + ) + if p.Errored() { + t.Fatalf("Packer.UnpackBool unexpectedly raised %s", p.Err) + } else if actual != expected { + t.Fatalf("Packer.UnpackBool returned %t, but expected %t", actual, expected) + } else if p.Offset != expectedLen { + t.Fatalf("Packer.UnpackBool left Offset %d, expected %d", p.Offset, expectedLen) + } + + actual = p.UnpackBool() + if !p.Errored() { + t.Fatalf("Packer.UnpackBool should have set error, due to attempted out of bounds read") + } else if actual != BoolSentinal { + t.Fatalf("Packer.UnpackBool returned %t, expected sentinal value %t", actual, BoolSentinal) + } + + p = Packer{Bytes: []byte{0x42}, Offset: 0} + expected = false + actual = p.UnpackBool() + if !p.Errored() { + t.Fatalf("Packer.UnpackBool id not raise error for invalid boolean value %v", p.Bytes) + } else if actual != expected { + t.Fatalf("Packer.UnpackBool returned %t, expected sentinal value %t", actual, BoolSentinal) + } +}