From 701d08ec7c2701338ef2bc438378c22adbfb74ee Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Thu, 29 Sep 2016 16:03:03 -0400 Subject: [PATCH] fix some overflows --- bit/decode.go | 20 ++++++++++++++++++++ ent/array.go | 2 +- ent/atoms.go | 12 ++---------- ent/env.go | 4 +++- ent/generic.go | 14 +++++++++++++- ent/selection.go | 2 +- 6 files changed, 40 insertions(+), 14 deletions(-) diff --git a/bit/decode.go b/bit/decode.go index 41c6d0f..6edc6b6 100644 --- a/bit/decode.go +++ b/bit/decode.go @@ -99,6 +99,26 @@ func ReadVarInt32(r Reader) uint32 { return uint32(x) } +// reads a 32bit varint +func ReadVarInt16(r Reader) uint16 { + var ( + x uint64 + b uint64 + shift uint + ) + for ; shift < 16; shift += 7 { + b = r.ReadBits(8) + if r.Err() != nil { + return 0 + } + x |= b & 0x7f << shift + if b&0x80 == 0 { + return uint16(x) + } + } + return uint16(x) +} + func ReadBool(r Reader) bool { return r.ReadBits(1) != 0 } diff --git a/ent/array.go b/ent/array.go index b22640b..306f016 100644 --- a/ent/array.go +++ b/ent/array.go @@ -50,7 +50,7 @@ type array_t struct { } func (t *array_t) nü() value { return array{t: t, slots: make([]value, t.count)} } -func (t array_t) typeName() string { return fmt.Sprintf("array:%s", t.elem.typeName()) } +func (t array_t) typeName() string { return fmt.Sprintf("%s[%d]", t.elem.typeName(), t.count) } type array struct { t *array_t diff --git a/ent/atoms.go b/ent/atoms.go index c5ec09e..71c5fd2 100644 --- a/ent/atoms.go +++ b/ent/atoms.go @@ -48,11 +48,7 @@ type uint8_v uint8 func (v uint8_v) tÿpe() tÿpe { return uint8_t } func (v *uint8_v) read(r bit.Reader) error { - u := bit.ReadVarInt(r) - if u > 1<<8-1 { - return fmt.Errorf("uint8 overflow: %d", u) - } - *v = uint8_v(u) + *v = uint8_v(r.ReadBits(8)) return r.Err() } @@ -75,11 +71,7 @@ type uint16_v uint16 func (v uint16_v) tÿpe() tÿpe { return uint16_t } func (v *uint16_v) read(r bit.Reader) error { - u := bit.ReadVarInt(r) - if u > 1<<16-1 { - return fmt.Errorf("uint16 overflow: %d", u) - } - *v = uint16_v(u) + *v = uint16_v(bit.ReadVarInt16(r)) return r.Err() } diff --git a/ent/env.go b/ent/env.go index 3b060e8..ca9ab38 100644 --- a/ent/env.go +++ b/ent/env.go @@ -2,6 +2,7 @@ package ent import ( "github.com/golang/protobuf/proto" + "os" "strconv" "github.com/jordanorelli/hyperstone/bit" @@ -178,7 +179,8 @@ func (e *Env) syncBaselineTable(t *stbl.Table) { Debug.Printf("selections: %v", selections) for _, s := range selections { if err := s.fillSlots(ent, r); err != nil { - Debug.Printf("unable to fill selection %s for %s: %v", s, className, err) + Debug.Printf("syncBaseline fill error: %v", err) + os.Exit(1) } } } diff --git a/ent/generic.go b/ent/generic.go index 5a3a5e5..ea80720 100644 --- a/ent/generic.go +++ b/ent/generic.go @@ -2,6 +2,7 @@ package ent import ( "fmt" + "strconv" "strings" "github.com/jordanorelli/hyperstone/bit" @@ -80,7 +81,7 @@ func (t cutl_vector_t) typeName() string { } type cutl_vector struct { - t tÿpe + t *cutl_vector_t slots []value } @@ -98,3 +99,14 @@ func (v cutl_vector) String() string { } return fmt.Sprintf("%s(%d)%v", v.t.typeName(), len(v.slots), v.slots) } + +func (v *cutl_vector) slotType(int) tÿpe { return v.t.elem } +func (v *cutl_vector) slotName(n int) string { return strconv.Itoa(n) } +func (v *cutl_vector) setSlotValue(slot int, val value) { + if slot == len(v.slots) { + v.slots = append(v.slots, val) + } else { + v.slots[slot] = val + } +} +func (v *cutl_vector) getSlotValue(slot int) value { return v.slots[slot] } diff --git a/ent/selection.go b/ent/selection.go index 16c9f74..0f5f620 100644 --- a/ent/selection.go +++ b/ent/selection.go @@ -32,7 +32,7 @@ func (s selection) fillSlotsIter(offset int, dest slotted, path string, r bit.Re case 1: v := dest.slotType(slot).nü() if err := v.read(r); err != nil { - return fmt.Errorf("unable to fill selection: %v", err) + return fmt.Errorf("unable to fill selection %v for %s.%s (%s): %v", s, path, dest.slotName(slot), dest.slotType(slot).typeName(), err) } old := dest.getSlotValue(slot) dest.setSlotValue(slot, v)