Commit 9f73742b authored by Kirill Smelkov's avatar Kirill Smelkov

decoder: Really stop decoding on opStop opcode

There was a break already on a `case opStop:` but break inside switch
only breaks out of this switch, not outer construct - looks like it was
a thinko.

So on opStop let's explicitly break out of instruction processing loop.

If we do not do so on e.g "I5\n.I7\n.N." input first call to .Decode()
returns None (from N.), not 5 and second call to Decode() panics (for
this see next patch).
parent 22c43a4f
......@@ -119,6 +119,7 @@ func NewDecoder(r io.Reader) Decoder {
func (d Decoder) Decode() (interface{}, error) {
insn := 0
loop:
for {
insn++
key, err := d.r.ReadByte()
......@@ -132,7 +133,7 @@ func (d Decoder) Decode() (interface{}, error) {
case opMark:
d.mark()
case opStop:
break
break loop
case opPop:
d.pop()
case opPopMark:
......
......@@ -78,6 +78,28 @@ func TestDecode(t *testing.T) {
}
}
// test that .Decode() decodes only until stop opcode, and can continue
// decoding further on next call
func TestDecodeMultiple(t *testing.T) {
input := "I5\n.I7\n.N."
expected := []interface{}{int64(5), int64(7), None{}}
buf := bytes.NewBufferString(input)
dec := NewDecoder(buf)
for i, objOk := range expected {
obj, err := dec.Decode()
if err != nil {
t.Errorf("step #%v: %v", i, err)
}
if !reflect.DeepEqual(obj, objOk) {
t.Errorf("step #%v: %q ; want %q", i, obj, objOk)
}
}
}
func TestZeroLengthData(t *testing.T) {
data := ""
output, err := decodeLong(data)
......
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