OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "test/unittests/test-utils.h" | 5 #include "test/unittests/test-utils.h" |
6 | 6 |
7 #include "src/wasm/module-decoder.h" | 7 #include "src/wasm/module-decoder.h" |
| 8 #include "src/wasm/wasm-macro-gen.h" |
8 #include "src/wasm/wasm-opcodes.h" | 9 #include "src/wasm/wasm-opcodes.h" |
9 | 10 |
10 namespace v8 { | 11 namespace v8 { |
11 namespace internal { | 12 namespace internal { |
12 namespace wasm { | 13 namespace wasm { |
13 | 14 |
| 15 #define EMPTY_FUNCTION(sig_index) 0, SIG_INDEX(sig_index), U16_LE(0) |
14 #define VOID_VOID_SIG 0, kLocalVoid | 16 #define VOID_VOID_SIG 0, kLocalVoid |
15 #define INT_INT_SIG 1, kLocalI32, kLocalI32 | 17 #define INT_INT_SIG 1, kLocalI32, kLocalI32 |
16 | 18 |
17 #define U32(v) \ | |
18 static_cast<byte>(v), static_cast<byte>(v >> 8), static_cast<byte>(v >> 16), \ | |
19 static_cast<byte>(v >> 24) | |
20 #define U16(v) static_cast<byte>(v), static_cast<byte>(v >> 8) | |
21 #define U8(v) static_cast<byte>(v) | |
22 | |
23 #define SIG_INDEX(v) U16(v) | |
24 #define FUNC_INDEX(v) U16(v) | |
25 #define NAME_OFFSET(v) U32(v) | |
26 | |
27 #define EMPTY_FUNCTION(sig_index) 0, SIG_INDEX(sig_index), U16(0) | |
28 | |
29 class WasmModuleVerifyTest : public TestWithZone { | |
30 public: | |
31 ModuleResult DecodeModule(const byte* module_start, const byte* module_end) { | |
32 return DecodeWasmModule(nullptr, zone(), module_start, module_end, false, | |
33 kWasmOrigin); | |
34 } | |
35 }; | |
36 | |
37 | |
38 #define EXPECT_VERIFIES(data) \ | 19 #define EXPECT_VERIFIES(data) \ |
39 do { \ | 20 do { \ |
40 ModuleResult result = DecodeModule(data, data + arraysize(data)); \ | 21 ModuleResult result = DecodeModule(data, data + arraysize(data)); \ |
41 EXPECT_TRUE(result.ok()); \ | 22 EXPECT_TRUE(result.ok()); \ |
42 if (result.val) delete result.val; \ | 23 if (result.val) delete result.val; \ |
43 } while (false) | 24 } while (false) |
44 | 25 |
45 | 26 #define EXPECT_FAILURE_LEN(data, length) \ |
46 #define EXPECT_FAILURE(data) \ | 27 do { \ |
47 do { \ | 28 ModuleResult result = DecodeModule(data, data + length); \ |
48 ModuleResult result = DecodeModule(data, data + arraysize(data)); \ | 29 EXPECT_FALSE(result.ok()); \ |
49 EXPECT_FALSE(result.ok()); \ | 30 if (result.val) delete result.val; \ |
50 if (result.val) delete result.val; \ | |
51 } while (false) | 31 } while (false) |
52 | 32 |
| 33 #define EXPECT_FAILURE(data) EXPECT_FAILURE_LEN(data, sizeof(data)) |
| 34 |
| 35 #define EXPECT_OFF_END_FAILURE(data, min, max) \ |
| 36 do { \ |
| 37 for (size_t length = min; length < max; length++) { \ |
| 38 EXPECT_FAILURE_LEN(data, length); \ |
| 39 } \ |
| 40 } while (false) |
53 | 41 |
54 struct LocalTypePair { | 42 struct LocalTypePair { |
55 uint8_t code; | 43 uint8_t code; |
56 LocalType type; | 44 LocalType type; |
57 } kLocalTypes[] = {{kLocalI32, kAstI32}, | 45 } kLocalTypes[] = {{kLocalI32, kAstI32}, |
58 {kLocalI64, kAstI64}, | 46 {kLocalI64, kAstI64}, |
59 {kLocalF32, kAstF32}, | 47 {kLocalF32, kAstF32}, |
60 {kLocalF64, kAstF64}}; | 48 {kLocalF64, kAstF64}}; |
61 | 49 |
| 50 class WasmModuleVerifyTest : public TestWithZone { |
| 51 public: |
| 52 ModuleResult DecodeModule(const byte* module_start, const byte* module_end) { |
| 53 // Add the WASM magic and version number automatically. |
| 54 size_t size = static_cast<size_t>(module_end - module_start); |
| 55 byte header[] = {WASM_MODULE_HEADER}; |
| 56 size_t total = sizeof(header) + size; |
| 57 auto temp = new byte[total]; |
| 58 memcpy(temp, header, sizeof(header)); |
| 59 memcpy(temp + sizeof(header), module_start, size); |
| 60 ModuleResult result = DecodeWasmModule(nullptr, zone(), temp, temp + total, |
| 61 false, kWasmOrigin); |
| 62 delete[] temp; |
| 63 return result; |
| 64 } |
| 65 ModuleResult DecodeModuleNoHeader(const byte* module_start, |
| 66 const byte* module_end) { |
| 67 return DecodeWasmModule(nullptr, zone(), module_start, module_end, false, |
| 68 kWasmOrigin); |
| 69 } |
| 70 }; |
62 | 71 |
63 TEST_F(WasmModuleVerifyTest, DecodeEmpty) { | 72 TEST_F(WasmModuleVerifyTest, WrongMagic) { |
64 static const byte data[1]{kDeclEnd}; | 73 for (uint32_t x = 1; x; x <<= 1) { |
65 { | 74 const byte data[] = {U32_LE(kWasmMagic ^ x), U32_LE(kWasmVersion), |
66 ModuleResult result = DecodeModule(data, data); | 75 kDeclEnd}; |
67 EXPECT_TRUE(result.ok()); | 76 ModuleResult result = DecodeModuleNoHeader(data, data + sizeof(data)); |
68 if (result.val) delete result.val; | 77 EXPECT_FALSE(result.ok()); |
69 } | |
70 { | |
71 ModuleResult result = DecodeModule(data, data + 1); | |
72 EXPECT_TRUE(result.ok()); | |
73 if (result.val) delete result.val; | 78 if (result.val) delete result.val; |
74 } | 79 } |
75 } | 80 } |
76 | 81 |
| 82 TEST_F(WasmModuleVerifyTest, WrongVersion) { |
| 83 for (uint32_t x = 1; x; x <<= 1) { |
| 84 const byte data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion ^ x), |
| 85 kDeclEnd}; |
| 86 ModuleResult result = DecodeModuleNoHeader(data, data + sizeof(data)); |
| 87 EXPECT_FALSE(result.ok()); |
| 88 if (result.val) delete result.val; |
| 89 } |
| 90 } |
| 91 |
| 92 TEST_F(WasmModuleVerifyTest, DecodeEmpty) { |
| 93 static const byte data[] = {kDeclEnd}; |
| 94 EXPECT_VERIFIES(data); |
| 95 } |
77 | 96 |
78 TEST_F(WasmModuleVerifyTest, OneGlobal) { | 97 TEST_F(WasmModuleVerifyTest, OneGlobal) { |
79 static const byte data[] = { | 98 static const byte data[] = { |
80 kDeclGlobals, | 99 kDeclGlobals, |
81 1, | 100 1, |
82 NAME_OFFSET(0), | 101 NAME_OFFSET(0), |
83 kMemI32, // memory type | 102 kMemI32, // memory type |
84 0, // exported | 103 0, // exported |
85 }; | 104 }; |
86 | 105 |
87 { | 106 { |
88 // Should decode to exactly one global. | 107 // Should decode to exactly one global. |
89 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 108 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
90 EXPECT_TRUE(result.ok()); | 109 EXPECT_TRUE(result.ok()); |
91 EXPECT_EQ(1, result.val->globals->size()); | 110 EXPECT_EQ(1, result.val->globals->size()); |
92 EXPECT_EQ(0, result.val->functions->size()); | 111 EXPECT_EQ(0, result.val->functions->size()); |
93 EXPECT_EQ(0, result.val->data_segments->size()); | 112 EXPECT_EQ(0, result.val->data_segments->size()); |
94 | 113 |
95 WasmGlobal* global = &result.val->globals->back(); | 114 WasmGlobal* global = &result.val->globals->back(); |
96 | 115 |
97 EXPECT_EQ(0, global->name_offset); | 116 EXPECT_EQ(0, global->name_offset); |
98 EXPECT_EQ(MachineType::Int32(), global->type); | 117 EXPECT_EQ(MachineType::Int32(), global->type); |
99 EXPECT_EQ(0, global->offset); | 118 EXPECT_EQ(0, global->offset); |
100 EXPECT_FALSE(global->exported); | 119 EXPECT_FALSE(global->exported); |
101 | 120 |
102 if (result.val) delete result.val; | 121 if (result.val) delete result.val; |
103 } | 122 } |
104 | 123 |
105 for (size_t size = 1; size < arraysize(data); size++) { | 124 EXPECT_OFF_END_FAILURE(data, 1, sizeof(data)); |
106 // Should fall off end of module bytes. | |
107 ModuleResult result = DecodeModule(data, data + size); | |
108 EXPECT_FALSE(result.ok()); | |
109 if (result.val) delete result.val; | |
110 } | |
111 } | 125 } |
112 | 126 |
113 | 127 |
114 TEST_F(WasmModuleVerifyTest, ZeroGlobals) { | 128 TEST_F(WasmModuleVerifyTest, ZeroGlobals) { |
115 static const byte data[] = { | 129 static const byte data[] = { |
116 kDeclGlobals, 0, // declare 0 globals | 130 kDeclGlobals, 0, // declare 0 globals |
117 }; | 131 }; |
118 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 132 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
119 EXPECT_TRUE(result.ok()); | 133 EXPECT_TRUE(result.ok()); |
120 if (result.val) delete result.val; | 134 if (result.val) delete result.val; |
(...skipping 14 matching lines...) Expand all Loading... |
135 } | 149 } |
136 } | 150 } |
137 | 151 |
138 | 152 |
139 TEST_F(WasmModuleVerifyTest, NGlobals) { | 153 TEST_F(WasmModuleVerifyTest, NGlobals) { |
140 static const byte data[] = { | 154 static const byte data[] = { |
141 NAME_OFFSET(0), // name offset | 155 NAME_OFFSET(0), // name offset |
142 kMemI32, // memory type | 156 kMemI32, // memory type |
143 0, // exported | 157 0, // exported |
144 }; | 158 }; |
145 for (uint32_t i = 0; i < 1000000; i = i * 7 + 1) { | 159 |
| 160 for (uint32_t i = 0; i < 1000000; i = i * 13 + 1) { |
146 std::vector<byte> buffer; | 161 std::vector<byte> buffer; |
147 buffer.push_back(kDeclGlobals); | 162 buffer.push_back(kDeclGlobals); |
148 AppendUint32v(buffer, i); | 163 AppendUint32v(buffer, i); |
149 for (uint32_t j = 0; j < i; j++) { | 164 for (uint32_t j = 0; j < i; j++) { |
150 buffer.insert(buffer.end(), data, data + arraysize(data)); | 165 buffer.insert(buffer.end(), data, data + sizeof(data)); |
151 } | 166 } |
152 | 167 |
153 ModuleResult result = DecodeModule(&buffer[0], &buffer[0] + buffer.size()); | 168 ModuleResult result = DecodeModule(&buffer[0], &buffer[0] + buffer.size()); |
154 EXPECT_TRUE(result.ok()); | 169 EXPECT_TRUE(result.ok()); |
155 if (result.val) delete result.val; | 170 if (result.val) delete result.val; |
156 } | 171 } |
157 } | 172 } |
158 | 173 |
159 | 174 |
160 TEST_F(WasmModuleVerifyTest, GlobalWithInvalidNameOffset) { | 175 TEST_F(WasmModuleVerifyTest, GlobalWithInvalidNameOffset) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 EXPECT_FALSE(g0->exported); | 227 EXPECT_FALSE(g0->exported); |
213 | 228 |
214 EXPECT_EQ(0, g1->name_offset); | 229 EXPECT_EQ(0, g1->name_offset); |
215 EXPECT_EQ(MachineType::Float64(), g1->type); | 230 EXPECT_EQ(MachineType::Float64(), g1->type); |
216 EXPECT_EQ(0, g1->offset); | 231 EXPECT_EQ(0, g1->offset); |
217 EXPECT_TRUE(g1->exported); | 232 EXPECT_TRUE(g1->exported); |
218 | 233 |
219 if (result.val) delete result.val; | 234 if (result.val) delete result.val; |
220 } | 235 } |
221 | 236 |
222 for (size_t size = 1; size < arraysize(data); size++) { | 237 EXPECT_OFF_END_FAILURE(data, 1, sizeof(data)); |
223 // Should fall off end of module bytes. | |
224 ModuleResult result = DecodeModule(data, data + size); | |
225 EXPECT_FALSE(result.ok()); | |
226 if (result.val) delete result.val; | |
227 } | |
228 } | 238 } |
229 | 239 |
230 | 240 |
231 TEST_F(WasmModuleVerifyTest, OneSignature) { | 241 TEST_F(WasmModuleVerifyTest, OneSignature) { |
232 { | 242 { |
233 static const byte data[] = {kDeclSignatures, 1, VOID_VOID_SIG}; | 243 static const byte data[] = {kDeclSignatures, 1, VOID_VOID_SIG}; |
234 EXPECT_VERIFIES(data); | 244 EXPECT_VERIFIES(data); |
235 } | 245 } |
236 | 246 |
237 { | 247 { |
(...skipping 25 matching lines...) Expand all Loading... |
263 EXPECT_EQ(0, result.val->signatures->at(0)->return_count()); | 273 EXPECT_EQ(0, result.val->signatures->at(0)->return_count()); |
264 EXPECT_EQ(1, result.val->signatures->at(1)->return_count()); | 274 EXPECT_EQ(1, result.val->signatures->at(1)->return_count()); |
265 EXPECT_EQ(1, result.val->signatures->at(2)->return_count()); | 275 EXPECT_EQ(1, result.val->signatures->at(2)->return_count()); |
266 | 276 |
267 EXPECT_EQ(0, result.val->signatures->at(0)->parameter_count()); | 277 EXPECT_EQ(0, result.val->signatures->at(0)->parameter_count()); |
268 EXPECT_EQ(1, result.val->signatures->at(1)->parameter_count()); | 278 EXPECT_EQ(1, result.val->signatures->at(1)->parameter_count()); |
269 EXPECT_EQ(2, result.val->signatures->at(2)->parameter_count()); | 279 EXPECT_EQ(2, result.val->signatures->at(2)->parameter_count()); |
270 } | 280 } |
271 if (result.val) delete result.val; | 281 if (result.val) delete result.val; |
272 | 282 |
273 for (size_t size = 1; size < arraysize(data); size++) { | 283 EXPECT_OFF_END_FAILURE(data, 1, sizeof(data)); |
274 ModuleResult result = DecodeModule(data, data + size); | |
275 // Should fall off the end of module bytes. | |
276 EXPECT_FALSE(result.ok()); | |
277 if (result.val) delete result.val; | |
278 } | |
279 } | 284 } |
280 | 285 |
281 | 286 |
282 TEST_F(WasmModuleVerifyTest, FunctionWithoutSig) { | 287 TEST_F(WasmModuleVerifyTest, FunctionWithoutSig) { |
283 static const byte data[] = { | 288 static const byte data[] = { |
284 kDeclFunctions, 1, | 289 kDeclFunctions, 1, |
285 // func#0 ------------------------------------------------------ | 290 // func#0 ------------------------------------------------------ |
286 SIG_INDEX(0), // signature index | 291 SIG_INDEX(0), // signature index |
287 NAME_OFFSET(0), // name offset | 292 NAME_OFFSET(0), // name offset |
288 U32(0), // code start offset | 293 U32_LE(0), // code start offset |
289 U32(0), // code end offset | 294 U32_LE(0), // code end offset |
290 U16(899), // local int32 count | 295 U16_LE(899), // local int32 count |
291 U16(799), // local int64 count | 296 U16_LE(799), // local int64 count |
292 U16(699), // local float32 count | 297 U16_LE(699), // local float32 count |
293 U16(599), // local float64 count | 298 U16_LE(599), // local float64 count |
294 0, // exported | 299 0, // exported |
295 1 // external | 300 1 // external |
296 }; | 301 }; |
297 | 302 |
298 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 303 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
299 EXPECT_FALSE(result.ok()); | 304 EXPECT_FALSE(result.ok()); |
300 if (result.val) delete result.val; | 305 if (result.val) delete result.val; |
301 } | 306 } |
302 | 307 |
303 | 308 |
304 TEST_F(WasmModuleVerifyTest, OneEmptyVoidVoidFunction) { | 309 TEST_F(WasmModuleVerifyTest, OneEmptyVoidVoidFunction) { |
305 const int kCodeStartOffset = 23; | 310 const int kCodeStartOffset = 31; |
306 const int kCodeEndOffset = kCodeStartOffset + 1; | 311 const int kCodeEndOffset = kCodeStartOffset + 1; |
307 | 312 |
308 static const byte data[] = { | 313 static const byte data[] = { |
309 kDeclSignatures, 1, | 314 kDeclSignatures, 1, |
310 // sig#0 ------------------------------------------------------- | 315 // sig#0 ------------------------------------------------------- |
311 VOID_VOID_SIG, | 316 VOID_VOID_SIG, |
312 // func#0 ------------------------------------------------------ | 317 // func#0 ------------------------------------------------------ |
313 kDeclFunctions, 1, | 318 kDeclFunctions, 1, |
314 kDeclFunctionLocals | kDeclFunctionExport | kDeclFunctionName, | 319 kDeclFunctionLocals | kDeclFunctionExport | kDeclFunctionName, |
315 SIG_INDEX(0), // signature index | 320 SIG_INDEX(0), // signature index |
316 NAME_OFFSET(9), // name offset | 321 NAME_OFFSET(9), // name offset |
317 U16(1466), // local int32 count | 322 U16_LE(1466), // local int32 count |
318 U16(1355), // local int64 count | 323 U16_LE(1355), // local int64 count |
319 U16(1244), // local float32 count | 324 U16_LE(1244), // local float32 count |
320 U16(1133), // local float64 count | 325 U16_LE(1133), // local float64 count |
321 1, 0, // size | 326 1, 0, // size |
322 kExprNop, | 327 kExprNop, |
323 }; | 328 }; |
324 | 329 |
325 { | 330 { |
326 // Should decode to exactly one function. | 331 // Should decode to exactly one function. |
327 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 332 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
328 EXPECT_TRUE(result.ok()); | 333 EXPECT_TRUE(result.ok()); |
329 EXPECT_EQ(0, result.val->globals->size()); | 334 EXPECT_EQ(0, result.val->globals->size()); |
330 EXPECT_EQ(1, result.val->signatures->size()); | 335 EXPECT_EQ(1, result.val->signatures->size()); |
(...skipping 11 matching lines...) Expand all Loading... |
342 EXPECT_EQ(1355, function->local_i64_count); | 347 EXPECT_EQ(1355, function->local_i64_count); |
343 EXPECT_EQ(1244, function->local_f32_count); | 348 EXPECT_EQ(1244, function->local_f32_count); |
344 EXPECT_EQ(1133, function->local_f64_count); | 349 EXPECT_EQ(1133, function->local_f64_count); |
345 | 350 |
346 EXPECT_TRUE(function->exported); | 351 EXPECT_TRUE(function->exported); |
347 EXPECT_FALSE(function->external); | 352 EXPECT_FALSE(function->external); |
348 | 353 |
349 if (result.val) delete result.val; | 354 if (result.val) delete result.val; |
350 } | 355 } |
351 | 356 |
352 for (size_t size = 5; size < arraysize(data); size++) { | 357 EXPECT_OFF_END_FAILURE(data, 5, sizeof(data)); |
353 // Should fall off end of module bytes. | |
354 ModuleResult result = DecodeModule(data, data + size); | |
355 EXPECT_FALSE(result.ok()); | |
356 if (result.val) delete result.val; | |
357 } | |
358 } | 358 } |
359 | 359 |
360 | 360 |
361 TEST_F(WasmModuleVerifyTest, OneFunctionImported) { | 361 TEST_F(WasmModuleVerifyTest, OneFunctionImported) { |
362 static const byte data[] = { | 362 static const byte data[] = { |
363 kDeclSignatures, 1, | 363 kDeclSignatures, 1, |
364 // sig#0 ------------------------------------------------------- | 364 // sig#0 ------------------------------------------------------- |
365 VOID_VOID_SIG, kDeclFunctions, 1, | 365 VOID_VOID_SIG, kDeclFunctions, 1, |
366 // func#0 ------------------------------------------------------ | 366 // func#0 ------------------------------------------------------ |
367 kDeclFunctionImport, // no name, no locals, imported | 367 kDeclFunctionImport, // no name, no locals, imported |
(...skipping 15 matching lines...) Expand all Loading... |
383 EXPECT_EQ(0, function->local_f64_count); | 383 EXPECT_EQ(0, function->local_f64_count); |
384 | 384 |
385 EXPECT_FALSE(function->exported); | 385 EXPECT_FALSE(function->exported); |
386 EXPECT_TRUE(function->external); | 386 EXPECT_TRUE(function->external); |
387 | 387 |
388 if (result.val) delete result.val; | 388 if (result.val) delete result.val; |
389 } | 389 } |
390 | 390 |
391 | 391 |
392 TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody) { | 392 TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody) { |
393 static const byte kCodeStartOffset = 11; | 393 static const byte kCodeStartOffset = 19; |
394 static const byte kCodeEndOffset = kCodeStartOffset + 1; | 394 static const byte kCodeEndOffset = kCodeStartOffset + 1; |
395 | 395 |
396 static const byte data[] = { | 396 static const byte data[] = { |
397 kDeclSignatures, 1, | 397 kDeclSignatures, 1, |
398 // sig#0 ------------------------------------------------------- | 398 // sig#0 ------------------------------------------------------- |
399 0, 0, // void -> void | 399 0, 0, // void -> void |
400 kDeclFunctions, 1, | 400 kDeclFunctions, 1, |
401 // func#0 ------------------------------------------------------ | 401 // func#0 ------------------------------------------------------ |
402 0, // no name, no locals | 402 0, // no name, no locals |
403 0, 0, // signature index | 403 0, 0, // signature index |
(...skipping 16 matching lines...) Expand all Loading... |
420 EXPECT_EQ(0, function->local_f64_count); | 420 EXPECT_EQ(0, function->local_f64_count); |
421 | 421 |
422 EXPECT_FALSE(function->exported); | 422 EXPECT_FALSE(function->exported); |
423 EXPECT_FALSE(function->external); | 423 EXPECT_FALSE(function->external); |
424 | 424 |
425 if (result.val) delete result.val; | 425 if (result.val) delete result.val; |
426 } | 426 } |
427 | 427 |
428 | 428 |
429 TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody_WithLocals) { | 429 TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody_WithLocals) { |
430 static const byte kCodeStartOffset = 19; | 430 static const byte kCodeStartOffset = 27; |
431 static const byte kCodeEndOffset = kCodeStartOffset + 1; | 431 static const byte kCodeEndOffset = kCodeStartOffset + 1; |
432 | 432 |
433 static const byte data[] = { | 433 static const byte data[] = { |
434 kDeclSignatures, 1, | 434 kDeclSignatures, 1, |
435 // sig#0 ------------------------------------------------------- | 435 // sig#0 ------------------------------------------------------- |
436 0, 0, // void -> void | 436 0, 0, // void -> void |
437 kDeclFunctions, 1, | 437 kDeclFunctions, 1, |
438 // func#0 ------------------------------------------------------ | 438 // func#0 ------------------------------------------------------ |
439 kDeclFunctionLocals, 0, 0, // signature index | 439 kDeclFunctionLocals, 0, 0, // signature index |
440 1, 2, // local int32 count | 440 1, 2, // local int32 count |
(...skipping 21 matching lines...) Expand all Loading... |
462 EXPECT_FALSE(function->exported); | 462 EXPECT_FALSE(function->exported); |
463 EXPECT_FALSE(function->external); | 463 EXPECT_FALSE(function->external); |
464 | 464 |
465 if (result.val) delete result.val; | 465 if (result.val) delete result.val; |
466 } | 466 } |
467 | 467 |
468 | 468 |
469 TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) { | 469 TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) { |
470 static const byte kDeclMemorySize = 4; | 470 static const byte kDeclMemorySize = 4; |
471 static const byte kCodeStartOffset = | 471 static const byte kCodeStartOffset = |
472 2 + kDeclMemorySize + kDeclGlobalSize + 4 + 2 + 17; | 472 8 + 2 + kDeclMemorySize + kDeclGlobalSize + 4 + 2 + 17; |
473 static const byte kCodeEndOffset = kCodeStartOffset + 3; | 473 static const byte kCodeEndOffset = kCodeStartOffset + 3; |
474 | 474 |
475 static const byte data[] = { | 475 static const byte data[] = { |
476 kDeclMemory, 28, 28, 1, | 476 kDeclMemory, 28, 28, 1, |
477 // global#0 -------------------------------------------------- | 477 // global#0 -------------------------------------------------- |
478 kDeclGlobals, 1, 0, 0, 0, 0, // name offset | 478 kDeclGlobals, 1, 0, 0, 0, 0, // name offset |
479 kMemU8, // memory type | 479 kMemU8, // memory type |
480 0, // exported | 480 0, // exported |
481 // sig#0 ----------------------------------------------------- | 481 // sig#0 ----------------------------------------------------- |
482 kDeclSignatures, 1, 0, 0, // void -> void | 482 kDeclSignatures, 1, 0, 0, // void -> void |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 WasmDataSegment* segment = &result.val->data_segments->back(); | 558 WasmDataSegment* segment = &result.val->data_segments->back(); |
559 | 559 |
560 EXPECT_EQ(0x9bbaa, segment->dest_addr); | 560 EXPECT_EQ(0x9bbaa, segment->dest_addr); |
561 EXPECT_EQ(11, segment->source_offset); | 561 EXPECT_EQ(11, segment->source_offset); |
562 EXPECT_EQ(3, segment->source_size); | 562 EXPECT_EQ(3, segment->source_size); |
563 EXPECT_TRUE(segment->init); | 563 EXPECT_TRUE(segment->init); |
564 | 564 |
565 if (result.val) delete result.val; | 565 if (result.val) delete result.val; |
566 } | 566 } |
567 | 567 |
568 for (size_t size = 5; size < arraysize(data); size++) { | 568 EXPECT_OFF_END_FAILURE(data, 5, sizeof(data)); |
569 // Should fall off end of module bytes. | |
570 ModuleResult result = DecodeModule(data, data + size); | |
571 EXPECT_FALSE(result.ok()); | |
572 if (result.val) delete result.val; | |
573 } | |
574 } | 569 } |
575 | 570 |
576 | 571 |
577 TEST_F(WasmModuleVerifyTest, TwoDataSegments) { | 572 TEST_F(WasmModuleVerifyTest, TwoDataSegments) { |
578 const byte data[] = { | 573 const byte data[] = { |
579 kDeclMemory, 28, 28, 1, kDeclDataSegments, 2, 0xee, 0xff, 0x07, | 574 kDeclMemory, 28, 28, 1, kDeclDataSegments, 2, 0xee, 0xff, 0x07, |
580 0, // dest addr | 575 0, // dest addr |
581 9, 0, 0, | 576 9, 0, 0, |
582 0, // #0: source offset | 577 0, // #0: source offset |
583 4, 0, 0, | 578 4, 0, 0, |
(...skipping 24 matching lines...) Expand all Loading... |
608 EXPECT_FALSE(s0->init); | 603 EXPECT_FALSE(s0->init); |
609 | 604 |
610 EXPECT_EQ(0x6ddcc, s1->dest_addr); | 605 EXPECT_EQ(0x6ddcc, s1->dest_addr); |
611 EXPECT_EQ(6, s1->source_offset); | 606 EXPECT_EQ(6, s1->source_offset); |
612 EXPECT_EQ(10, s1->source_size); | 607 EXPECT_EQ(10, s1->source_size); |
613 EXPECT_TRUE(s1->init); | 608 EXPECT_TRUE(s1->init); |
614 | 609 |
615 if (result.val) delete result.val; | 610 if (result.val) delete result.val; |
616 } | 611 } |
617 | 612 |
618 for (size_t size = 5; size < arraysize(data); size++) { | 613 EXPECT_OFF_END_FAILURE(data, 5, sizeof(data)); |
619 // Should fall off end of module bytes. | |
620 ModuleResult result = DecodeModule(data, data + size); | |
621 EXPECT_FALSE(result.ok()); | |
622 if (result.val) delete result.val; | |
623 } | |
624 } | 614 } |
625 | 615 |
626 | 616 |
627 TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidSource) { | 617 TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidSource) { |
628 const int dest_addr = 0x100; | 618 const int dest_addr = 0x100; |
629 const byte mem_size_log2 = 15; | 619 const byte mem_size_log2 = 15; |
| 620 const int kHeaderSize = 8; |
630 const int kDataSize = 19; | 621 const int kDataSize = 19; |
| 622 const int kTotalSize = kHeaderSize + kDataSize; |
631 | 623 |
632 for (int source_offset = 0; source_offset < 5 + kDataSize; source_offset++) { | 624 for (int source_offset = 0; source_offset < 5 + kDataSize; source_offset++) { |
633 for (int source_size = -1; source_size < 5 + kDataSize; source_size += 3) { | 625 for (int source_size = -1; source_size < 5 + kDataSize; source_size += 3) { |
634 byte data[] = { | 626 byte data[] = { |
635 kDeclMemory, | 627 kDeclMemory, |
636 mem_size_log2, | 628 mem_size_log2, |
637 mem_size_log2, | 629 mem_size_log2, |
638 1, | 630 1, |
639 kDeclDataSegments, | 631 kDeclDataSegments, |
640 1, | 632 1, |
641 U32(dest_addr), | 633 U32_LE(dest_addr), |
642 U32(source_offset), | 634 U32_LE(source_offset), |
643 U32(source_size), | 635 U32_LE(source_size), |
644 1, // init | 636 1, // init |
645 }; | 637 }; |
646 | 638 |
647 STATIC_ASSERT(kDataSize == arraysize(data)); | 639 STATIC_ASSERT(kDataSize == arraysize(data)); |
648 | 640 |
649 if (source_offset < kDataSize && source_size >= 0 && | 641 if (source_offset < kTotalSize && source_size >= 0 && |
650 (source_offset + source_size) <= kDataSize) { | 642 (source_offset + source_size) <= kTotalSize) { |
651 EXPECT_VERIFIES(data); | 643 EXPECT_VERIFIES(data); |
652 } else { | 644 } else { |
653 EXPECT_FAILURE(data); | 645 EXPECT_FAILURE(data); |
654 } | 646 } |
655 } | 647 } |
656 } | 648 } |
657 } | 649 } |
658 | 650 |
659 | 651 |
660 TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidDest) { | 652 TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidDest) { |
661 const int source_size = 3; | 653 const int source_size = 3; |
662 const int source_offset = 11; | 654 const int source_offset = 11; |
663 | 655 |
664 for (byte mem_size_log2 = 12; mem_size_log2 < 20; mem_size_log2++) { | 656 for (byte mem_size_log2 = 12; mem_size_log2 < 20; mem_size_log2++) { |
665 int mem_size = 1 << mem_size_log2; | 657 int mem_size = 1 << mem_size_log2; |
666 | 658 |
667 for (int dest_addr = mem_size - source_size; | 659 for (int dest_addr = mem_size - source_size; |
668 dest_addr < mem_size + source_size; dest_addr++) { | 660 dest_addr < mem_size + source_size; dest_addr++) { |
669 byte data[] = { | 661 byte data[] = { |
670 kDeclMemory, | 662 kDeclMemory, |
671 mem_size_log2, | 663 mem_size_log2, |
672 mem_size_log2, | 664 mem_size_log2, |
673 1, | 665 1, |
674 kDeclDataSegments, | 666 kDeclDataSegments, |
675 1, | 667 1, |
676 U32(dest_addr), | 668 U32_LE(dest_addr), |
677 U32(source_offset), | 669 U32_LE(source_offset), |
678 U32(source_size), | 670 U32_LE(source_size), |
679 1, // init | 671 1, // init |
680 }; | 672 }; |
681 | 673 |
682 if (dest_addr <= (mem_size - source_size)) { | 674 if (dest_addr <= (mem_size - source_size)) { |
683 EXPECT_VERIFIES(data); | 675 EXPECT_VERIFIES(data); |
684 } else { | 676 } else { |
685 EXPECT_FAILURE(data); | 677 EXPECT_FAILURE(data); |
686 } | 678 } |
687 } | 679 } |
688 } | 680 } |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1036 } | 1028 } |
1037 | 1029 |
1038 TEST_F(WasmModuleVerifyTest, ImportTable_off_end) { | 1030 TEST_F(WasmModuleVerifyTest, ImportTable_off_end) { |
1039 static const byte data[] = { | 1031 static const byte data[] = { |
1040 kDeclSignatures, 1, VOID_VOID_SIG, kDeclImportTable, 1, | 1032 kDeclSignatures, 1, VOID_VOID_SIG, kDeclImportTable, 1, |
1041 SIG_INDEX(0), // sig index | 1033 SIG_INDEX(0), // sig index |
1042 NAME_OFFSET(1), // module name | 1034 NAME_OFFSET(1), // module name |
1043 NAME_OFFSET(1), // function name | 1035 NAME_OFFSET(1), // function name |
1044 }; | 1036 }; |
1045 | 1037 |
1046 for (size_t length = 5; length < sizeof(data); length++) { | 1038 EXPECT_OFF_END_FAILURE(data, 5, sizeof(data)); |
1047 ModuleResult result = DecodeModule(data, data + length); | |
1048 EXPECT_FALSE(result.ok()); | |
1049 if (result.val) delete result.val; | |
1050 } | |
1051 } | 1039 } |
1052 | 1040 |
1053 TEST_F(WasmModuleVerifyTest, ExportTable_empty) { | 1041 TEST_F(WasmModuleVerifyTest, ExportTable_empty) { |
1054 static const byte data[] = {kDeclSignatures, 0, kDeclFunctions, 0, | 1042 static const byte data[] = {kDeclSignatures, 0, kDeclFunctions, 0, |
1055 kDeclExportTable, 0}; | 1043 kDeclExportTable, 0}; |
1056 EXPECT_VERIFIES(data); | 1044 EXPECT_VERIFIES(data); |
1057 } | 1045 } |
1058 | 1046 |
1059 TEST_F(WasmModuleVerifyTest, ExportTable_NoFunctions1) { | 1047 TEST_F(WasmModuleVerifyTest, ExportTable_NoFunctions1) { |
1060 static const byte data[] = {kDeclSignatures, 0, kDeclExportTable, 0}; | 1048 static const byte data[] = {kDeclSignatures, 0, kDeclExportTable, 0}; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 for (int length = 13; length < sizeof(data); length++) { | 1137 for (int length = 13; length < sizeof(data); length++) { |
1150 ModuleResult result = DecodeModule(data, data + length); | 1138 ModuleResult result = DecodeModule(data, data + length); |
1151 EXPECT_FALSE(result.ok()); | 1139 EXPECT_FALSE(result.ok()); |
1152 if (result.val) delete result.val; | 1140 if (result.val) delete result.val; |
1153 } | 1141 } |
1154 } | 1142 } |
1155 | 1143 |
1156 } // namespace wasm | 1144 } // namespace wasm |
1157 } // namespace internal | 1145 } // namespace internal |
1158 } // namespace v8 | 1146 } // namespace v8 |
OLD | NEW |