Commit 39ea1352 authored by Kamil Kisiel's avatar Kamil Kisiel

Merge branch 'no-panics' of https://github.com/larzconwell/og-rek into larzconwell-no-panics

parents 92c2c3bf 06476df7
...@@ -8,6 +8,14 @@ import ( ...@@ -8,6 +8,14 @@ import (
"reflect" "reflect"
) )
type TypeError struct {
typ string
}
func (te *TypeError) Error() string {
return fmt.Sprintf("no support for type '%s'", te.typ)
}
// An Encoder encodes Go data structures into pickle byte stream // An Encoder encodes Go data structures into pickle byte stream
type Encoder struct { type Encoder struct {
w io.Writer w io.Writer
...@@ -74,7 +82,7 @@ func (e *Encoder) encode(rv reflect.Value) error { ...@@ -74,7 +82,7 @@ func (e *Encoder) encode(rv reflect.Value) error {
_, err := e.w.Write([]byte{opNone}) _, err := e.w.Write([]byte{opNone})
return err return err
default: default:
panic(fmt.Sprintf("no support for type '%s'", rk.String())) return &TypeError{typ: rk.String()}
} }
return nil return nil
......
...@@ -80,6 +80,7 @@ const ( ...@@ -80,6 +80,7 @@ const (
var errNotImplemented = errors.New("unimplemented opcode") var errNotImplemented = errors.New("unimplemented opcode")
var ErrInvalidPickleVersion = errors.New("invalid pickle version") var ErrInvalidPickleVersion = errors.New("invalid pickle version")
var ErrNoMarker = errors.New("no marker in stack")
type OpcodeError struct { type OpcodeError struct {
Key byte Key byte
...@@ -243,15 +244,15 @@ func (d *Decoder) mark() { ...@@ -243,15 +244,15 @@ func (d *Decoder) mark() {
} }
// Return the position of the topmost marker // Return the position of the topmost marker
func (d *Decoder) marker() int { func (d *Decoder) marker() (int, error) {
m := mark{} m := mark{}
var k int var k int
for k = len(d.stack) - 1; d.stack[k] != m && k > 0; k-- { for k = len(d.stack) - 1; d.stack[k] != m && k > 0; k-- {
} }
if k >= 0 { if k >= 0 {
return k return k, nil
} }
panic("no marker in stack") return 0, ErrNoMarker
} }
// Append a new value // Append a new value
...@@ -560,7 +561,11 @@ func (d *Decoder) global() error { ...@@ -560,7 +561,11 @@ func (d *Decoder) global() error {
} }
func (d *Decoder) loadDict() error { func (d *Decoder) loadDict() error {
k := d.marker() k, err := d.marker()
if err != nil {
return err
}
m := make(map[interface{}]interface{}, 0) m := make(map[interface{}]interface{}, 0)
items := d.stack[k+1:] items := d.stack[k+1:]
for i := 0; i < len(items); i += 2 { for i := 0; i < len(items); i += 2 {
...@@ -577,7 +582,11 @@ func (d *Decoder) loadEmptyDict() error { ...@@ -577,7 +582,11 @@ func (d *Decoder) loadEmptyDict() error {
} }
func (d *Decoder) loadAppends() error { func (d *Decoder) loadAppends() error {
k := d.marker() k, err := d.marker()
if err != nil {
return err
}
l := d.stack[k-1] l := d.stack[k-1]
switch l.(type) { switch l.(type) {
case []interface{}: case []interface{}:
...@@ -632,14 +641,22 @@ func (d *Decoder) loadBool(b bool) error { ...@@ -632,14 +641,22 @@ func (d *Decoder) loadBool(b bool) error {
} }
func (d *Decoder) loadList() error { func (d *Decoder) loadList() error {
k := d.marker() k, err := d.marker()
if err != nil {
return err
}
v := append([]interface{}{}, d.stack[k+1:]...) v := append([]interface{}{}, d.stack[k+1:]...)
d.stack = append(d.stack[:k], v) d.stack = append(d.stack[:k], v)
return nil return nil
} }
func (d *Decoder) loadTuple() error { func (d *Decoder) loadTuple() error {
k := d.marker() k, err := d.marker()
if err != nil {
return err
}
v := append([]interface{}{}, d.stack[k+1:]...) v := append([]interface{}{}, d.stack[k+1:]...)
d.stack = append(d.stack[:k], v) d.stack = append(d.stack[:k], v)
return nil return nil
...@@ -715,7 +732,11 @@ func (d *Decoder) loadSetItem() error { ...@@ -715,7 +732,11 @@ func (d *Decoder) loadSetItem() error {
} }
func (d *Decoder) loadSetItems() error { func (d *Decoder) loadSetItems() error {
k := d.marker() k, err := d.marker()
if err != nil {
return err
}
l := d.stack[k-1] l := d.stack[k-1]
switch m := l.(type) { switch m := l.(type) {
case map[interface{}]interface{}: case map[interface{}]interface{}:
......
...@@ -18,7 +18,11 @@ func TestMarker(t *testing.T) { ...@@ -18,7 +18,11 @@ func TestMarker(t *testing.T) {
buf := bytes.Buffer{} buf := bytes.Buffer{}
dec := NewDecoder(&buf) dec := NewDecoder(&buf)
dec.mark() dec.mark()
if dec.marker() != 0 { k, err := dec.marker()
if err != nil {
t.Error(err)
}
if k != 0 {
t.Error("no marker found") t.Error("no marker found")
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment