blob: 44e78653e3922dbd3fc4d9629330839ce315ca0f [file] [log] [blame]
Ben Murdoch014dc512016-03-22 12:00:34 +00001// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "test/unittests/test-utils.h"
6
7#include "src/wasm/module-decoder.h"
Ben Murdoch3b9bc312016-06-02 14:46:10 +01008#include "src/wasm/wasm-macro-gen.h"
Ben Murdoch014dc512016-03-22 12:00:34 +00009#include "src/wasm/wasm-opcodes.h"
10
11namespace v8 {
12namespace internal {
13namespace wasm {
14
Ben Murdoch3b9bc312016-06-02 14:46:10 +010015#define EMPTY_FUNCTION(sig_index) 0, SIG_INDEX(sig_index), U16_LE(0)
16#define EMPTY_FUNCTION_SIZE ((size_t)5)
17#define EMPTY_BODY 0
18#define EMPTY_BODY_SIZE ((size_t)1)
19#define NOP_BODY 2, 0, kExprNop
20#define NOP_BODY_SIZE ((size_t)3)
21#define VOID_VOID_SIG 0, kLocalVoid
22#define VOID_VOID_SIG_SIZE ((size_t)2)
23#define INT_INT_SIG 1, kLocalI32, kLocalI32
24#define INT_INT_SIG_SIZE ((size_t)3)
Ben Murdoch014dc512016-03-22 12:00:34 +000025
Ben Murdoch3b9bc312016-06-02 14:46:10 +010026#define SECTION(NAME, EXTRA_SIZE) \
27 U32V_1(WASM_SECTION_##NAME##_SIZE + (EXTRA_SIZE)), WASM_SECTION_##NAME
Ben Murdoch014dc512016-03-22 12:00:34 +000028
29#define EXPECT_VERIFIES(data) \
30 do { \
31 ModuleResult result = DecodeModule(data, data + arraysize(data)); \
32 EXPECT_TRUE(result.ok()); \
33 if (result.val) delete result.val; \
34 } while (false)
35
Ben Murdoch3b9bc312016-06-02 14:46:10 +010036#define EXPECT_FAILURE_LEN(data, length) \
37 do { \
38 ModuleResult result = DecodeModule(data, data + length); \
39 EXPECT_FALSE(result.ok()); \
40 if (result.val) delete result.val; \
Ben Murdoch014dc512016-03-22 12:00:34 +000041 } while (false)
42
Ben Murdoch3b9bc312016-06-02 14:46:10 +010043#define EXPECT_FAILURE(data) EXPECT_FAILURE_LEN(data, sizeof(data))
44
45#define EXPECT_OFF_END_FAILURE(data, min, max) \
46 do { \
47 for (size_t length = min; length < max; length++) { \
48 EXPECT_FAILURE_LEN(data, length); \
49 } \
50 } while (false)
51
52static size_t SizeOfVarInt(size_t value) {
53 size_t size = 0;
54 do {
55 size++;
56 value = value >> 7;
57 } while (value > 0);
58 return size;
59}
Ben Murdoch014dc512016-03-22 12:00:34 +000060
61struct LocalTypePair {
62 uint8_t code;
63 LocalType type;
64} kLocalTypes[] = {{kLocalI32, kAstI32},
65 {kLocalI64, kAstI64},
66 {kLocalF32, kAstF32},
67 {kLocalF64, kAstF64}};
68
Ben Murdoch3b9bc312016-06-02 14:46:10 +010069class WasmModuleVerifyTest : public TestWithZone {
70 public:
71 ModuleResult DecodeModule(const byte* module_start, const byte* module_end) {
72 // Add the WASM magic and version number automatically.
73 size_t size = static_cast<size_t>(module_end - module_start);
74 byte header[] = {WASM_MODULE_HEADER};
75 size_t total = sizeof(header) + size;
76 auto temp = new byte[total];
77 memcpy(temp, header, sizeof(header));
78 memcpy(temp + sizeof(header), module_start, size);
79 ModuleResult result = DecodeWasmModule(nullptr, zone(), temp, temp + total,
80 false, kWasmOrigin);
81 delete[] temp;
82 return result;
Ben Murdoch014dc512016-03-22 12:00:34 +000083 }
Ben Murdoch3b9bc312016-06-02 14:46:10 +010084 ModuleResult DecodeModuleNoHeader(const byte* module_start,
85 const byte* module_end) {
86 return DecodeWasmModule(nullptr, zone(), module_start, module_end, false,
87 kWasmOrigin);
88 }
89};
90
91TEST_F(WasmModuleVerifyTest, WrongMagic) {
92 for (uint32_t x = 1; x; x <<= 1) {
93 const byte data[] = {U32_LE(kWasmMagic ^ x), U32_LE(kWasmVersion),
94 SECTION(END, 0)};
95 ModuleResult result = DecodeModuleNoHeader(data, data + sizeof(data));
96 EXPECT_FALSE(result.ok());
Ben Murdoch014dc512016-03-22 12:00:34 +000097 if (result.val) delete result.val;
98 }
99}
100
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100101TEST_F(WasmModuleVerifyTest, WrongVersion) {
102 for (uint32_t x = 1; x; x <<= 1) {
103 const byte data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion ^ x),
104 SECTION(END, 0)};
105 ModuleResult result = DecodeModuleNoHeader(data, data + sizeof(data));
106 EXPECT_FALSE(result.ok());
107 if (result.val) delete result.val;
108 }
109}
110
111TEST_F(WasmModuleVerifyTest, DecodeEmpty) {
112 static const byte data[] = {SECTION(END, 0)};
113 EXPECT_VERIFIES(data);
114}
Ben Murdoch014dc512016-03-22 12:00:34 +0000115
116TEST_F(WasmModuleVerifyTest, OneGlobal) {
Ben Murdoch109988c2016-05-18 11:27:45 +0100117 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100118 SECTION(GLOBALS, 7), // --
Ben Murdoch014dc512016-03-22 12:00:34 +0000119 1,
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100120 NAME_LENGTH(1),
121 'g', // name
Ben Murdoch014dc512016-03-22 12:00:34 +0000122 kMemI32, // memory type
123 0, // exported
124 };
125
126 {
127 // Should decode to exactly one global.
128 ModuleResult result = DecodeModule(data, data + arraysize(data));
129 EXPECT_TRUE(result.ok());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100130 EXPECT_EQ(1, result.val->globals.size());
131 EXPECT_EQ(0, result.val->functions.size());
132 EXPECT_EQ(0, result.val->data_segments.size());
Ben Murdoch014dc512016-03-22 12:00:34 +0000133
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100134 WasmGlobal* global = &result.val->globals.back();
Ben Murdoch014dc512016-03-22 12:00:34 +0000135
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100136 EXPECT_EQ(1, global->name_length);
Ben Murdoch014dc512016-03-22 12:00:34 +0000137 EXPECT_EQ(MachineType::Int32(), global->type);
138 EXPECT_EQ(0, global->offset);
139 EXPECT_FALSE(global->exported);
140
141 if (result.val) delete result.val;
142 }
143
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100144 EXPECT_OFF_END_FAILURE(data, 1, sizeof(data));
Ben Murdoch014dc512016-03-22 12:00:34 +0000145}
146
147
148TEST_F(WasmModuleVerifyTest, ZeroGlobals) {
Ben Murdoch109988c2016-05-18 11:27:45 +0100149 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100150 SECTION(GLOBALS, 1), // --
151 0, // declare 0 globals
Ben Murdoch014dc512016-03-22 12:00:34 +0000152 };
153 ModuleResult result = DecodeModule(data, data + arraysize(data));
154 EXPECT_TRUE(result.ok());
155 if (result.val) delete result.val;
156}
157
158
159static void AppendUint32v(std::vector<byte>& buffer, uint32_t val) {
160 while (true) {
161 uint32_t next = val >> 7;
162 uint32_t out = val & 0x7f;
163 if (next) {
164 buffer.push_back(static_cast<byte>(0x80 | out));
165 val = next;
166 } else {
167 buffer.push_back(static_cast<byte>(out));
168 break;
169 }
170 }
171}
172
173
174TEST_F(WasmModuleVerifyTest, NGlobals) {
Ben Murdoch109988c2016-05-18 11:27:45 +0100175 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100176 NO_NAME, // name length
177 kMemI32, // memory type
178 0, // exported
Ben Murdoch014dc512016-03-22 12:00:34 +0000179 };
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100180
181 for (uint32_t i = 0; i < 1000000; i = i * 13 + 1) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000182 std::vector<byte> buffer;
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100183 size_t size =
184 WASM_SECTION_GLOBALS_SIZE + SizeOfVarInt(i) + i * sizeof(data);
185 const byte globals[] = {U32V_5(size), WASM_SECTION_GLOBALS};
186 for (size_t g = 0; g != sizeof(globals); ++g) {
187 buffer.push_back(globals[g]);
188 }
189 AppendUint32v(buffer, i); // Number of globals.
Ben Murdoch014dc512016-03-22 12:00:34 +0000190 for (uint32_t j = 0; j < i; j++) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100191 buffer.insert(buffer.end(), data, data + sizeof(data));
Ben Murdoch014dc512016-03-22 12:00:34 +0000192 }
193
194 ModuleResult result = DecodeModule(&buffer[0], &buffer[0] + buffer.size());
195 EXPECT_TRUE(result.ok());
196 if (result.val) delete result.val;
197 }
198}
199
Ben Murdoch014dc512016-03-22 12:00:34 +0000200TEST_F(WasmModuleVerifyTest, GlobalWithInvalidNameOffset) {
Ben Murdoch109988c2016-05-18 11:27:45 +0100201 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100202 SECTION(GLOBALS, 7),
203 1, // declare one global
204 NO_NAME, // name offset
205 33, // memory type
Ben Murdoch014dc512016-03-22 12:00:34 +0000206 0, // exported
207 };
208
209 EXPECT_FAILURE(data);
210}
211
Ben Murdoch014dc512016-03-22 12:00:34 +0000212TEST_F(WasmModuleVerifyTest, GlobalWithInvalidMemoryType) {
Ben Murdoch109988c2016-05-18 11:27:45 +0100213 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100214 SECTION(GLOBALS, 7),
215 1, // declare one global
216 NO_NAME, // name offset
217 33, // memory type
218 0, // exported
Ben Murdoch014dc512016-03-22 12:00:34 +0000219 };
220
221 EXPECT_FAILURE(data);
222}
223
224
225TEST_F(WasmModuleVerifyTest, TwoGlobals) {
Ben Murdoch109988c2016-05-18 11:27:45 +0100226 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100227 SECTION(GLOBALS, 13),
Ben Murdoch014dc512016-03-22 12:00:34 +0000228 2,
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100229 NO_NAME, // #0: name length
Ben Murdoch014dc512016-03-22 12:00:34 +0000230 kMemF32, // memory type
231 0, // exported
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100232 NO_NAME, // #1: name length
Ben Murdoch014dc512016-03-22 12:00:34 +0000233 kMemF64, // memory type
234 1, // exported
235 };
236
237 {
238 // Should decode to exactly two globals.
239 ModuleResult result = DecodeModule(data, data + arraysize(data));
240 EXPECT_TRUE(result.ok());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100241 EXPECT_EQ(2, result.val->globals.size());
242 EXPECT_EQ(0, result.val->functions.size());
243 EXPECT_EQ(0, result.val->data_segments.size());
Ben Murdoch014dc512016-03-22 12:00:34 +0000244
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100245 WasmGlobal* g0 = &result.val->globals[0];
246 WasmGlobal* g1 = &result.val->globals[1];
Ben Murdoch014dc512016-03-22 12:00:34 +0000247
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100248 EXPECT_EQ(0, g0->name_length);
Ben Murdoch014dc512016-03-22 12:00:34 +0000249 EXPECT_EQ(MachineType::Float32(), g0->type);
250 EXPECT_EQ(0, g0->offset);
251 EXPECT_FALSE(g0->exported);
252
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100253 EXPECT_EQ(0, g1->name_length);
Ben Murdoch014dc512016-03-22 12:00:34 +0000254 EXPECT_EQ(MachineType::Float64(), g1->type);
255 EXPECT_EQ(0, g1->offset);
256 EXPECT_TRUE(g1->exported);
257
258 if (result.val) delete result.val;
259 }
260
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100261 EXPECT_OFF_END_FAILURE(data, 1, sizeof(data));
Ben Murdoch014dc512016-03-22 12:00:34 +0000262}
263
264
265TEST_F(WasmModuleVerifyTest, OneSignature) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100266 {
267 static const byte data[] = {SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE), 1,
268 VOID_VOID_SIG};
269 EXPECT_VERIFIES(data);
270 }
271
272 {
273 static const byte data[] = {SECTION(SIGNATURES, 1 + INT_INT_SIG_SIZE), 1,
274 INT_INT_SIG};
275 EXPECT_VERIFIES(data);
276 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000277}
278
279
280TEST_F(WasmModuleVerifyTest, MultipleSignatures) {
281 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100282 SECTION(SIGNATURES, 10),
Ben Murdoch014dc512016-03-22 12:00:34 +0000283 3,
284 0,
285 kLocalVoid, // void -> void
286 1,
287 kLocalI32,
288 kLocalF32, // f32 -> i32
289 2,
290 kLocalI32,
291 kLocalF64,
292 kLocalF64, // (f64,f64) -> i32
293 };
294
295 ModuleResult result = DecodeModule(data, data + arraysize(data));
296 EXPECT_TRUE(result.ok());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100297 EXPECT_EQ(3, result.val->signatures.size());
298 if (result.val->signatures.size() == 3) {
299 EXPECT_EQ(0, result.val->signatures[0]->return_count());
300 EXPECT_EQ(1, result.val->signatures[1]->return_count());
301 EXPECT_EQ(1, result.val->signatures[2]->return_count());
Ben Murdoch014dc512016-03-22 12:00:34 +0000302
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100303 EXPECT_EQ(0, result.val->signatures[0]->parameter_count());
304 EXPECT_EQ(1, result.val->signatures[1]->parameter_count());
305 EXPECT_EQ(2, result.val->signatures[2]->parameter_count());
Ben Murdoch014dc512016-03-22 12:00:34 +0000306 }
307 if (result.val) delete result.val;
308
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100309 EXPECT_OFF_END_FAILURE(data, 1, sizeof(data));
Ben Murdoch014dc512016-03-22 12:00:34 +0000310}
311
312
313TEST_F(WasmModuleVerifyTest, FunctionWithoutSig) {
314 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100315 SECTION(FUNCTIONS, 25), 1,
Ben Murdoch014dc512016-03-22 12:00:34 +0000316 // func#0 ------------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100317 SIG_INDEX(0), // signature index
318 NO_NAME, // name length
319 U32_LE(0), // code start offset
320 U32_LE(0), // code end offset
321 U16_LE(899), // local int32 count
322 U16_LE(799), // local int64 count
323 U16_LE(699), // local float32 count
324 U16_LE(599), // local float64 count
325 0, // exported
326 1 // external
Ben Murdoch014dc512016-03-22 12:00:34 +0000327 };
328
329 ModuleResult result = DecodeModule(data, data + arraysize(data));
330 EXPECT_FALSE(result.ok());
331 if (result.val) delete result.val;
332}
333
334
335TEST_F(WasmModuleVerifyTest, OneEmptyVoidVoidFunction) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100336 const int kCodeStartOffset = 51;
Ben Murdoch014dc512016-03-22 12:00:34 +0000337 const int kCodeEndOffset = kCodeStartOffset + 1;
338
339 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100340 SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE), 1,
Ben Murdoch014dc512016-03-22 12:00:34 +0000341 // sig#0 -------------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100342 VOID_VOID_SIG,
Ben Murdoch014dc512016-03-22 12:00:34 +0000343 // func#0 ------------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100344 SECTION(FUNCTIONS, 19), 1,
345 kDeclFunctionLocals | kDeclFunctionExport | kDeclFunctionName,
346 SIG_INDEX(0), // signature index
347 NAME_LENGTH(2), 'h', 'i', // name
348 U16_LE(1466), // local int32 count
349 U16_LE(1355), // local int64 count
350 U16_LE(1244), // local float32 count
351 U16_LE(1133), // local float64 count
352 1, 0, // size
Ben Murdoch014dc512016-03-22 12:00:34 +0000353 kExprNop,
354 };
355
356 {
357 // Should decode to exactly one function.
358 ModuleResult result = DecodeModule(data, data + arraysize(data));
359 EXPECT_TRUE(result.ok());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100360 EXPECT_EQ(0, result.val->globals.size());
361 EXPECT_EQ(1, result.val->signatures.size());
362 EXPECT_EQ(1, result.val->functions.size());
363 EXPECT_EQ(0, result.val->data_segments.size());
364 EXPECT_EQ(0, result.val->function_table.size());
Ben Murdoch014dc512016-03-22 12:00:34 +0000365
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100366 WasmFunction* function = &result.val->functions.back();
Ben Murdoch014dc512016-03-22 12:00:34 +0000367
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100368 EXPECT_EQ(39, function->name_offset);
369 EXPECT_EQ(2, function->name_length);
Ben Murdoch014dc512016-03-22 12:00:34 +0000370 EXPECT_EQ(kCodeStartOffset, function->code_start_offset);
371 EXPECT_EQ(kCodeEndOffset, function->code_end_offset);
372
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100373 EXPECT_EQ(1466, function->local_i32_count);
374 EXPECT_EQ(1355, function->local_i64_count);
375 EXPECT_EQ(1244, function->local_f32_count);
376 EXPECT_EQ(1133, function->local_f64_count);
Ben Murdoch014dc512016-03-22 12:00:34 +0000377
378 EXPECT_TRUE(function->exported);
379 EXPECT_FALSE(function->external);
380
381 if (result.val) delete result.val;
382 }
383
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100384 EXPECT_OFF_END_FAILURE(data, 16, sizeof(data));
Ben Murdoch014dc512016-03-22 12:00:34 +0000385}
386
387
388TEST_F(WasmModuleVerifyTest, OneFunctionImported) {
389 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100390 SECTION(SIGNATURES, VOID_VOID_SIG_SIZE), 1,
Ben Murdoch014dc512016-03-22 12:00:34 +0000391 // sig#0 -------------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100392 VOID_VOID_SIG, SECTION(FUNCTIONS, 6), 1,
Ben Murdoch014dc512016-03-22 12:00:34 +0000393 // func#0 ------------------------------------------------------
394 kDeclFunctionImport, // no name, no locals, imported
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100395 SIG_INDEX(0),
Ben Murdoch014dc512016-03-22 12:00:34 +0000396 };
397
398 ModuleResult result = DecodeModule(data, data + arraysize(data));
399 EXPECT_TRUE(result.ok());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100400 EXPECT_EQ(1, result.val->functions.size());
401 WasmFunction* function = &result.val->functions.back();
Ben Murdoch014dc512016-03-22 12:00:34 +0000402
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100403 EXPECT_EQ(0, function->name_length);
Ben Murdoch014dc512016-03-22 12:00:34 +0000404 EXPECT_EQ(0, function->code_start_offset);
405 EXPECT_EQ(0, function->code_end_offset);
406
Ben Murdoch109988c2016-05-18 11:27:45 +0100407 EXPECT_EQ(0, function->local_i32_count);
408 EXPECT_EQ(0, function->local_i64_count);
409 EXPECT_EQ(0, function->local_f32_count);
410 EXPECT_EQ(0, function->local_f64_count);
Ben Murdoch014dc512016-03-22 12:00:34 +0000411
412 EXPECT_FALSE(function->exported);
413 EXPECT_TRUE(function->external);
414
415 if (result.val) delete result.val;
416}
417
Ben Murdoch014dc512016-03-22 12:00:34 +0000418TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100419 static const byte kCodeStartOffset = 40;
Ben Murdoch014dc512016-03-22 12:00:34 +0000420 static const byte kCodeEndOffset = kCodeStartOffset + 1;
421
422 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100423 SECTION(SIGNATURES, 3), 1,
Ben Murdoch014dc512016-03-22 12:00:34 +0000424 // sig#0 -------------------------------------------------------
425 0, 0, // void -> void
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100426 SECTION(FUNCTIONS, 7), 1,
Ben Murdoch014dc512016-03-22 12:00:34 +0000427 // func#0 ------------------------------------------------------
428 0, // no name, no locals
429 0, 0, // signature index
430 1, 0, // body size
431 kExprNop // body
432 };
433
434 ModuleResult result = DecodeModule(data, data + arraysize(data));
435 EXPECT_TRUE(result.ok());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100436 EXPECT_EQ(1, result.val->functions.size());
437 WasmFunction* function = &result.val->functions.back();
Ben Murdoch014dc512016-03-22 12:00:34 +0000438
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100439 EXPECT_EQ(0, function->name_length);
Ben Murdoch014dc512016-03-22 12:00:34 +0000440 EXPECT_EQ(kCodeStartOffset, function->code_start_offset);
441 EXPECT_EQ(kCodeEndOffset, function->code_end_offset);
442
Ben Murdoch109988c2016-05-18 11:27:45 +0100443 EXPECT_EQ(0, function->local_i32_count);
444 EXPECT_EQ(0, function->local_i64_count);
445 EXPECT_EQ(0, function->local_f32_count);
446 EXPECT_EQ(0, function->local_f64_count);
Ben Murdoch014dc512016-03-22 12:00:34 +0000447
448 EXPECT_FALSE(function->exported);
449 EXPECT_FALSE(function->external);
450
451 if (result.val) delete result.val;
452}
453
454
455TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody_WithLocals) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100456 static const byte kCodeStartOffset = 48;
Ben Murdoch014dc512016-03-22 12:00:34 +0000457 static const byte kCodeEndOffset = kCodeStartOffset + 1;
458
459 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100460 SECTION(SIGNATURES, 3), 1,
Ben Murdoch014dc512016-03-22 12:00:34 +0000461 // sig#0 -------------------------------------------------------
462 0, 0, // void -> void
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100463 SECTION(FUNCTIONS, 15), 1,
Ben Murdoch014dc512016-03-22 12:00:34 +0000464 // func#0 ------------------------------------------------------
465 kDeclFunctionLocals, 0, 0, // signature index
466 1, 2, // local int32 count
467 3, 4, // local int64 count
468 5, 6, // local float32 count
469 7, 8, // local float64 count
470 1, 0, // body size
471 kExprNop // body
472 };
473
474 ModuleResult result = DecodeModule(data, data + arraysize(data));
475 EXPECT_TRUE(result.ok());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100476 EXPECT_EQ(1, result.val->functions.size());
477 WasmFunction* function = &result.val->functions.back();
Ben Murdoch014dc512016-03-22 12:00:34 +0000478
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100479 EXPECT_EQ(0, function->name_length);
Ben Murdoch014dc512016-03-22 12:00:34 +0000480 EXPECT_EQ(kCodeStartOffset, function->code_start_offset);
481 EXPECT_EQ(kCodeEndOffset, function->code_end_offset);
482
Ben Murdoch109988c2016-05-18 11:27:45 +0100483 EXPECT_EQ(513, function->local_i32_count);
484 EXPECT_EQ(1027, function->local_i64_count);
485 EXPECT_EQ(1541, function->local_f32_count);
486 EXPECT_EQ(2055, function->local_f64_count);
Ben Murdoch014dc512016-03-22 12:00:34 +0000487
488 EXPECT_FALSE(function->exported);
489 EXPECT_FALSE(function->external);
490
491 if (result.val) delete result.val;
492}
493
494
495TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100496 static const byte kCodeStartOffset = 75;
Ben Murdoch014dc512016-03-22 12:00:34 +0000497 static const byte kCodeEndOffset = kCodeStartOffset + 3;
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100498 static const byte kDataSegmentSourceOffset = kCodeEndOffset + 20;
Ben Murdoch014dc512016-03-22 12:00:34 +0000499
500 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100501 SECTION(MEMORY, 3), 28, 28, 1,
Ben Murdoch014dc512016-03-22 12:00:34 +0000502 // global#0 --------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100503 SECTION(GLOBALS, 7), 1,
504 0, // name length
505 kMemU8, // memory type
506 0, // exported
Ben Murdoch014dc512016-03-22 12:00:34 +0000507 // sig#0 -----------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100508 SECTION(SIGNATURES, 3), 1, 0, 0, // void -> void
Ben Murdoch014dc512016-03-22 12:00:34 +0000509 // func#0 ----------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100510 SECTION(FUNCTIONS, 20), 1, kDeclFunctionLocals | kDeclFunctionName, 0,
511 0, // signature index
512 2, 'h', 'i', // name
513 1, 2, // local int32 count
514 3, 4, // local int64 count
515 5, 6, // local float32 count
516 7, 8, // local float64 count
517 3, 0, // body size
518 kExprNop, // func#0 body
519 kExprNop, // func#0 body
520 kExprNop, // func#0 body
Ben Murdoch014dc512016-03-22 12:00:34 +0000521 // segment#0 -------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100522 SECTION(DATA_SEGMENTS, 14), 1,
523 U32V_3(0x8b3ae), // dest addr
524 U32V_1(5), // source size
525 0, 1, 2, 3, 4, // data bytes
Ben Murdoch014dc512016-03-22 12:00:34 +0000526 // rest ------------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100527 SECTION(END, 0),
Ben Murdoch014dc512016-03-22 12:00:34 +0000528 };
529
530 {
531 ModuleResult result = DecodeModule(data, data + arraysize(data));
532 EXPECT_TRUE(result.ok());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100533 EXPECT_EQ(1, result.val->globals.size());
534 EXPECT_EQ(1, result.val->functions.size());
535 EXPECT_EQ(1, result.val->data_segments.size());
Ben Murdoch014dc512016-03-22 12:00:34 +0000536
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100537 WasmGlobal* global = &result.val->globals.back();
Ben Murdoch014dc512016-03-22 12:00:34 +0000538
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100539 EXPECT_EQ(0, global->name_length);
Ben Murdoch014dc512016-03-22 12:00:34 +0000540 EXPECT_EQ(MachineType::Uint8(), global->type);
541 EXPECT_EQ(0, global->offset);
542 EXPECT_FALSE(global->exported);
543
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100544 WasmFunction* function = &result.val->functions.back();
Ben Murdoch014dc512016-03-22 12:00:34 +0000545
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100546 EXPECT_EQ(63, function->name_offset);
547 EXPECT_EQ(2, function->name_length);
Ben Murdoch014dc512016-03-22 12:00:34 +0000548 EXPECT_EQ(kCodeStartOffset, function->code_start_offset);
549 EXPECT_EQ(kCodeEndOffset, function->code_end_offset);
550
551 EXPECT_FALSE(function->exported);
552 EXPECT_FALSE(function->external);
553
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100554 WasmDataSegment* segment = &result.val->data_segments.back();
Ben Murdoch014dc512016-03-22 12:00:34 +0000555
556 EXPECT_EQ(0x8b3ae, segment->dest_addr);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100557 EXPECT_EQ(kDataSegmentSourceOffset, segment->source_offset);
Ben Murdoch014dc512016-03-22 12:00:34 +0000558 EXPECT_EQ(5, segment->source_size);
559 EXPECT_TRUE(segment->init);
560
561 if (result.val) delete result.val;
562 }
563}
564
565
566TEST_F(WasmModuleVerifyTest, OneDataSegment) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100567 const byte kDataSegmentSourceOffset = 39;
Ben Murdoch014dc512016-03-22 12:00:34 +0000568 const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100569 SECTION(MEMORY, 3),
570 28,
571 28,
572 1,
573 SECTION(DATA_SEGMENTS, 8),
574 1,
575 U32V_3(0x9bbaa), // dest addr
576 U32V_1(3), // source size
577 'a',
578 'b',
579 'c' // data bytes
Ben Murdoch014dc512016-03-22 12:00:34 +0000580 };
581
582 {
Ben Murdoch109988c2016-05-18 11:27:45 +0100583 EXPECT_VERIFIES(data);
Ben Murdoch014dc512016-03-22 12:00:34 +0000584 ModuleResult result = DecodeModule(data, data + arraysize(data));
585 EXPECT_TRUE(result.ok());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100586 EXPECT_EQ(0, result.val->globals.size());
587 EXPECT_EQ(0, result.val->functions.size());
588 EXPECT_EQ(1, result.val->data_segments.size());
Ben Murdoch014dc512016-03-22 12:00:34 +0000589
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100590 WasmDataSegment* segment = &result.val->data_segments.back();
Ben Murdoch014dc512016-03-22 12:00:34 +0000591
592 EXPECT_EQ(0x9bbaa, segment->dest_addr);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100593 EXPECT_EQ(kDataSegmentSourceOffset, segment->source_offset);
Ben Murdoch014dc512016-03-22 12:00:34 +0000594 EXPECT_EQ(3, segment->source_size);
595 EXPECT_TRUE(segment->init);
596
597 if (result.val) delete result.val;
598 }
599
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100600 EXPECT_OFF_END_FAILURE(data, 13, sizeof(data));
Ben Murdoch014dc512016-03-22 12:00:34 +0000601}
602
603
604TEST_F(WasmModuleVerifyTest, TwoDataSegments) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100605 const byte kDataSegment0SourceOffset = 39;
606 const byte kDataSegment1SourceOffset = 39 + 8;
607
Ben Murdoch014dc512016-03-22 12:00:34 +0000608 const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100609 SECTION(MEMORY, 3),
610 28,
611 28,
612 1,
613 SECTION(DATA_SEGMENTS, 31),
614 2, // segment count
615 U32V_3(0x7ffee), // #0: dest addr
616 U32V_1(4), // source size
617 1,
618 2,
619 3,
620 4, // data bytes
621 U32V_3(0x6ddcc), // #1: dest addr
622 U32V_1(10), // source size
623 1,
624 2,
625 3,
626 4,
627 5,
628 6,
629 7,
630 8,
631 9,
632 10 // data bytes
Ben Murdoch014dc512016-03-22 12:00:34 +0000633 };
634
635 {
636 ModuleResult result = DecodeModule(data, data + arraysize(data));
637 EXPECT_TRUE(result.ok());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100638 EXPECT_EQ(0, result.val->globals.size());
639 EXPECT_EQ(0, result.val->functions.size());
640 EXPECT_EQ(2, result.val->data_segments.size());
Ben Murdoch014dc512016-03-22 12:00:34 +0000641
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100642 WasmDataSegment* s0 = &result.val->data_segments[0];
643 WasmDataSegment* s1 = &result.val->data_segments[1];
Ben Murdoch014dc512016-03-22 12:00:34 +0000644
645 EXPECT_EQ(0x7ffee, s0->dest_addr);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100646 EXPECT_EQ(kDataSegment0SourceOffset, s0->source_offset);
Ben Murdoch014dc512016-03-22 12:00:34 +0000647 EXPECT_EQ(4, s0->source_size);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100648 EXPECT_TRUE(s0->init);
Ben Murdoch014dc512016-03-22 12:00:34 +0000649
650 EXPECT_EQ(0x6ddcc, s1->dest_addr);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100651 EXPECT_EQ(kDataSegment1SourceOffset, s1->source_offset);
Ben Murdoch014dc512016-03-22 12:00:34 +0000652 EXPECT_EQ(10, s1->source_size);
653 EXPECT_TRUE(s1->init);
654
655 if (result.val) delete result.val;
656 }
657
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100658 EXPECT_OFF_END_FAILURE(data, 13, sizeof(data));
Ben Murdoch014dc512016-03-22 12:00:34 +0000659}
660
Ben Murdoch109988c2016-05-18 11:27:45 +0100661TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidDest) {
662 const int source_size = 3;
Ben Murdoch109988c2016-05-18 11:27:45 +0100663
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100664 for (byte mem_pages = 1; mem_pages < 16; mem_pages++) {
665 int mem_size = mem_pages * 0x10000; // 64k pages.
Ben Murdoch109988c2016-05-18 11:27:45 +0100666
667 for (int dest_addr = mem_size - source_size;
668 dest_addr < mem_size + source_size; dest_addr++) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100669 byte data[] = {SECTION(MEMORY, 3),
670 mem_pages,
671 mem_pages,
672 1,
673 SECTION(DATA_SEGMENTS, 14),
674 1,
675 U32V_3(dest_addr),
676 U32V_1(source_size),
677 'a',
678 'b',
679 'c'};
Ben Murdoch109988c2016-05-18 11:27:45 +0100680
681 if (dest_addr <= (mem_size - source_size)) {
682 EXPECT_VERIFIES(data);
683 } else {
684 EXPECT_FAILURE(data);
685 }
686 }
687 }
688}
689
690
Ben Murdoch014dc512016-03-22 12:00:34 +0000691// To make below tests for indirect calls much shorter.
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100692#define FUNCTION(sig_index, external) kDeclFunctionImport, SIG_INDEX(sig_index)
Ben Murdoch014dc512016-03-22 12:00:34 +0000693
694TEST_F(WasmModuleVerifyTest, OneIndirectFunction) {
695 static const byte data[] = {
696 // sig#0 -------------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100697 SECTION(SIGNATURES, 3), 1, 0, 0, // void -> void
Ben Murdoch014dc512016-03-22 12:00:34 +0000698 // func#0 ------------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100699 SECTION(FUNCTIONS, 4), 1, FUNCTION(0, 0),
Ben Murdoch014dc512016-03-22 12:00:34 +0000700 // indirect table ----------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100701 SECTION(FUNCTION_TABLE, 2), 1, U32V_1(0)};
Ben Murdoch014dc512016-03-22 12:00:34 +0000702
703 ModuleResult result = DecodeModule(data, data + arraysize(data));
704 EXPECT_TRUE(result.ok());
705 if (result.ok()) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100706 EXPECT_EQ(1, result.val->signatures.size());
707 EXPECT_EQ(1, result.val->functions.size());
708 EXPECT_EQ(1, result.val->function_table.size());
709 EXPECT_EQ(0, result.val->function_table[0]);
Ben Murdoch014dc512016-03-22 12:00:34 +0000710 }
711 if (result.val) delete result.val;
712}
713
714
715TEST_F(WasmModuleVerifyTest, MultipleIndirectFunctions) {
716 static const byte data[] = {
717 // sig#0 -------------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100718 SECTION(SIGNATURES, 5), 2, 0, 0, // void -> void
719 0, kLocalI32, // void -> i32
Ben Murdoch014dc512016-03-22 12:00:34 +0000720 // func#0 ------------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100721 SECTION(FUNCTIONS, 13), 4, FUNCTION(0, 1), // --
722 FUNCTION(1, 1), // --
723 FUNCTION(0, 1), // --
724 FUNCTION(1, 1), // --
Ben Murdoch014dc512016-03-22 12:00:34 +0000725 // indirect table ----------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100726 SECTION(FUNCTION_TABLE, 9), 8,
727 U32V_1(0), // --
728 U32V_1(1), // --
729 U32V_1(2), // --
730 U32V_1(3), // --
731 U32V_1(0), // --
732 U32V_1(1), // --
733 U32V_1(2), // --
734 U32V_1(3), // --
Ben Murdoch014dc512016-03-22 12:00:34 +0000735 };
736
737 ModuleResult result = DecodeModule(data, data + arraysize(data));
738 EXPECT_TRUE(result.ok());
739 if (result.ok()) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100740 EXPECT_EQ(2, result.val->signatures.size());
741 EXPECT_EQ(4, result.val->functions.size());
742 EXPECT_EQ(8, result.val->function_table.size());
Ben Murdoch014dc512016-03-22 12:00:34 +0000743 for (int i = 0; i < 8; i++) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100744 EXPECT_EQ(i & 3, result.val->function_table[i]);
Ben Murdoch014dc512016-03-22 12:00:34 +0000745 }
746 }
747 if (result.val) delete result.val;
748}
749
750
751TEST_F(WasmModuleVerifyTest, IndirectFunctionNoFunctions) {
752 static const byte data[] = {
753 // sig#0 -------------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100754 SECTION(SIGNATURES, 3), 1, 0, 0, // void -> void
Ben Murdoch014dc512016-03-22 12:00:34 +0000755 // indirect table ----------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100756 SECTION(FUNCTION_TABLE, 3), 1, 0, 0,
Ben Murdoch014dc512016-03-22 12:00:34 +0000757 };
758
759 EXPECT_FAILURE(data);
760}
761
762
763TEST_F(WasmModuleVerifyTest, IndirectFunctionInvalidIndex) {
764 static const byte data[] = {
765 // sig#0 -------------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100766 SECTION(SIGNATURES, 3), 1, 0, 0, // void -> void
Ben Murdoch014dc512016-03-22 12:00:34 +0000767 // functions ---------------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100768 SECTION(FUNCTIONS, 4), 1, FUNCTION(0, 1),
Ben Murdoch014dc512016-03-22 12:00:34 +0000769 // indirect table ----------------------------------------------
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100770 SECTION(FUNCTION_TABLE, 3), 1, 1, 0,
Ben Murdoch014dc512016-03-22 12:00:34 +0000771 };
772
773 EXPECT_FAILURE(data);
774}
775
776
777class WasmSignatureDecodeTest : public TestWithZone {};
778
779
780TEST_F(WasmSignatureDecodeTest, Ok_v_v) {
781 static const byte data[] = {0, 0};
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100782 base::AccountingAllocator allocator;
783 Zone zone(&allocator);
Ben Murdoch014dc512016-03-22 12:00:34 +0000784 FunctionSig* sig =
785 DecodeWasmSignatureForTesting(&zone, data, data + arraysize(data));
786
787 EXPECT_TRUE(sig != nullptr);
788 EXPECT_EQ(0, sig->parameter_count());
789 EXPECT_EQ(0, sig->return_count());
790}
791
792
793TEST_F(WasmSignatureDecodeTest, Ok_t_v) {
794 for (size_t i = 0; i < arraysize(kLocalTypes); i++) {
795 LocalTypePair ret_type = kLocalTypes[i];
796 const byte data[] = {0, ret_type.code};
797 FunctionSig* sig =
798 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data));
799
800 EXPECT_TRUE(sig != nullptr);
801 EXPECT_EQ(0, sig->parameter_count());
802 EXPECT_EQ(1, sig->return_count());
803 EXPECT_EQ(ret_type.type, sig->GetReturn());
804 }
805}
806
807
808TEST_F(WasmSignatureDecodeTest, Ok_v_t) {
809 for (size_t i = 0; i < arraysize(kLocalTypes); i++) {
810 LocalTypePair param_type = kLocalTypes[i];
811 const byte data[] = {1, 0, param_type.code};
812 FunctionSig* sig =
813 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data));
814
815 EXPECT_TRUE(sig != nullptr);
816 EXPECT_EQ(1, sig->parameter_count());
817 EXPECT_EQ(0, sig->return_count());
818 EXPECT_EQ(param_type.type, sig->GetParam(0));
819 }
820}
821
822
823TEST_F(WasmSignatureDecodeTest, Ok_t_t) {
824 for (size_t i = 0; i < arraysize(kLocalTypes); i++) {
825 LocalTypePair ret_type = kLocalTypes[i];
826 for (size_t j = 0; j < arraysize(kLocalTypes); j++) {
827 LocalTypePair param_type = kLocalTypes[j];
828 const byte data[] = {1, // param count
829 ret_type.code, // ret
830 param_type.code}; // param
831 FunctionSig* sig =
832 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data));
833
834 EXPECT_TRUE(sig != nullptr);
835 EXPECT_EQ(1, sig->parameter_count());
836 EXPECT_EQ(1, sig->return_count());
837 EXPECT_EQ(param_type.type, sig->GetParam(0));
838 EXPECT_EQ(ret_type.type, sig->GetReturn());
839 }
840 }
841}
842
843
844TEST_F(WasmSignatureDecodeTest, Ok_i_tt) {
845 for (size_t i = 0; i < arraysize(kLocalTypes); i++) {
846 LocalTypePair p0_type = kLocalTypes[i];
847 for (size_t j = 0; j < arraysize(kLocalTypes); j++) {
848 LocalTypePair p1_type = kLocalTypes[j];
849 const byte data[] = {2, // param count
850 kLocalI32, // ret
851 p0_type.code, // p0
852 p1_type.code}; // p1
853 FunctionSig* sig =
854 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data));
855
856 EXPECT_TRUE(sig != nullptr);
857 EXPECT_EQ(2, sig->parameter_count());
858 EXPECT_EQ(1, sig->return_count());
859 EXPECT_EQ(p0_type.type, sig->GetParam(0));
860 EXPECT_EQ(p1_type.type, sig->GetParam(1));
861 }
862 }
863}
864
865
866TEST_F(WasmSignatureDecodeTest, Fail_off_end) {
867 byte data[256];
868 for (int p = 0; p <= 255; p = p + 1 + p * 3) {
869 for (int i = 0; i <= p; i++) data[i] = kLocalI32;
870 data[0] = static_cast<byte>(p);
871
872 for (int i = 0; i < p + 1; i++) {
873 // Should fall off the end for all signatures.
874 FunctionSig* sig = DecodeWasmSignatureForTesting(zone(), data, data + i);
875 EXPECT_EQ(nullptr, sig);
876 }
877 }
878}
879
880
881TEST_F(WasmSignatureDecodeTest, Fail_invalid_type) {
882 byte kInvalidType = 76;
883 for (int i = 1; i < 3; i++) {
884 byte data[] = {2, kLocalI32, kLocalI32, kLocalI32};
885 data[i] = kInvalidType;
886 FunctionSig* sig =
887 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data));
888 EXPECT_EQ(nullptr, sig);
889 }
890}
891
892
893TEST_F(WasmSignatureDecodeTest, Fail_invalid_param_type) {
894 static const int kParamCount = 3;
895 for (int i = 0; i < kParamCount; i++) {
896 byte data[] = {kParamCount, kLocalI32, kLocalI32, kLocalI32, kLocalI32};
897 data[i + 2] = kLocalVoid;
898 FunctionSig* sig =
899 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data));
900 EXPECT_EQ(nullptr, sig);
901 }
902}
903
904
905class WasmFunctionVerifyTest : public TestWithZone {};
906
907
908TEST_F(WasmFunctionVerifyTest, Ok_v_v_empty) {
Ben Murdoch109988c2016-05-18 11:27:45 +0100909 static const byte data[] = {
Ben Murdoch014dc512016-03-22 12:00:34 +0000910 0, kLocalVoid, // signature
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100911 4, // locals
912 3, kLocalI32, // --
913 4, kLocalI64, // --
914 5, kLocalF32, // --
915 6, kLocalF64, // --
Ben Murdoch014dc512016-03-22 12:00:34 +0000916 kExprNop // body
917 };
918
919 FunctionResult result = DecodeWasmFunction(nullptr, zone(), nullptr, data,
920 data + arraysize(data));
921 EXPECT_TRUE(result.ok());
922
923 if (result.val && result.ok()) {
924 WasmFunction* function = result.val;
925 EXPECT_EQ(0, function->sig->parameter_count());
926 EXPECT_EQ(0, function->sig->return_count());
927 EXPECT_EQ(0, function->name_offset);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100928 EXPECT_EQ(2, function->code_start_offset);
Ben Murdoch014dc512016-03-22 12:00:34 +0000929 EXPECT_EQ(arraysize(data), function->code_end_offset);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100930 // TODO(titzer): verify encoding of local declarations
Ben Murdoch014dc512016-03-22 12:00:34 +0000931 EXPECT_FALSE(function->external);
932 EXPECT_FALSE(function->exported);
933 }
934
935 if (result.val) delete result.val;
936}
937
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100938TEST_F(WasmModuleVerifyTest, SectionWithoutNameLength) {
939 const byte data[] = {1};
940 EXPECT_FAILURE(data);
941}
Ben Murdoch014dc512016-03-22 12:00:34 +0000942
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100943TEST_F(WasmModuleVerifyTest, TheLoneliestOfValidModulesTheTrulyEmptyOne) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000944 const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100945 1, // Section size.
946 0, // Empty section name.
947 // No section name, no content, nothing but sadness.
948 };
949 EXPECT_VERIFIES(data);
950}
951
952TEST_F(WasmModuleVerifyTest, OnlyUnknownSectionEmpty) {
953 const byte data[] = {
954 5, // Section size.
955 4, 'l', 'u', 'l', 'z', // unknown section.
956 };
957 EXPECT_VERIFIES(data);
958}
959
960TEST_F(WasmModuleVerifyTest, OnlyUnknownSectionNonEmpty) {
961 const byte data[] = {
962 10, // Section size.
963 4, 'l', 'u', 'l', 'z', // unknown section.
964 // Section content:
965 0xff, 0xff, 0xff, 0xff, 0xff,
966 };
967 EXPECT_VERIFIES(data);
968}
969
970TEST_F(WasmModuleVerifyTest, SignatureFollowedByEmptyUnknownSection) {
971 const byte data[] = {
972 SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE), 1, VOID_VOID_SIG,
973 // -----------------------------------------------------------
974 5, // Section size.
975 4, 'l', 'u', 'l', 'z', // unknown section.
976 };
977 EXPECT_VERIFIES(data);
978}
979
980TEST_F(WasmModuleVerifyTest, SignatureFollowedByUnknownSection) {
981 const byte data[] = {
982 SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE), 1, VOID_VOID_SIG,
983 // -----------------------------------------------------------
984 10, // Section size.
985 4, 'l', 'u', 'l', 'z', // unknown section.
986 0xff, 0xff, 0xff, 0xff, 0xff,
987 };
988 EXPECT_VERIFIES(data);
989}
990
991TEST_F(WasmModuleVerifyTest, SignatureFollowedByUnknownSectionWithLongLEB) {
992 const byte data[] = {
993 SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE), 1, VOID_VOID_SIG,
994 // -----------------------------------------------------------
995 0x85, 0x80, 0x80, 0x80, 0x00, // Section size: 1 but in a 5-byte LEB.
996 4, 'l', 'u', 'l', 'z', // unknown section.
997 };
998 EXPECT_VERIFIES(data);
999}
1000
1001TEST_F(WasmModuleVerifyTest, UnknownSectionOverflow) {
1002 static const byte data[] = {
1003 13, // Section size.
1004 1, // Section name length.
1005 '\0', // Section name.
1006 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10 byte section
Ben Murdoch014dc512016-03-22 12:00:34 +00001007 };
1008 EXPECT_FAILURE(data);
1009}
1010
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001011TEST_F(WasmModuleVerifyTest, UnknownSectionUnderflow) {
Ben Murdoch109988c2016-05-18 11:27:45 +01001012 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001013 0xff, 0xff, 0xff, 0xff, 0x0f, // Section size LEB128 0xffffffff
1014 1, '\0', // Section name and name length.
1015 1, 2, 3, 4, // 4 byte section
Ben Murdoch014dc512016-03-22 12:00:34 +00001016 };
1017 EXPECT_FAILURE(data);
1018}
1019
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001020TEST_F(WasmModuleVerifyTest, UnknownSectionLoop) {
Ben Murdoch014dc512016-03-22 12:00:34 +00001021 // Would infinite loop decoding if wrapping and allowed.
Ben Murdoch109988c2016-05-18 11:27:45 +01001022 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001023 0xfa, 0xff, 0xff, 0xff, 0x0f, // Section size LEB128 0xfffffffa
1024 1, '\0', // Section name and name length.
1025 1, 2, 3, 4, // 4 byte section
Ben Murdoch014dc512016-03-22 12:00:34 +00001026 };
1027 EXPECT_FAILURE(data);
1028}
1029
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001030TEST_F(WasmModuleVerifyTest, UnknownSectionSkipped) {
1031 static const byte data[] = {
1032 3, // Section size.
1033 1,
1034 '\0', // Section name: LEB128 1, string '\0'
1035 0, // one byte section
1036 SECTION(GLOBALS, 7),
1037 1,
1038 0, // name length
1039 kMemI32, // memory type
1040 0, // exported
1041 };
1042 ModuleResult result = DecodeModule(data, data + arraysize(data));
1043 EXPECT_TRUE(result.ok());
1044
1045 EXPECT_EQ(1, result.val->globals.size());
1046 EXPECT_EQ(0, result.val->functions.size());
1047 EXPECT_EQ(0, result.val->data_segments.size());
1048
1049 WasmGlobal* global = &result.val->globals.back();
1050
1051 EXPECT_EQ(0, global->name_length);
1052 EXPECT_EQ(MachineType::Int32(), global->type);
1053 EXPECT_EQ(0, global->offset);
1054 EXPECT_FALSE(global->exported);
1055
1056 if (result.val) delete result.val;
1057}
1058
Ben Murdoch109988c2016-05-18 11:27:45 +01001059TEST_F(WasmModuleVerifyTest, ImportTable_empty) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001060 static const byte data[] = {SECTION(SIGNATURES, 1), 0,
1061 SECTION(IMPORT_TABLE, 1), 0};
Ben Murdoch109988c2016-05-18 11:27:45 +01001062 EXPECT_VERIFIES(data);
1063}
1064
1065TEST_F(WasmModuleVerifyTest, ImportTable_nosigs) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001066 static const byte data[] = {SECTION(IMPORT_TABLE, 1), 0};
Ben Murdoch109988c2016-05-18 11:27:45 +01001067 EXPECT_FAILURE(data);
1068}
1069
1070TEST_F(WasmModuleVerifyTest, ImportTable_invalid_sig) {
1071 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001072 SECTION(SIGNATURES, 1), 0, SECTION(IMPORT_TABLE, 6), 1,
1073 IMPORT_SIG_INDEX(0), // sig index
1074 NAME_LENGTH(1), 'm', // module name
1075 NAME_LENGTH(1), 'f', // function name
Ben Murdoch109988c2016-05-18 11:27:45 +01001076 };
1077 EXPECT_FAILURE(data);
1078}
1079
1080TEST_F(WasmModuleVerifyTest, ImportTable_one_sig) {
1081 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001082 SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE),
Ben Murdoch109988c2016-05-18 11:27:45 +01001083 1,
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001084 VOID_VOID_SIG,
1085 SECTION(IMPORT_TABLE, 6),
1086 1, // --
1087 IMPORT_SIG_INDEX(0), // sig index
1088 NAME_LENGTH(1),
1089 'm', // module name
1090 NAME_LENGTH(1),
1091 'f', // function name
Ben Murdoch109988c2016-05-18 11:27:45 +01001092 };
1093 EXPECT_VERIFIES(data);
1094}
1095
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001096TEST_F(WasmModuleVerifyTest, ImportTable_invalid_module) {
1097 static const byte data[] = {
1098 SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE),
1099 1,
1100 VOID_VOID_SIG,
1101 SECTION(IMPORT_TABLE, 6),
1102 1, // --
1103 IMPORT_SIG_INDEX(0), // sig index
1104 NO_NAME, // module name
1105 NAME_LENGTH(1),
1106 'f' // function name
1107 };
1108 EXPECT_FAILURE(data);
1109}
1110
Ben Murdoch109988c2016-05-18 11:27:45 +01001111TEST_F(WasmModuleVerifyTest, ImportTable_off_end) {
1112 static const byte data[] = {
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001113 SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE),
Ben Murdoch109988c2016-05-18 11:27:45 +01001114 1,
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001115 VOID_VOID_SIG,
1116 SECTION(IMPORT_TABLE, 6),
Ben Murdoch109988c2016-05-18 11:27:45 +01001117 1,
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001118 IMPORT_SIG_INDEX(0), // sig index
1119 NAME_LENGTH(1),
1120 'm', // module name
1121 NAME_LENGTH(1),
1122 'f', // function name
Ben Murdoch109988c2016-05-18 11:27:45 +01001123 };
1124
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001125 EXPECT_OFF_END_FAILURE(data, 16, sizeof(data));
1126}
1127
1128TEST_F(WasmModuleVerifyTest, ExportTable_empty1) {
1129 static const byte data[] = {SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE),
1130 1,
1131 VOID_VOID_SIG,
1132 SECTION(FUNCTIONS, 1 + EMPTY_FUNCTION_SIZE),
1133 1,
1134 EMPTY_FUNCTION(0),
1135 SECTION(EXPORT_TABLE, 1),
1136 0};
1137 EXPECT_VERIFIES(data);
1138}
1139
1140TEST_F(WasmModuleVerifyTest, ExportTable_empty2) {
1141 static const byte data[] = {SECTION(SIGNATURES, 1), 0,
1142 SECTION(FUNCTIONS, 1), 0,
1143 SECTION(EXPORT_TABLE, 1), 0};
1144 // TODO(titzer): current behavior treats empty functions section as missing.
1145 EXPECT_FAILURE(data);
1146}
1147
1148TEST_F(WasmModuleVerifyTest, ExportTable_NoFunctions1) {
1149 static const byte data[] = {SECTION(SIGNATURES, 1), 0,
1150 SECTION(EXPORT_TABLE, 1), 0};
1151 EXPECT_FAILURE(data);
1152}
1153
1154TEST_F(WasmModuleVerifyTest, ExportTable_NoFunctions2) {
1155 static const byte data[] = {SECTION(EXPORT_TABLE, 1), 0};
1156 EXPECT_FAILURE(data);
1157}
1158
1159TEST_F(WasmModuleVerifyTest, ExportTableOne) {
1160 static const byte data[] = {
1161 SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE),
1162 1, // sigs
1163 VOID_VOID_SIG, // --
1164 SECTION(FUNCTIONS, 1 + EMPTY_FUNCTION_SIZE),
1165 1, // functions
1166 EMPTY_FUNCTION(0), // --
1167 SECTION(EXPORT_TABLE, 7),
1168 1, // exports
1169 FUNC_INDEX(0), // --
1170 NO_NAME // --
1171 };
1172 EXPECT_VERIFIES(data);
1173}
1174
1175TEST_F(WasmModuleVerifyTest, ExportTableTwo) {
1176 static const byte data[] = {
1177 SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE),
1178 1, // sigs
1179 VOID_VOID_SIG, // --
1180 SECTION(FUNCTIONS, 1 + EMPTY_FUNCTION_SIZE),
1181 1, // functions
1182 EMPTY_FUNCTION(0), // --
1183 SECTION(EXPORT_TABLE, 12),
1184 2, // exports
1185 FUNC_INDEX(0), // --
1186 NAME_LENGTH(4),
1187 'n',
1188 'a',
1189 'm',
1190 'e', // --
1191 FUNC_INDEX(0), // --
1192 NAME_LENGTH(3),
1193 'n',
1194 'o',
1195 'm' // --
1196 };
1197 EXPECT_VERIFIES(data);
1198}
1199
1200TEST_F(WasmModuleVerifyTest, ExportTableThree) {
1201 static const byte data[] = {
1202 SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE),
1203 1, // sigs
1204 VOID_VOID_SIG, // --
1205 SECTION(FUNCTIONS, 1 + 3 * EMPTY_FUNCTION_SIZE),
1206 3, // functions
1207 EMPTY_FUNCTION(0), // --
1208 EMPTY_FUNCTION(0), // --
1209 EMPTY_FUNCTION(0), // --
1210 SECTION(EXPORT_TABLE, 10),
1211 3, // exports
1212 FUNC_INDEX(0), // --
1213 NAME_LENGTH(1),
1214 'a', // --
1215 FUNC_INDEX(1), // --
1216 NAME_LENGTH(1),
1217 'b', // --
1218 FUNC_INDEX(2), // --
1219 NAME_LENGTH(1),
1220 'c' // --
1221 };
1222 EXPECT_VERIFIES(data);
1223}
1224
1225TEST_F(WasmModuleVerifyTest, ExportTableThreeOne) {
1226 for (int i = 0; i < 6; i++) {
1227 const byte data[] = {
1228 SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE),
1229 1, // sigs
1230 VOID_VOID_SIG, // --
1231 SECTION(FUNCTIONS, 1 + 3 * EMPTY_FUNCTION_SIZE),
1232 3, // functions
1233 EMPTY_FUNCTION(0), // --
1234 EMPTY_FUNCTION(0), // --
1235 EMPTY_FUNCTION(0), // --
1236 SECTION(EXPORT_TABLE, 5),
1237 1, // exports
1238 FUNC_INDEX(i), // --
1239 NAME_LENGTH(2),
1240 'e',
1241 'x', // --
1242 };
1243
1244 if (i < 3) {
1245 EXPECT_VERIFIES(data);
1246 } else {
1247 EXPECT_FAILURE(data);
1248 }
1249 }
1250}
1251
1252TEST_F(WasmModuleVerifyTest, ExportTableOne_off_end) {
1253 static const byte data[] = {
1254 SECTION(SIGNATURES, 1 + VOID_VOID_SIG_SIZE),
1255 1, // sigs
1256 VOID_VOID_SIG, // --
1257 SECTION(FUNCTIONS, 1 + EMPTY_FUNCTION_SIZE),
1258 1, // functions
1259 EMPTY_FUNCTION(0), // --
1260 SECTION(EXPORT_TABLE, 1 + 6),
1261 1, // exports
1262 FUNC_INDEX(0), // --
1263 NO_NAME // --
1264 };
1265
1266 for (int length = 33; length < sizeof(data); length++) {
Ben Murdoch109988c2016-05-18 11:27:45 +01001267 ModuleResult result = DecodeModule(data, data + length);
1268 EXPECT_FALSE(result.ok());
1269 if (result.val) delete result.val;
1270 }
1271}
1272
Ben Murdoch3b9bc312016-06-02 14:46:10 +01001273#define SIGNATURES_SECTION(count, ...) \
1274 SECTION(SIGNATURES, 1 + 3 * (count)), U32V_1(count), __VA_ARGS__
1275#define FUNCTION_SIGNATURES_SECTION(count, ...) \
1276 SECTION(FUNCTION_SIGNATURES, 1 + (count)), U32V_1(count), __VA_ARGS__
1277
1278#define FOO_STRING 3, 'f', 'o', 'o'
1279#define NO_LOCAL_NAMES 0
1280
1281#define EMPTY_SIGNATURES_SECTION SECTION(SIGNATURES, 1), 0
1282#define EMPTY_FUNCTION_SIGNATURES_SECTION SECTION(FUNCTION_SIGNATURES, 1), 0
1283#define EMPTY_FUNCTION_BODIES_SECTION SECTION(FUNCTION_BODIES, 1), 0
1284#define EMPTY_NAMES_SECTION SECTION(NAMES, 1), 0
1285
1286TEST_F(WasmModuleVerifyTest, FunctionSignatures_empty) {
1287 static const byte data[] = {SECTION(SIGNATURES, 1), 0,
1288 SECTION(FUNCTION_SIGNATURES, 1), 0};
1289 EXPECT_VERIFIES(data);
1290}
1291
1292TEST_F(WasmModuleVerifyTest, FunctionSignatures_one) {
1293 static const byte data[] = {SIGNATURES_SECTION(1, VOID_VOID_SIG),
1294 FUNCTION_SIGNATURES_SECTION(1, 0)};
1295 EXPECT_VERIFIES(data);
1296}
1297
1298TEST_F(WasmModuleVerifyTest, FunctionBodies_empty) {
1299 static const byte data[] = {EMPTY_SIGNATURES_SECTION,
1300 EMPTY_FUNCTION_SIGNATURES_SECTION,
1301 EMPTY_FUNCTION_BODIES_SECTION};
1302 EXPECT_VERIFIES(data);
1303}
1304
1305TEST_F(WasmModuleVerifyTest, FunctionBodies_one_empty) {
1306 static const byte data[] = {
1307 SIGNATURES_SECTION(1, VOID_VOID_SIG), FUNCTION_SIGNATURES_SECTION(1, 0),
1308 SECTION(FUNCTION_BODIES, 1 + EMPTY_BODY_SIZE), 1, EMPTY_BODY};
1309 EXPECT_VERIFIES(data);
1310}
1311
1312TEST_F(WasmModuleVerifyTest, FunctionBodies_one_nop) {
1313 static const byte data[] = {
1314 SIGNATURES_SECTION(1, VOID_VOID_SIG), FUNCTION_SIGNATURES_SECTION(1, 0),
1315 SECTION(FUNCTION_BODIES, 1 + NOP_BODY_SIZE), 1, NOP_BODY};
1316 EXPECT_VERIFIES(data);
1317}
1318
1319TEST_F(WasmModuleVerifyTest, FunctionBodies_count_mismatch1) {
1320 static const byte data[] = {SIGNATURES_SECTION(1, VOID_VOID_SIG),
1321 FUNCTION_SIGNATURES_SECTION(2, 0, 0),
1322 SECTION(FUNCTION_BODIES, 1 + EMPTY_BODY_SIZE), 1,
1323 EMPTY_BODY};
1324 EXPECT_FAILURE(data);
1325}
1326
1327TEST_F(WasmModuleVerifyTest, FunctionBodies_count_mismatch2) {
1328 static const byte data[] = {SIGNATURES_SECTION(1, VOID_VOID_SIG),
1329 FUNCTION_SIGNATURES_SECTION(1, 0),
1330 SECTION(FUNCTION_BODIES, 1 + 2 * NOP_BODY_SIZE),
1331 2,
1332 NOP_BODY,
1333 NOP_BODY};
1334 EXPECT_FAILURE(data);
1335}
1336
1337TEST_F(WasmModuleVerifyTest, Names_empty) {
1338 static const byte data[] = {
1339 EMPTY_SIGNATURES_SECTION, EMPTY_FUNCTION_SIGNATURES_SECTION,
1340 EMPTY_FUNCTION_BODIES_SECTION, EMPTY_NAMES_SECTION};
1341 EXPECT_VERIFIES(data);
1342}
1343
1344TEST_F(WasmModuleVerifyTest, Names_one_empty) {
1345 static const byte data[] = {
1346 SIGNATURES_SECTION(1, VOID_VOID_SIG), // --
1347 FUNCTION_SIGNATURES_SECTION(1, 0), // --
1348 SECTION(FUNCTION_BODIES, 1 + EMPTY_BODY_SIZE),
1349 1,
1350 EMPTY_BODY, // --
1351 SECTION(NAMES, 1 + 5),
1352 1,
1353 FOO_STRING,
1354 NO_LOCAL_NAMES // --
1355 };
1356 EXPECT_VERIFIES(data);
1357}
1358
1359TEST_F(WasmModuleVerifyTest, Names_two_empty) {
1360 static const byte data[] = {
1361 SIGNATURES_SECTION(1, VOID_VOID_SIG), // --
1362 FUNCTION_SIGNATURES_SECTION(2, 0, 0), // --
1363 SECTION(FUNCTION_BODIES, 1 + 2 * EMPTY_BODY_SIZE), // --
1364 2,
1365 EMPTY_BODY,
1366 EMPTY_BODY, // --
1367 SECTION(NAMES, 1 + 10),
1368 2, // --
1369 FOO_STRING,
1370 NO_LOCAL_NAMES, // --
1371 FOO_STRING,
1372 NO_LOCAL_NAMES, // --
1373 };
1374 EXPECT_VERIFIES(data);
1375}
1376
Ben Murdoch014dc512016-03-22 12:00:34 +00001377} // namespace wasm
1378} // namespace internal
1379} // namespace v8