1 package binary
2
3 import (
4 "bytes"
5 "testing"
6
7 "github.com/tetratelabs/wazero/api"
8 "github.com/tetratelabs/wazero/internal/testing/binaryencoding"
9 "github.com/tetratelabs/wazero/internal/testing/require"
10 "github.com/tetratelabs/wazero/internal/wasm"
11 )
12
13 func TestTableSection(t *testing.T) {
14 three := uint32(3)
15 tests := []struct {
16 name string
17 input []byte
18 expected []wasm.Table
19 }{
20 {
21 name: "min and min with max",
22 input: []byte{
23 0x01,
24 wasm.RefTypeFuncref, 0x01, 2, 3,
25 },
26 expected: []wasm.Table{{Min: 2, Max: &three, Type: wasm.RefTypeFuncref}},
27 },
28 {
29 name: "min and min with max - three tables",
30 input: []byte{
31 0x03,
32 wasm.RefTypeFuncref, 0x01, 2, 3,
33 wasm.RefTypeExternref, 0x01, 2, 3,
34 wasm.RefTypeFuncref, 0x01, 2, 3,
35 },
36 expected: []wasm.Table{
37 {Min: 2, Max: &three, Type: wasm.RefTypeFuncref},
38 {Min: 2, Max: &three, Type: wasm.RefTypeExternref},
39 {Min: 2, Max: &three, Type: wasm.RefTypeFuncref},
40 },
41 },
42 }
43
44 for _, tt := range tests {
45 tc := tt
46
47 t.Run(tc.name, func(t *testing.T) {
48 tables, err := decodeTableSection(bytes.NewReader(tc.input), api.CoreFeatureReferenceTypes)
49 require.NoError(t, err)
50 require.Equal(t, tc.expected, tables)
51 })
52 }
53 }
54
55 func TestTableSection_Errors(t *testing.T) {
56 tests := []struct {
57 name string
58 input []byte
59 expectedErr string
60 features api.CoreFeatures
61 }{
62 {
63 name: "min and min with max",
64 input: []byte{
65 0x02,
66 wasm.RefTypeFuncref, 0x00, 0x01,
67 wasm.RefTypeFuncref, 0x01, 0x02, 0x03,
68 },
69 expectedErr: "at most one table allowed in module as feature \"reference-types\" is disabled",
70 features: api.CoreFeaturesV1,
71 },
72 }
73
74 for _, tt := range tests {
75 tc := tt
76
77 t.Run(tc.name, func(t *testing.T) {
78 _, err := decodeTableSection(bytes.NewReader(tc.input), tc.features)
79 require.EqualError(t, err, tc.expectedErr)
80 })
81 }
82 }
83
84 func TestMemorySection(t *testing.T) {
85 max := wasm.MemoryLimitPages
86
87 three := uint32(3)
88 tests := []struct {
89 name string
90 input []byte
91 expected *wasm.Memory
92 }{
93 {
94 name: "min and min with max",
95 input: []byte{
96 0x01,
97 0x01, 0x02, 0x03,
98 },
99 expected: &wasm.Memory{Min: 2, Cap: 2, Max: three, IsMaxEncoded: true},
100 },
101 }
102
103 for _, tt := range tests {
104 tc := tt
105
106 t.Run(tc.name, func(t *testing.T) {
107 memories, err := decodeMemorySection(bytes.NewReader(tc.input), newMemorySizer(max, false), max)
108 require.NoError(t, err)
109 require.Equal(t, tc.expected, memories)
110 })
111 }
112 }
113
114 func TestMemorySection_Errors(t *testing.T) {
115 max := wasm.MemoryLimitPages
116
117 tests := []struct {
118 name string
119 input []byte
120 expectedErr string
121 }{
122 {
123 name: "min and min with max",
124 input: []byte{
125 0x02,
126 0x01,
127 0x02, 0x03,
128 },
129 expectedErr: "at most one memory allowed in module, but read 2",
130 },
131 }
132
133 for _, tt := range tests {
134 tc := tt
135
136 t.Run(tc.name, func(t *testing.T) {
137 _, err := decodeMemorySection(bytes.NewReader(tc.input), newMemorySizer(max, false), max)
138 require.EqualError(t, err, tc.expectedErr)
139 })
140 }
141 }
142
143 func TestDecodeExportSection(t *testing.T) {
144 tests := []struct {
145 name string
146 input []byte
147 expected []wasm.Export
148 }{
149 {
150 name: "empty and non-empty name",
151 input: []byte{
152 0x02,
153 0x00,
154 wasm.ExternTypeFunc, 0x02,
155 0x01, 'a',
156 wasm.ExternTypeFunc, 0x01,
157 },
158 expected: []wasm.Export{
159 {Name: "", Type: wasm.ExternTypeFunc, Index: wasm.Index(2)},
160 {Name: "a", Type: wasm.ExternTypeFunc, Index: wasm.Index(1)},
161 },
162 },
163 }
164
165 for _, tt := range tests {
166 tc := tt
167
168 t.Run(tc.name, func(t *testing.T) {
169 actual, actualExpMap, err := decodeExportSection(bytes.NewReader(tc.input))
170 require.NoError(t, err)
171 require.Equal(t, tc.expected, actual)
172
173 expMap := make(map[string]*wasm.Export, len(tc.expected))
174 for i := range tc.expected {
175 exp := &tc.expected[i]
176 expMap[exp.Name] = exp
177 }
178 require.Equal(t, expMap, actualExpMap)
179 })
180 }
181 }
182
183 func TestDecodeExportSection_Errors(t *testing.T) {
184 tests := []struct {
185 name string
186 input []byte
187 expectedErr string
188 }{
189 {
190 name: "duplicates empty name",
191 input: []byte{
192 0x02,
193 0x00,
194 wasm.ExternTypeFunc, 0x00,
195 0x00,
196 wasm.ExternTypeFunc, 0x00,
197 },
198 expectedErr: "export[1] duplicates name \"\"",
199 },
200 {
201 name: "duplicates name",
202 input: []byte{
203 0x02,
204 0x01, 'a',
205 wasm.ExternTypeFunc, 0x00,
206 0x01, 'a',
207 wasm.ExternTypeFunc, 0x00,
208 },
209 expectedErr: "export[1] duplicates name \"a\"",
210 },
211 }
212
213 for _, tt := range tests {
214 tc := tt
215
216 t.Run(tc.name, func(t *testing.T) {
217 _, _, err := decodeExportSection(bytes.NewReader(tc.input))
218 require.EqualError(t, err, tc.expectedErr)
219 })
220 }
221 }
222
223 func TestEncodeFunctionSection(t *testing.T) {
224 require.Equal(t, []byte{wasm.SectionIDFunction, 0x2, 0x01, 0x05}, binaryencoding.EncodeFunctionSection([]wasm.Index{5}))
225 }
226
227
228 func TestEncodeStartSection(t *testing.T) {
229 require.Equal(t, []byte{wasm.SectionIDStart, 0x01, 0x05}, binaryencoding.EncodeStartSection(5))
230 }
231
232 func TestDecodeDataCountSection(t *testing.T) {
233 t.Run("ok", func(t *testing.T) {
234 v, err := decodeDataCountSection(bytes.NewReader([]byte{0x1}))
235 require.NoError(t, err)
236 require.Equal(t, uint32(1), *v)
237 })
238 t.Run("eof", func(t *testing.T) {
239
240 _, err := decodeDataCountSection(bytes.NewReader([]byte{}))
241 require.NoError(t, err)
242 })
243 }
244
View as plain text