Skip to content
This repository was archived by the owner on May 11, 2020. It is now read-only.

Commit 4c85b4e

Browse files
laizysbinet
authored andcommitted
disasm,wasm: fix types decoding
1 parent 46451e6 commit 4c85b4e

File tree

6 files changed

+64
-35
lines changed

6 files changed

+64
-35
lines changed

disasm/asm.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func Assemble(instr []Instr) ([]byte, error) {
2121
body.WriteByte(ins.Op.Code)
2222
switch op := ins.Op.Code; op {
2323
case ops.Block, ops.Loop, ops.If:
24-
leb128.WriteVarint64(body, int64(ins.Immediates[0].(wasm.BlockType)))
24+
body.WriteByte(byte(ins.Immediates[0].(wasm.BlockType)))
2525
case ops.Br, ops.BrIf:
2626
leb128.WriteVarUint32(body, ins.Immediates[0].(uint32))
2727
case ops.BrTable:

disasm/disasm.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ func NewDisassembly(fn wasm.Function, module *wasm.Module) (*Disassembly, error)
222222
}
223223

224224
case ops.Block, ops.Loop, ops.If:
225-
sig := uint32(instr.Immediates[0].(wasm.BlockType))
225+
sig := instr.Immediates[0].(wasm.BlockType)
226226
logger.Printf("if, depth is %d", stackDepths.Top())
227227
stackDepths.Push(stackDepths.Top())
228228
// If this new block is unreachable, its
@@ -237,7 +237,7 @@ func NewDisassembly(fn wasm.Function, module *wasm.Module) (*Disassembly, error)
237237
}
238238
instr.Block = &BlockInfo{
239239
Start: true,
240-
Signature: wasm.BlockType(sig),
240+
Signature: sig,
241241
}
242242

243243
blockIndices.Push(uint64(curIndex))
@@ -391,7 +391,7 @@ func Disassemble(code []byte) ([]Instr, error) {
391391

392392
switch op {
393393
case ops.Block, ops.Loop, ops.If:
394-
sig, err := leb128.ReadVarint32(reader)
394+
sig, err := wasm.ReadByte(reader)
395395
if err != nil {
396396
return nil, err
397397
}

validate/validate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func verifyBody(fn *wasm.FunctionSig, body *wasm.FunctionBody, module *wasm.Modu
6767

6868
switch op {
6969
case ops.If, ops.Block, ops.Loop:
70-
sig, err := vm.fetchVarInt()
70+
sig, err := vm.fetchByte()
7171
if err != nil {
7272
return vm, err
7373
}

validate/vm.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ func (vm *mockVM) fetchVarInt() (int32, error) {
4949
return leb128.ReadVarint32(vm.code)
5050
}
5151

52+
func (vm *mockVM) fetchByte() (byte, error) {
53+
return vm.code.ReadByte()
54+
}
55+
5256
func (vm *mockVM) fetchVarInt64() (int64, error) {
5357
return leb128.ReadVarint64(vm.code)
5458
}

wasm/read.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ func readBytes(r io.Reader, n int) ([]byte, error) {
3535
return nil, io.ErrUnexpectedEOF
3636
}
3737

38+
func writeByte(w io.Writer, b byte) error {
39+
_, err := w.Write([]byte{b})
40+
return err
41+
}
42+
43+
func ReadByte(r io.Reader) (byte, error) {
44+
p := make([]byte, 1)
45+
_, err := r.Read(p)
46+
return p[0], err
47+
}
48+
3849
func readBytesUint(r io.Reader) ([]byte, error) {
3950
n, err := leb128.ReadVarUint32(r)
4051
if err != nil {

wasm/types.go

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package wasm
66

77
import (
8+
"errors"
89
"fmt"
910
"io"
1011

@@ -22,13 +23,13 @@ type Unmarshaler interface {
2223
}
2324

2425
// ValueType represents the type of a valid value in Wasm
25-
type ValueType int8
26+
type ValueType uint8
2627

2728
const (
28-
ValueTypeI32 ValueType = -0x01
29-
ValueTypeI64 ValueType = -0x02
30-
ValueTypeF32 ValueType = -0x03
31-
ValueTypeF64 ValueType = -0x04
29+
ValueTypeI32 ValueType = 0x7f
30+
ValueTypeI64 ValueType = 0x7e
31+
ValueTypeF32 ValueType = 0x7d
32+
ValueTypeF64 ValueType = 0x7c
3233
)
3334

3435
var valueTypeStrMap = map[ValueType]string{
@@ -47,10 +48,10 @@ func (t ValueType) String() string {
4748
}
4849

4950
// TypeFunc represents the value type of a function
50-
const TypeFunc int = -0x20
51+
const TypeFunc uint8 = 0x60
5152

5253
func (t *ValueType) UnmarshalWASM(r io.Reader) error {
53-
v, err := leb128.ReadVarint32(r)
54+
v, err := ReadByte(r)
5455
if err != nil {
5556
return err
5657
}
@@ -59,13 +60,13 @@ func (t *ValueType) UnmarshalWASM(r io.Reader) error {
5960
}
6061

6162
func (t ValueType) MarshalWASM(w io.Writer) error {
62-
_, err := leb128.WriteVarint64(w, int64(t))
63+
err := writeByte(w, byte(t))
6364
return err
6465
}
6566

6667
// BlockType represents the signature of a structured block
6768
type BlockType ValueType // varint7
68-
const BlockTypeEmpty BlockType = -0x40
69+
const BlockTypeEmpty BlockType = 0x40
6970

7071
func (b BlockType) String() string {
7172
if b == BlockTypeEmpty {
@@ -75,22 +76,24 @@ func (b BlockType) String() string {
7576
}
7677

7778
// ElemType describes the type of a table's elements
78-
type ElemType int // varint7
79+
type ElemType uint8 // varint7
7980
// ElemTypeAnyFunc descibres an any_func value
80-
const ElemTypeAnyFunc ElemType = -0x10
81+
const ElemTypeAnyFunc ElemType = 0x70
8182

8283
func (t *ElemType) UnmarshalWASM(r io.Reader) error {
83-
b, err := leb128.ReadVarint32(r)
84+
b, err := ReadByte(r)
8485
if err != nil {
8586
return err
8687
}
88+
if b != uint8(ElemTypeAnyFunc) {
89+
return fmt.Errorf("wasm: unsupported elem type:%d", b)
90+
}
8791
*t = ElemType(b)
8892
return nil
8993
}
9094

9195
func (t ElemType) MarshalWASM(w io.Writer) error {
92-
_, err := leb128.WriteVarint64(w, int64(t))
93-
return err
96+
return writeByte(w, byte(t))
9497
}
9598

9699
func (t ElemType) String() string {
@@ -104,7 +107,7 @@ func (t ElemType) String() string {
104107
// FunctionSig describes the signature of a declared function in a WASM module
105108
type FunctionSig struct {
106109
// value for the 'func` type constructor
107-
Form int8
110+
Form uint8 // must be 0x60
108111
// The parameter types of the function
109112
ParamTypes []ValueType
110113
ReturnTypes []ValueType
@@ -124,11 +127,14 @@ func (e InvalidTypeConstructorError) Error() string {
124127
}
125128

126129
func (f *FunctionSig) UnmarshalWASM(r io.Reader) error {
127-
form, err := leb128.ReadVarint32(r)
130+
form, err := ReadByte(r)
128131
if err != nil {
129132
return err
130133
}
131-
f.Form = int8(form)
134+
if form != TypeFunc {
135+
return fmt.Errorf("wasm: unknown function form: %x", form)
136+
}
137+
f.Form = uint8(form)
132138

133139
paramCount, err := leb128.ReadVarUint32(r)
134140
if err != nil {
@@ -162,7 +168,7 @@ func (f *FunctionSig) UnmarshalWASM(r io.Reader) error {
162168
}
163169

164170
func (f *FunctionSig) MarshalWASM(w io.Writer) error {
165-
_, err := leb128.WriteVarint64(w, int64(f.Form))
171+
err := writeByte(w, f.Form)
166172
if err != nil {
167173
return err
168174
}
@@ -205,12 +211,16 @@ func (g *GlobalVar) UnmarshalWASM(r io.Reader) error {
205211
return err
206212
}
207213

208-
m, err := leb128.ReadVarUint32(r)
214+
m, err := ReadByte(r)
209215
if err != nil {
210216
return err
211217
}
212218

213-
g.Mutable = m == 1
219+
if m != 0x00 && m != 0x01 {
220+
return errors.New("wasm: invalid global mutable flag")
221+
}
222+
223+
g.Mutable = m == 0x01
214224

215225
return nil
216226
}
@@ -219,14 +229,11 @@ func (g *GlobalVar) MarshalWASM(w io.Writer) error {
219229
if err := g.Type.MarshalWASM(w); err != nil {
220230
return err
221231
}
222-
var m uint32
232+
var m uint8
223233
if g.Mutable {
224234
m = 1
225235
}
226-
if _, err := leb128.WriteVarUint32(w, m); err != nil {
227-
return err
228-
}
229-
return nil
236+
return writeByte(w, m)
230237
}
231238

232239
// Table describes a table in a Wasm module.
@@ -310,17 +317,20 @@ func (e External) MarshalWASM(w io.Writer) error {
310317

311318
// ResizableLimits describe the limit of a table or linear memory.
312319
type ResizableLimits struct {
313-
Flags uint32 // 1 if the Maximum field is valid
320+
Flags uint8 // 1 if the Maximum field is valid, 0 otherwise
314321
Initial uint32 // initial length (in units of table elements or wasm pages)
315322
Maximum uint32 // If flags is 1, it describes the maximum size of the table or memory
316323
}
317324

318325
func (lim *ResizableLimits) UnmarshalWASM(r io.Reader) error {
319326
*lim = ResizableLimits{}
320-
f, err := leb128.ReadVarUint32(r)
327+
f, err := ReadByte(r)
321328
if err != nil {
322329
return err
323330
}
331+
if f != 0 && f != 1 {
332+
return errors.New("wasm: invalid limit flag")
333+
}
324334
lim.Flags = f
325335

326336
lim.Initial, err = leb128.ReadVarUint32(r)
@@ -339,14 +349,18 @@ func (lim *ResizableLimits) UnmarshalWASM(r io.Reader) error {
339349
}
340350

341351
func (lim *ResizableLimits) MarshalWASM(w io.Writer) error {
342-
if _, err := leb128.WriteVarUint32(w, uint32(lim.Flags)); err != nil {
352+
f := lim.Flags
353+
if f != 0 && f != 1 {
354+
return errors.New("wasm: invalid limit flag")
355+
}
356+
if _, err := w.Write([]byte{f}); err != nil {
343357
return err
344358
}
345-
if _, err := leb128.WriteVarUint32(w, uint32(lim.Initial)); err != nil {
359+
if _, err := leb128.WriteVarUint32(w, lim.Initial); err != nil {
346360
return err
347361
}
348362
if lim.Flags&0x1 != 0 {
349-
if _, err := leb128.WriteVarUint32(w, uint32(lim.Maximum)); err != nil {
363+
if _, err := leb128.WriteVarUint32(w, lim.Maximum); err != nil {
350364
return err
351365
}
352366
}

0 commit comments

Comments
 (0)