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 3// found in the LICENSE file. 4 5#include "test/unittests/test-utils.h" 6 7#include "src/handles.h" 8#include "src/objects-inl.h" 9#include "src/wasm/module-decoder.h" 10#include "src/wasm/wasm-macro-gen.h" 11#include "src/wasm/wasm-opcodes.h" 12 13namespace v8 { 14namespace internal { 15namespace wasm { 16 17#define EMPTY_FUNCTION(sig_index) 0, SIG_INDEX(sig_index), U16_LE(0) 18#define SIZEOF_EMPTY_FUNCTION ((size_t)5) 19#define EMPTY_BODY 0 20#define SIZEOF_EMPTY_BODY ((size_t)1) 21#define NOP_BODY 2, 0, kExprNop 22#define SIZEOF_NOP_BODY ((size_t)3) 23 24#define SIG_ENTRY_i_i SIG_ENTRY_x_x(kLocalI32, kLocalI32) 25 26#define UNKNOWN_EMPTY_SECTION_NAME 1, '\0' 27#define UNKNOWN_SECTION_NAME 4, 'l', 'u', 'l', 'z' 28 29#define SECTION(NAME, EXTRA_SIZE) WASM_SECTION_##NAME, U32V_1(EXTRA_SIZE) 30 31#define SIGNATURES_SECTION(count, ...) \ 32 SECTION(SIGNATURES, 1 + 3 * (count)), U32V_1(count), __VA_ARGS__ 33#define FUNCTION_SIGNATURES_SECTION(count, ...) \ 34 SECTION(FUNCTION_SIGNATURES, 1 + (count)), U32V_1(count), __VA_ARGS__ 35 36#define FOO_STRING 3, 'f', 'o', 'o' 37#define NO_LOCAL_NAMES 0 38 39#define EMPTY_SIGNATURES_SECTION SECTION(SIGNATURES, 1), 0 40#define EMPTY_FUNCTION_SIGNATURES_SECTION SECTION(FUNCTION_SIGNATURES, 1), 0 41#define EMPTY_FUNCTION_BODIES_SECTION SECTION(FUNCTION_BODIES, 1), 0 42#define EMPTY_NAMES_SECTION SECTION(NAMES, 1), 0 43 44#define X1(...) __VA_ARGS__ 45#define X2(...) __VA_ARGS__, __VA_ARGS__ 46#define X3(...) __VA_ARGS__, __VA_ARGS__, __VA_ARGS__ 47#define X4(...) __VA_ARGS__, __VA_ARGS__, __VA_ARGS__, __VA_ARGS__ 48 49#define ONE_EMPTY_FUNCTION WASM_SECTION_FUNCTION_SIGNATURES, 1 + 1 * 1, 1, X1(0) 50 51#define TWO_EMPTY_FUNCTIONS \ 52 WASM_SECTION_FUNCTION_SIGNATURES, 1 + 2 * 1, 2, X2(0) 53 54#define THREE_EMPTY_FUNCTIONS \ 55 WASM_SECTION_FUNCTION_SIGNATURES, 1 + 3 * 1, 3, X3(0) 56 57#define FOUR_EMPTY_FUNCTIONS \ 58 WASM_SECTION_FUNCTION_SIGNATURES, 1 + 4 * 1, 4, X4(0) 59 60#define ONE_EMPTY_BODY \ 61 WASM_SECTION_FUNCTION_BODIES, 1 + 1 * (1 + SIZEOF_EMPTY_BODY), 1, \ 62 X1(SIZEOF_EMPTY_BODY, EMPTY_BODY) 63 64#define TWO_EMPTY_BODIES \ 65 WASM_SECTION_FUNCTION_BODIES, 1 + 2 * (1 + SIZEOF_EMPTY_BODY), 2, \ 66 X2(SIZEOF_EMPTY_BODY, EMPTY_BODY) 67 68#define THREE_EMPTY_BODIES \ 69 WASM_SECTION_FUNCTION_BODIES, 1 + 3 * (1 + SIZEOF_EMPTY_BODY), 3, \ 70 X3(SIZEOF_EMPTY_BODY, EMPTY_BODY) 71 72#define FOUR_EMPTY_BODIES \ 73 WASM_SECTION_FUNCTION_BODIES, 1 + 4 * (1 + SIZEOF_EMPTY_BODY), 4, \ 74 X4(SIZEOF_EMPTY_BODY, EMPTY_BODY) 75 76#define SIGNATURES_SECTION_VOID_VOID \ 77 SECTION(SIGNATURES, 1 + SIZEOF_SIG_ENTRY_v_v), 1, SIG_ENTRY_v_v 78 79#define EXPECT_VERIFIES(data) \ 80 do { \ 81 ModuleResult result = DecodeModule(data, data + arraysize(data)); \ 82 EXPECT_TRUE(result.ok()); \ 83 if (result.val) delete result.val; \ 84 } while (false) 85 86#define EXPECT_FAILURE_LEN(data, length) \ 87 do { \ 88 ModuleResult result = DecodeModule(data, data + length); \ 89 EXPECT_FALSE(result.ok()); \ 90 if (result.val) delete result.val; \ 91 } while (false) 92 93#define EXPECT_FAILURE(data) EXPECT_FAILURE_LEN(data, sizeof(data)) 94 95#define EXPECT_OFF_END_FAILURE(data, min, max) \ 96 do { \ 97 for (size_t length = min; length < max; length++) { \ 98 EXPECT_FAILURE_LEN(data, length); \ 99 } \ 100 } while (false) 101 102#define EXPECT_OK(result) \ 103 do { \ 104 EXPECT_TRUE(result.ok()); \ 105 if (!result.ok()) { \ 106 if (result.val) delete result.val; \ 107 return; \ 108 } \ 109 } while (false) 110 111static size_t SizeOfVarInt(size_t value) { 112 size_t size = 0; 113 do { 114 size++; 115 value = value >> 7; 116 } while (value > 0); 117 return size; 118} 119 120struct LocalTypePair { 121 uint8_t code; 122 LocalType type; 123} kLocalTypes[] = {{kLocalI32, kAstI32}, 124 {kLocalI64, kAstI64}, 125 {kLocalF32, kAstF32}, 126 {kLocalF64, kAstF64}}; 127 128class WasmModuleVerifyTest : public TestWithIsolateAndZone { 129 public: 130 ModuleResult DecodeModule(const byte* module_start, const byte* module_end) { 131 // Add the WASM magic and version number automatically. 132 size_t size = static_cast<size_t>(module_end - module_start); 133 byte header[] = {WASM_MODULE_HEADER}; 134 size_t total = sizeof(header) + size; 135 auto temp = new byte[total]; 136 memcpy(temp, header, sizeof(header)); 137 memcpy(temp + sizeof(header), module_start, size); 138 ModuleResult result = DecodeWasmModule(isolate(), zone(), temp, 139 temp + total, false, kWasmOrigin); 140 delete[] temp; 141 return result; 142 } 143 ModuleResult DecodeModuleNoHeader(const byte* module_start, 144 const byte* module_end) { 145 return DecodeWasmModule(isolate(), zone(), module_start, module_end, false, 146 kWasmOrigin); 147 } 148}; 149 150TEST_F(WasmModuleVerifyTest, WrongMagic) { 151 for (uint32_t x = 1; x; x <<= 1) { 152 const byte data[] = {U32_LE(kWasmMagic ^ x), U32_LE(kWasmVersion), 153 SECTION(END, 0)}; 154 ModuleResult result = DecodeModuleNoHeader(data, data + sizeof(data)); 155 EXPECT_FALSE(result.ok()); 156 if (result.val) delete result.val; 157 } 158} 159 160TEST_F(WasmModuleVerifyTest, WrongVersion) { 161 for (uint32_t x = 1; x; x <<= 1) { 162 const byte data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion ^ x), 163 SECTION(END, 0)}; 164 ModuleResult result = DecodeModuleNoHeader(data, data + sizeof(data)); 165 EXPECT_FALSE(result.ok()); 166 if (result.val) delete result.val; 167 } 168} 169 170TEST_F(WasmModuleVerifyTest, DecodeEmpty) { 171 static const byte data[] = {SECTION(END, 0)}; 172 EXPECT_VERIFIES(data); 173} 174 175TEST_F(WasmModuleVerifyTest, OneGlobal) { 176 static const byte data[] = { 177 SECTION(GLOBALS, 5), // -- 178 1, 179 NAME_LENGTH(1), 180 'g', // name 181 kMemI32, // memory type 182 0, // exported 183 }; 184 185 { 186 // Should decode to exactly one global. 187 ModuleResult result = DecodeModule(data, data + arraysize(data)); 188 EXPECT_OK(result); 189 EXPECT_EQ(1, result.val->globals.size()); 190 EXPECT_EQ(0, result.val->functions.size()); 191 EXPECT_EQ(0, result.val->data_segments.size()); 192 193 const WasmGlobal* global = &result.val->globals.back(); 194 195 EXPECT_EQ(1, global->name_length); 196 EXPECT_EQ(MachineType::Int32(), global->type); 197 EXPECT_EQ(0, global->offset); 198 EXPECT_FALSE(global->exported); 199 200 if (result.val) delete result.val; 201 } 202 203 EXPECT_OFF_END_FAILURE(data, 1, sizeof(data)); 204} 205 206TEST_F(WasmModuleVerifyTest, Global_invalid_type) { 207 static const byte data[] = { 208 SECTION(GLOBALS, 5), // -- 209 1, 210 NAME_LENGTH(1), 211 'g', // name 212 64, // invalid memory type 213 0, // exported 214 }; 215 216 ModuleResult result = DecodeModuleNoHeader(data, data + sizeof(data)); 217 EXPECT_FALSE(result.ok()); 218 if (result.val) delete result.val; 219} 220 221TEST_F(WasmModuleVerifyTest, ZeroGlobals) { 222 static const byte data[] = { 223 SECTION(GLOBALS, 1), // -- 224 0, // declare 0 globals 225 }; 226 ModuleResult result = DecodeModule(data, data + arraysize(data)); 227 EXPECT_OK(result); 228 if (result.val) delete result.val; 229} 230 231static void AppendUint32v(std::vector<byte>& buffer, uint32_t val) { 232 while (true) { 233 uint32_t next = val >> 7; 234 uint32_t out = val & 0x7f; 235 if (next) { 236 buffer.push_back(static_cast<byte>(0x80 | out)); 237 val = next; 238 } else { 239 buffer.push_back(static_cast<byte>(out)); 240 break; 241 } 242 } 243} 244 245TEST_F(WasmModuleVerifyTest, NGlobals) { 246 static const byte data[] = { 247 NO_NAME, // name length 248 kMemI32, // memory type 249 0, // exported 250 }; 251 252 for (uint32_t i = 0; i < 1000000; i = i * 13 + 1) { 253 std::vector<byte> buffer; 254 size_t size = SizeOfVarInt(i) + i * sizeof(data); 255 const byte globals[] = {WASM_SECTION_GLOBALS, U32V_5(size)}; 256 for (size_t g = 0; g != sizeof(globals); ++g) { 257 buffer.push_back(globals[g]); 258 } 259 AppendUint32v(buffer, i); // Number of globals. 260 for (uint32_t j = 0; j < i; j++) { 261 buffer.insert(buffer.end(), data, data + sizeof(data)); 262 } 263 264 ModuleResult result = DecodeModule(&buffer[0], &buffer[0] + buffer.size()); 265 EXPECT_OK(result); 266 if (result.val) delete result.val; 267 } 268} 269 270TEST_F(WasmModuleVerifyTest, GlobalWithInvalidNameOffset) { 271 static const byte data[] = { 272 SECTION(GLOBALS, 7), 273 1, // declare one global 274 NO_NAME, // name offset 275 33, // memory type 276 0, // exported 277 }; 278 279 EXPECT_FAILURE(data); 280} 281 282TEST_F(WasmModuleVerifyTest, GlobalWithInvalidMemoryType) { 283 static const byte data[] = { 284 SECTION(GLOBALS, 7), 285 1, // declare one global 286 NO_NAME, // name offset 287 33, // memory type 288 0, // exported 289 }; 290 291 EXPECT_FAILURE(data); 292} 293 294TEST_F(WasmModuleVerifyTest, TwoGlobals) { 295 static const byte data[] = { 296 SECTION(GLOBALS, 7), 297 2, 298 NO_NAME, // #0: name length 299 kMemF32, // memory type 300 0, // exported 301 NO_NAME, // #1: name length 302 kMemF64, // memory type 303 1, // exported 304 }; 305 306 { 307 // Should decode to exactly two globals. 308 ModuleResult result = DecodeModule(data, data + arraysize(data)); 309 EXPECT_OK(result); 310 EXPECT_EQ(2, result.val->globals.size()); 311 EXPECT_EQ(0, result.val->functions.size()); 312 EXPECT_EQ(0, result.val->data_segments.size()); 313 314 const WasmGlobal* g0 = &result.val->globals[0]; 315 const WasmGlobal* g1 = &result.val->globals[1]; 316 317 EXPECT_EQ(0, g0->name_length); 318 EXPECT_EQ(MachineType::Float32(), g0->type); 319 EXPECT_EQ(0, g0->offset); 320 EXPECT_FALSE(g0->exported); 321 322 EXPECT_EQ(0, g1->name_length); 323 EXPECT_EQ(MachineType::Float64(), g1->type); 324 EXPECT_EQ(8, g1->offset); 325 EXPECT_TRUE(g1->exported); 326 327 if (result.val) delete result.val; 328 } 329 330 EXPECT_OFF_END_FAILURE(data, 1, sizeof(data)); 331} 332 333TEST_F(WasmModuleVerifyTest, OneSignature) { 334 { 335 static const byte data[] = {SIGNATURES_SECTION_VOID_VOID}; 336 EXPECT_VERIFIES(data); 337 } 338 339 { 340 static const byte data[] = {SECTION(SIGNATURES, 1 + SIZEOF_SIG_ENTRY_x_x), 341 1, SIG_ENTRY_i_i}; 342 EXPECT_VERIFIES(data); 343 } 344} 345 346TEST_F(WasmModuleVerifyTest, MultipleSignatures) { 347 static const byte data[] = { 348 SECTION(SIGNATURES, 1 + SIZEOF_SIG_ENTRY_v_v + SIZEOF_SIG_ENTRY_x_x + 349 SIZEOF_SIG_ENTRY_x_xx), // -- 350 3, // -- 351 SIG_ENTRY_v_v, // void -> void 352 SIG_ENTRY_x_x(kLocalI32, kLocalF32), // f32 -> i32 353 SIG_ENTRY_x_xx(kLocalI32, kLocalF64, kLocalF64), // f64,f64 -> i32 354 }; 355 356 ModuleResult result = DecodeModule(data, data + arraysize(data)); 357 EXPECT_OK(result); 358 EXPECT_EQ(3, result.val->signatures.size()); 359 if (result.val->signatures.size() == 3) { 360 EXPECT_EQ(0, result.val->signatures[0]->return_count()); 361 EXPECT_EQ(1, result.val->signatures[1]->return_count()); 362 EXPECT_EQ(1, result.val->signatures[2]->return_count()); 363 364 EXPECT_EQ(0, result.val->signatures[0]->parameter_count()); 365 EXPECT_EQ(1, result.val->signatures[1]->parameter_count()); 366 EXPECT_EQ(2, result.val->signatures[2]->parameter_count()); 367 } 368 if (result.val) delete result.val; 369 370 EXPECT_OFF_END_FAILURE(data, 1, sizeof(data)); 371} 372 373TEST_F(WasmModuleVerifyTest, OneDataSegment) { 374 const byte kDataSegmentSourceOffset = 30; 375 const byte data[] = { 376 SECTION(MEMORY, 3), 377 28, 378 28, 379 1, 380 SECTION(DATA_SEGMENTS, 8), 381 1, 382 U32V_3(0x9bbaa), // dest addr 383 U32V_1(3), // source size 384 'a', 385 'b', 386 'c' // data bytes 387 }; 388 389 { 390 EXPECT_VERIFIES(data); 391 ModuleResult result = DecodeModule(data, data + arraysize(data)); 392 EXPECT_OK(result); 393 EXPECT_EQ(0, result.val->globals.size()); 394 EXPECT_EQ(0, result.val->functions.size()); 395 EXPECT_EQ(1, result.val->data_segments.size()); 396 397 const WasmDataSegment* segment = &result.val->data_segments.back(); 398 399 EXPECT_EQ(0x9bbaa, segment->dest_addr); 400 EXPECT_EQ(kDataSegmentSourceOffset, segment->source_offset); 401 EXPECT_EQ(3, segment->source_size); 402 EXPECT_TRUE(segment->init); 403 404 if (result.val) delete result.val; 405 } 406 407 EXPECT_OFF_END_FAILURE(data, 13, sizeof(data)); 408} 409 410TEST_F(WasmModuleVerifyTest, TwoDataSegments) { 411 const byte kDataSegment0SourceOffset = 30; 412 const byte kDataSegment1SourceOffset = 30 + 8; 413 414 const byte data[] = { 415 SECTION(MEMORY, 3), 416 28, 417 28, 418 1, 419 SECTION(DATA_SEGMENTS, 23), 420 2, // segment count 421 U32V_3(0x7ffee), // #0: dest addr 422 U32V_1(4), // source size 423 1, 424 2, 425 3, 426 4, // data bytes 427 U32V_3(0x6ddcc), // #1: dest addr 428 U32V_1(10), // source size 429 1, 430 2, 431 3, 432 4, 433 5, 434 6, 435 7, 436 8, 437 9, 438 10 // data bytes 439 }; 440 441 { 442 ModuleResult result = DecodeModule(data, data + arraysize(data)); 443 EXPECT_OK(result); 444 EXPECT_EQ(0, result.val->globals.size()); 445 EXPECT_EQ(0, result.val->functions.size()); 446 EXPECT_EQ(2, result.val->data_segments.size()); 447 448 const WasmDataSegment* s0 = &result.val->data_segments[0]; 449 const WasmDataSegment* s1 = &result.val->data_segments[1]; 450 451 EXPECT_EQ(0x7ffee, s0->dest_addr); 452 EXPECT_EQ(kDataSegment0SourceOffset, s0->source_offset); 453 EXPECT_EQ(4, s0->source_size); 454 EXPECT_TRUE(s0->init); 455 456 EXPECT_EQ(0x6ddcc, s1->dest_addr); 457 EXPECT_EQ(kDataSegment1SourceOffset, s1->source_offset); 458 EXPECT_EQ(10, s1->source_size); 459 EXPECT_TRUE(s1->init); 460 461 if (result.val) delete result.val; 462 } 463 464 EXPECT_OFF_END_FAILURE(data, 13, sizeof(data)); 465} 466 467TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidDest) { 468 const int source_size = 3; 469 470 for (byte mem_pages = 1; mem_pages < 16; mem_pages++) { 471 int mem_size = mem_pages * 0x10000; // 64k pages. 472 473 for (int dest_addr = mem_size - source_size; 474 dest_addr < mem_size + source_size; dest_addr++) { 475 byte data[] = {SECTION(MEMORY, 3), 476 mem_pages, 477 mem_pages, 478 1, 479 SECTION(DATA_SEGMENTS, 8), 480 1, 481 U32V_3(dest_addr), 482 U32V_1(source_size), 483 'a', 484 'b', 485 'c'}; 486 487 if (dest_addr <= (mem_size - source_size)) { 488 EXPECT_VERIFIES(data); 489 } else { 490 EXPECT_FAILURE(data); 491 } 492 } 493 } 494} 495 496TEST_F(WasmModuleVerifyTest, OneIndirectFunction) { 497 static const byte data[] = { 498 // sig#0 ------------------------------------------------------- 499 SIGNATURES_SECTION_VOID_VOID, 500 // funcs ------------------------------------------------------ 501 ONE_EMPTY_FUNCTION, 502 // indirect table ---------------------------------------------- 503 SECTION(FUNCTION_TABLE, 2), 1, U32V_1(0)}; 504 505 ModuleResult result = DecodeModule(data, data + arraysize(data)); 506 EXPECT_OK(result); 507 if (result.ok()) { 508 EXPECT_EQ(1, result.val->signatures.size()); 509 EXPECT_EQ(1, result.val->functions.size()); 510 EXPECT_EQ(1, result.val->function_table.size()); 511 EXPECT_EQ(0, result.val->function_table[0]); 512 } 513 if (result.val) delete result.val; 514} 515 516TEST_F(WasmModuleVerifyTest, MultipleIndirectFunctions) { 517 static const byte data[] = { 518 // sig#0 ------------------------------------------------------- 519 SECTION(SIGNATURES, 1 + SIZEOF_SIG_ENTRY_v_v + SIZEOF_SIG_ENTRY_v_x), 520 2, // -- 521 SIG_ENTRY_v_v, // void -> void 522 SIG_ENTRY_v_x(kLocalI32), // void -> i32 523 // funcs ------------------------------------------------------ 524 FOUR_EMPTY_FUNCTIONS, 525 // indirect table ---------------------------------------------- 526 SECTION(FUNCTION_TABLE, 9), 8, 527 U32V_1(0), // -- 528 U32V_1(1), // -- 529 U32V_1(2), // -- 530 U32V_1(3), // -- 531 U32V_1(0), // -- 532 U32V_1(1), // -- 533 U32V_1(2), // -- 534 U32V_1(3), // -- 535 FOUR_EMPTY_BODIES}; 536 537 ModuleResult result = DecodeModule(data, data + arraysize(data)); 538 EXPECT_OK(result); 539 if (result.ok()) { 540 EXPECT_EQ(2, result.val->signatures.size()); 541 EXPECT_EQ(4, result.val->functions.size()); 542 EXPECT_EQ(8, result.val->function_table.size()); 543 for (int i = 0; i < 8; i++) { 544 EXPECT_EQ(i & 3, result.val->function_table[i]); 545 } 546 } 547 if (result.val) delete result.val; 548} 549 550TEST_F(WasmModuleVerifyTest, IndirectFunctionNoFunctions) { 551 static const byte data[] = { 552 // sig#0 ------------------------------------------------------- 553 SIGNATURES_SECTION_VOID_VOID, 554 // indirect table ---------------------------------------------- 555 SECTION(FUNCTION_TABLE, 3), 1, 0, 0, 556 }; 557 558 EXPECT_FAILURE(data); 559} 560 561TEST_F(WasmModuleVerifyTest, IndirectFunctionInvalidIndex) { 562 static const byte data[] = { 563 // sig#0 ------------------------------------------------------- 564 SIGNATURES_SECTION_VOID_VOID, 565 // functions --------------------------------------------------- 566 ONE_EMPTY_FUNCTION, 567 // indirect table ---------------------------------------------- 568 SECTION(FUNCTION_TABLE, 3), 1, 1, 0, 569 }; 570 571 EXPECT_FAILURE(data); 572} 573 574class WasmSignatureDecodeTest : public TestWithZone {}; 575 576TEST_F(WasmSignatureDecodeTest, Ok_v_v) { 577 static const byte data[] = {SIG_ENTRY_v_v}; 578 base::AccountingAllocator allocator; 579 Zone zone(&allocator); 580 FunctionSig* sig = 581 DecodeWasmSignatureForTesting(&zone, data, data + arraysize(data)); 582 583 EXPECT_TRUE(sig != nullptr); 584 EXPECT_EQ(0, sig->parameter_count()); 585 EXPECT_EQ(0, sig->return_count()); 586} 587 588TEST_F(WasmSignatureDecodeTest, Ok_t_v) { 589 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { 590 LocalTypePair ret_type = kLocalTypes[i]; 591 const byte data[] = {SIG_ENTRY_x(ret_type.code)}; 592 FunctionSig* sig = 593 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data)); 594 595 EXPECT_TRUE(sig != nullptr); 596 EXPECT_EQ(0, sig->parameter_count()); 597 EXPECT_EQ(1, sig->return_count()); 598 EXPECT_EQ(ret_type.type, sig->GetReturn()); 599 } 600} 601 602TEST_F(WasmSignatureDecodeTest, Ok_v_t) { 603 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { 604 LocalTypePair param_type = kLocalTypes[i]; 605 const byte data[] = {SIG_ENTRY_v_x(param_type.code)}; 606 FunctionSig* sig = 607 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data)); 608 609 EXPECT_TRUE(sig != nullptr); 610 EXPECT_EQ(1, sig->parameter_count()); 611 EXPECT_EQ(0, sig->return_count()); 612 EXPECT_EQ(param_type.type, sig->GetParam(0)); 613 } 614} 615 616TEST_F(WasmSignatureDecodeTest, Ok_t_t) { 617 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { 618 LocalTypePair ret_type = kLocalTypes[i]; 619 for (size_t j = 0; j < arraysize(kLocalTypes); j++) { 620 LocalTypePair param_type = kLocalTypes[j]; 621 const byte data[] = {SIG_ENTRY_x_x(ret_type.code, param_type.code)}; 622 FunctionSig* sig = 623 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data)); 624 625 EXPECT_TRUE(sig != nullptr); 626 EXPECT_EQ(1, sig->parameter_count()); 627 EXPECT_EQ(1, sig->return_count()); 628 EXPECT_EQ(param_type.type, sig->GetParam(0)); 629 EXPECT_EQ(ret_type.type, sig->GetReturn()); 630 } 631 } 632} 633 634TEST_F(WasmSignatureDecodeTest, Ok_i_tt) { 635 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { 636 LocalTypePair p0_type = kLocalTypes[i]; 637 for (size_t j = 0; j < arraysize(kLocalTypes); j++) { 638 LocalTypePair p1_type = kLocalTypes[j]; 639 const byte data[] = { 640 SIG_ENTRY_x_xx(kLocalI32, p0_type.code, p1_type.code)}; 641 FunctionSig* sig = 642 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data)); 643 644 EXPECT_TRUE(sig != nullptr); 645 EXPECT_EQ(2, sig->parameter_count()); 646 EXPECT_EQ(1, sig->return_count()); 647 EXPECT_EQ(p0_type.type, sig->GetParam(0)); 648 EXPECT_EQ(p1_type.type, sig->GetParam(1)); 649 } 650 } 651} 652 653TEST_F(WasmSignatureDecodeTest, Fail_off_end) { 654 byte data[256]; 655 for (int p = 0; p <= 255; p = p + 1 + p * 3) { 656 for (int i = 0; i <= p; i++) data[i] = kLocalI32; 657 data[0] = static_cast<byte>(p); 658 659 for (int i = 0; i < p + 1; i++) { 660 // Should fall off the end for all signatures. 661 FunctionSig* sig = DecodeWasmSignatureForTesting(zone(), data, data + i); 662 EXPECT_EQ(nullptr, sig); 663 } 664 } 665} 666 667TEST_F(WasmSignatureDecodeTest, Fail_invalid_type) { 668 byte kInvalidType = 76; 669 for (size_t i = 0; i < SIZEOF_SIG_ENTRY_x_xx; i++) { 670 byte data[] = {SIG_ENTRY_x_xx(kLocalI32, kLocalI32, kLocalI32)}; 671 data[i] = kInvalidType; 672 FunctionSig* sig = 673 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data)); 674 EXPECT_EQ(nullptr, sig); 675 } 676} 677 678TEST_F(WasmSignatureDecodeTest, Fail_invalid_ret_type1) { 679 static const byte data[] = {SIG_ENTRY_x_x(kLocalVoid, kLocalI32)}; 680 FunctionSig* sig = 681 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data)); 682 EXPECT_EQ(nullptr, sig); 683} 684 685TEST_F(WasmSignatureDecodeTest, Fail_invalid_param_type1) { 686 static const byte data[] = {SIG_ENTRY_x_x(kLocalI32, kLocalVoid)}; 687 FunctionSig* sig = 688 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data)); 689 EXPECT_EQ(nullptr, sig); 690} 691 692TEST_F(WasmSignatureDecodeTest, Fail_invalid_param_type2) { 693 static const byte data[] = {SIG_ENTRY_x_xx(kLocalI32, kLocalI32, kLocalVoid)}; 694 FunctionSig* sig = 695 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data)); 696 EXPECT_EQ(nullptr, sig); 697} 698 699class WasmFunctionVerifyTest : public TestWithIsolateAndZone {}; 700 701TEST_F(WasmFunctionVerifyTest, Ok_v_v_empty) { 702 static const byte data[] = { 703 SIG_ENTRY_v_v, // signature entry 704 4, // locals 705 3, 706 kLocalI32, // -- 707 4, 708 kLocalI64, // -- 709 5, 710 kLocalF32, // -- 711 6, 712 kLocalF64, // -- 713 kExprNop // body 714 }; 715 716 FunctionResult result = DecodeWasmFunction(isolate(), zone(), nullptr, data, 717 data + arraysize(data)); 718 EXPECT_OK(result); 719 720 if (result.val && result.ok()) { 721 WasmFunction* function = result.val; 722 EXPECT_EQ(0, function->sig->parameter_count()); 723 EXPECT_EQ(0, function->sig->return_count()); 724 EXPECT_EQ(0, function->name_offset); 725 EXPECT_EQ(SIZEOF_SIG_ENTRY_v_v, function->code_start_offset); 726 EXPECT_EQ(arraysize(data), function->code_end_offset); 727 // TODO(titzer): verify encoding of local declarations 728 } 729 730 if (result.val) delete result.val; 731} 732 733TEST_F(WasmModuleVerifyTest, SectionWithoutNameLength) { 734 const byte data[] = {1}; 735 EXPECT_FAILURE(data); 736} 737 738TEST_F(WasmModuleVerifyTest, TheLoneliestOfValidModulesTheTrulyEmptyOne) { 739 const byte data[] = { 740 0, // Empty section name. 741 // No section name, no content, nothing but sadness. 742 0, // No section content. 743 }; 744 EXPECT_VERIFIES(data); 745} 746 747TEST_F(WasmModuleVerifyTest, OnlyUnknownSectionEmpty) { 748 const byte data[] = { 749 UNKNOWN_SECTION_NAME, 0, 750 }; 751 EXPECT_VERIFIES(data); 752} 753 754TEST_F(WasmModuleVerifyTest, OnlyUnknownSectionNonEmpty) { 755 const byte data[] = { 756 UNKNOWN_SECTION_NAME, 757 5, // section size 758 0xff, 759 0xff, 760 0xff, 761 0xff, 762 0xff, // section data 763 }; 764 EXPECT_VERIFIES(data); 765} 766 767TEST_F(WasmModuleVerifyTest, SignatureFollowedByEmptyUnknownSection) { 768 const byte data[] = { 769 // signatures 770 SIGNATURES_SECTION_VOID_VOID, 771 // ----------------------------------------------------------- 772 UNKNOWN_SECTION_NAME, 773 0 // empty section 774 }; 775 EXPECT_VERIFIES(data); 776} 777 778TEST_F(WasmModuleVerifyTest, SignatureFollowedByUnknownSection) { 779 const byte data[] = { 780 // signatures 781 SIGNATURES_SECTION_VOID_VOID, 782 // ----------------------------------------------------------- 783 UNKNOWN_SECTION_NAME, 784 5, // section size 785 0xff, 0xff, 0xff, 0xff, 0xff, 786 }; 787 EXPECT_VERIFIES(data); 788} 789 790TEST_F(WasmModuleVerifyTest, SignatureFollowedByUnknownSectionWithLongLEB) { 791 const byte data[] = { 792 // signatures 793 SIGNATURES_SECTION_VOID_VOID, 794 // ----------------------------------------------------------- 795 UNKNOWN_SECTION_NAME, 0x81, 0x80, 0x80, 0x80, 796 0x00, // section size: 1 but in a 5-byte LEB 797 0, 798 }; 799 EXPECT_VERIFIES(data); 800} 801 802TEST_F(WasmModuleVerifyTest, UnknownSectionOverflow) { 803 static const byte data[] = { 804 UNKNOWN_EMPTY_SECTION_NAME, 805 9, // section size 806 1, 807 2, 808 3, 809 4, 810 5, 811 6, 812 7, 813 8, 814 9, 815 10, // 10 byte section 816 }; 817 EXPECT_FAILURE(data); 818} 819 820TEST_F(WasmModuleVerifyTest, UnknownSectionUnderflow) { 821 static const byte data[] = { 822 UNKNOWN_EMPTY_SECTION_NAME, 823 0xff, 824 0xff, 825 0xff, 826 0xff, 827 0x0f, // Section size LEB128 0xffffffff 828 1, 829 2, 830 3, 831 4, // 4 byte section 832 }; 833 EXPECT_FAILURE(data); 834} 835 836TEST_F(WasmModuleVerifyTest, UnknownSectionLoop) { 837 // Would infinite loop decoding if wrapping and allowed. 838 static const byte data[] = { 839 UNKNOWN_EMPTY_SECTION_NAME, 840 1, 841 2, 842 3, 843 4, // 4 byte section 844 0xfa, 845 0xff, 846 0xff, 847 0xff, 848 0x0f, // Section size LEB128 0xfffffffa 849 }; 850 EXPECT_FAILURE(data); 851} 852 853TEST_F(WasmModuleVerifyTest, UnknownSectionSkipped) { 854 static const byte data[] = { 855 UNKNOWN_EMPTY_SECTION_NAME, 856 1, // section size 857 0, // one byte section 858 SECTION(GLOBALS, 4), 859 1, 860 0, // name length 861 kMemI32, // memory type 862 0, // exported 863 }; 864 ModuleResult result = DecodeModule(data, data + arraysize(data)); 865 EXPECT_OK(result); 866 867 EXPECT_EQ(1, result.val->globals.size()); 868 EXPECT_EQ(0, result.val->functions.size()); 869 EXPECT_EQ(0, result.val->data_segments.size()); 870 871 const WasmGlobal* global = &result.val->globals.back(); 872 873 EXPECT_EQ(0, global->name_length); 874 EXPECT_EQ(MachineType::Int32(), global->type); 875 EXPECT_EQ(0, global->offset); 876 EXPECT_FALSE(global->exported); 877 878 if (result.val) delete result.val; 879} 880 881TEST_F(WasmModuleVerifyTest, ImportTable_empty) { 882 static const byte data[] = {SECTION(SIGNATURES, 1), 0, 883 SECTION(IMPORT_TABLE, 1), 0}; 884 EXPECT_VERIFIES(data); 885} 886 887TEST_F(WasmModuleVerifyTest, ImportTable_nosigs1) { 888 static const byte data[] = {SECTION(IMPORT_TABLE, 1), 0}; 889 EXPECT_VERIFIES(data); 890} 891 892TEST_F(WasmModuleVerifyTest, ImportTable_nosigs2) { 893 static const byte data[] = { 894 SECTION(IMPORT_TABLE, 6), 1, // sig table 895 IMPORT_SIG_INDEX(0), // sig index 896 NAME_LENGTH(1), 'm', // module name 897 NAME_LENGTH(1), 'f', // function name 898 }; 899 EXPECT_FAILURE(data); 900} 901 902TEST_F(WasmModuleVerifyTest, ImportTable_invalid_sig) { 903 static const byte data[] = { 904 SECTION(SIGNATURES, 1), 0, // -- 905 SECTION(IMPORT_TABLE, 6), 1, // -- 906 IMPORT_SIG_INDEX(0), // sig index 907 NAME_LENGTH(1), 'm', // module name 908 NAME_LENGTH(1), 'f', // function name 909 }; 910 EXPECT_FAILURE(data); 911} 912 913TEST_F(WasmModuleVerifyTest, ImportTable_one_sig) { 914 static const byte data[] = { 915 // signatures 916 SIGNATURES_SECTION_VOID_VOID, 917 SECTION(IMPORT_TABLE, 6), 918 1, // -- 919 IMPORT_SIG_INDEX(0), // sig index 920 NAME_LENGTH(1), 921 'm', // module name 922 NAME_LENGTH(1), 923 'f', // function name 924 }; 925 EXPECT_VERIFIES(data); 926} 927 928TEST_F(WasmModuleVerifyTest, ImportTable_invalid_module) { 929 static const byte data[] = { 930 // signatures 931 SIGNATURES_SECTION_VOID_VOID, 932 SECTION(IMPORT_TABLE, 6), 933 1, // -- 934 IMPORT_SIG_INDEX(0), // sig index 935 NO_NAME, // module name 936 NAME_LENGTH(1), 937 'f' // function name 938 }; 939 EXPECT_FAILURE(data); 940} 941 942TEST_F(WasmModuleVerifyTest, ImportTable_off_end) { 943 static const byte data[] = { 944 // signatures 945 SIGNATURES_SECTION_VOID_VOID, 946 SECTION(IMPORT_TABLE, 6), 947 1, 948 IMPORT_SIG_INDEX(0), // sig index 949 NAME_LENGTH(1), 950 'm', // module name 951 NAME_LENGTH(1), 952 'f', // function name 953 }; 954 955 EXPECT_OFF_END_FAILURE(data, 16, sizeof(data)); 956} 957 958TEST_F(WasmModuleVerifyTest, ExportTable_empty1) { 959 static const byte data[] = {// signatures 960 SIGNATURES_SECTION_VOID_VOID, ONE_EMPTY_FUNCTION, 961 SECTION(EXPORT_TABLE, 1), 962 0, // -- 963 ONE_EMPTY_BODY}; 964 965 ModuleResult result = DecodeModule(data, data + arraysize(data)); 966 EXPECT_OK(result); 967 968 EXPECT_EQ(1, result.val->functions.size()); 969 EXPECT_EQ(0, result.val->export_table.size()); 970 971 if (result.val) delete result.val; 972} 973 974TEST_F(WasmModuleVerifyTest, ExportTable_empty2) { 975 static const byte data[] = { 976 SECTION(SIGNATURES, 1), 0, SECTION(EXPORT_TABLE, 1), 0 // -- 977 }; 978 // TODO(titzer): current behavior treats empty functions section as missing. 979 EXPECT_FAILURE(data); 980} 981 982TEST_F(WasmModuleVerifyTest, ExportTable_NoFunctions1) { 983 static const byte data[] = { 984 SECTION(SIGNATURES, 1), 0, SECTION(EXPORT_TABLE, 1), 0 // -- 985 }; 986 EXPECT_FAILURE(data); 987} 988 989TEST_F(WasmModuleVerifyTest, ExportTable_NoFunctions2) { 990 static const byte data[] = {SECTION(EXPORT_TABLE, 1), 0}; 991 EXPECT_FAILURE(data); 992} 993 994TEST_F(WasmModuleVerifyTest, ExportTableOne) { 995 static const byte data[] = {// signatures 996 SIGNATURES_SECTION_VOID_VOID, 997 ONE_EMPTY_FUNCTION, 998 SECTION(EXPORT_TABLE, 3), 999 1, // exports 1000 FUNC_INDEX(0), // -- 1001 NO_NAME, // -- 1002 ONE_EMPTY_BODY}; 1003 ModuleResult result = DecodeModule(data, data + arraysize(data)); 1004 EXPECT_OK(result); 1005 1006 EXPECT_EQ(1, result.val->functions.size()); 1007 EXPECT_EQ(1, result.val->export_table.size()); 1008 1009 if (result.val) delete result.val; 1010} 1011 1012TEST_F(WasmModuleVerifyTest, ExportTableTwo) { 1013 static const byte data[] = {// signatures 1014 SIGNATURES_SECTION_VOID_VOID, 1015 ONE_EMPTY_FUNCTION, 1016 SECTION(EXPORT_TABLE, 12), 1017 2, // exports 1018 FUNC_INDEX(0), // -- 1019 NAME_LENGTH(4), 1020 'n', 1021 'a', 1022 'm', 1023 'e', // -- 1024 FUNC_INDEX(0), // -- 1025 NAME_LENGTH(3), 1026 'n', 1027 'o', 1028 'm', // -- 1029 ONE_EMPTY_BODY}; 1030 1031 ModuleResult result = DecodeModule(data, data + arraysize(data)); 1032 EXPECT_OK(result); 1033 1034 EXPECT_EQ(1, result.val->functions.size()); 1035 EXPECT_EQ(2, result.val->export_table.size()); 1036 1037 if (result.val) delete result.val; 1038} 1039 1040TEST_F(WasmModuleVerifyTest, ExportTableThree) { 1041 static const byte data[] = {// signatures 1042 SIGNATURES_SECTION_VOID_VOID, 1043 THREE_EMPTY_FUNCTIONS, 1044 SECTION(EXPORT_TABLE, 10), 1045 3, // exports 1046 FUNC_INDEX(0), // -- 1047 NAME_LENGTH(1), 1048 'a', // -- 1049 FUNC_INDEX(1), // -- 1050 NAME_LENGTH(1), 1051 'b', // -- 1052 FUNC_INDEX(2), // -- 1053 NAME_LENGTH(1), 1054 'c', // -- 1055 THREE_EMPTY_BODIES}; 1056 ModuleResult result = DecodeModule(data, data + arraysize(data)); 1057 EXPECT_OK(result); 1058 1059 EXPECT_EQ(3, result.val->functions.size()); 1060 EXPECT_EQ(3, result.val->export_table.size()); 1061 1062 if (result.val) delete result.val; 1063} 1064 1065TEST_F(WasmModuleVerifyTest, ExportTableThreeOne) { 1066 for (int i = 0; i < 6; i++) { 1067 const byte data[] = {// signatures 1068 SIGNATURES_SECTION_VOID_VOID, 1069 THREE_EMPTY_FUNCTIONS, 1070 SECTION(EXPORT_TABLE, 5), 1071 1, // exports 1072 FUNC_INDEX(i), // -- 1073 NAME_LENGTH(2), 1074 'e', 1075 'x', // -- 1076 THREE_EMPTY_BODIES}; 1077 1078 if (i < 3) { 1079 EXPECT_VERIFIES(data); 1080 } else { 1081 EXPECT_FAILURE(data); 1082 } 1083 } 1084} 1085 1086TEST_F(WasmModuleVerifyTest, ExportTableOne_off_end) { 1087 static const byte data[] = { 1088 // signatures 1089 SIGNATURES_SECTION_VOID_VOID, 1090 ONE_EMPTY_FUNCTION, 1091 SECTION(EXPORT_TABLE, 1 + 6), 1092 1, // exports 1093 FUNC_INDEX(0), // -- 1094 NO_NAME // -- 1095 }; 1096 1097 for (int length = 33; length < sizeof(data); length++) { 1098 ModuleResult result = DecodeModule(data, data + length); 1099 EXPECT_FALSE(result.ok()); 1100 if (result.val) delete result.val; 1101 } 1102} 1103 1104TEST_F(WasmModuleVerifyTest, FunctionSignatures_empty) { 1105 static const byte data[] = { 1106 SECTION(SIGNATURES, 1), 0, // -- 1107 SECTION(FUNCTION_SIGNATURES, 1), 0 // -- 1108 }; // -- 1109 EXPECT_VERIFIES(data); 1110} 1111 1112TEST_F(WasmModuleVerifyTest, FunctionSignatures_one) { 1113 static const byte data[] = { 1114 SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // -- 1115 FUNCTION_SIGNATURES_SECTION(1, 0) // -- 1116 }; 1117 EXPECT_VERIFIES(data); 1118} 1119 1120TEST_F(WasmModuleVerifyTest, FunctionBodies_empty) { 1121 static const byte data[] = { 1122 EMPTY_SIGNATURES_SECTION, // -- 1123 EMPTY_FUNCTION_SIGNATURES_SECTION, // -- 1124 EMPTY_FUNCTION_BODIES_SECTION // -- 1125 }; 1126 EXPECT_VERIFIES(data); 1127} 1128 1129TEST_F(WasmModuleVerifyTest, FunctionBodies_one_empty) { 1130 static const byte data[] = { 1131 SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // -- 1132 FUNCTION_SIGNATURES_SECTION(1, 0), // -- 1133 SECTION(FUNCTION_BODIES, 1 + SIZEOF_EMPTY_BODY), 1, EMPTY_BODY // -- 1134 }; 1135 EXPECT_VERIFIES(data); 1136} 1137 1138TEST_F(WasmModuleVerifyTest, FunctionBodies_one_nop) { 1139 static const byte data[] = { 1140 SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // -- 1141 FUNCTION_SIGNATURES_SECTION(1, 0), // -- 1142 SECTION(FUNCTION_BODIES, 1 + SIZEOF_NOP_BODY), 1, NOP_BODY // -- 1143 }; 1144 EXPECT_VERIFIES(data); 1145} 1146 1147TEST_F(WasmModuleVerifyTest, FunctionBodies_count_mismatch1) { 1148 static const byte data[] = { 1149 SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // -- 1150 FUNCTION_SIGNATURES_SECTION(2, 0, 0), // -- 1151 SECTION(FUNCTION_BODIES, 1 + SIZEOF_EMPTY_BODY), 1, // -- 1152 EMPTY_BODY // -- 1153 }; 1154 EXPECT_FAILURE(data); 1155} 1156 1157TEST_F(WasmModuleVerifyTest, FunctionBodies_count_mismatch2) { 1158 static const byte data[] = { 1159 SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // -- 1160 FUNCTION_SIGNATURES_SECTION(1, 0), // -- 1161 SECTION(FUNCTION_BODIES, 1 + 2 * SIZEOF_NOP_BODY), // -- 1162 2, // -- 1163 NOP_BODY, // -- 1164 NOP_BODY // -- 1165 }; 1166 EXPECT_FAILURE(data); 1167} 1168 1169TEST_F(WasmModuleVerifyTest, Names_empty) { 1170 static const byte data[] = { 1171 EMPTY_SIGNATURES_SECTION, EMPTY_FUNCTION_SIGNATURES_SECTION, 1172 EMPTY_FUNCTION_BODIES_SECTION, EMPTY_NAMES_SECTION}; 1173 EXPECT_VERIFIES(data); 1174} 1175 1176TEST_F(WasmModuleVerifyTest, Names_one_empty) { 1177 static const byte data[] = { 1178 SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // -- 1179 FUNCTION_SIGNATURES_SECTION(1, 0), // -- 1180 SECTION(FUNCTION_BODIES, 1 + SIZEOF_EMPTY_BODY), 1181 1, 1182 EMPTY_BODY, // -- 1183 SECTION(NAMES, 1 + 5), 1184 1, 1185 FOO_STRING, 1186 NO_LOCAL_NAMES // -- 1187 }; 1188 EXPECT_VERIFIES(data); 1189} 1190 1191TEST_F(WasmModuleVerifyTest, Names_two_empty) { 1192 static const byte data[] = { 1193 SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // -- 1194 FUNCTION_SIGNATURES_SECTION(2, 0, 0), // -- 1195 SECTION(FUNCTION_BODIES, 1 + 2 * SIZEOF_EMPTY_BODY), // -- 1196 2, 1197 EMPTY_BODY, 1198 EMPTY_BODY, // -- 1199 SECTION(NAMES, 1 + 10), 1200 2, // -- 1201 FOO_STRING, 1202 NO_LOCAL_NAMES, // -- 1203 FOO_STRING, 1204 NO_LOCAL_NAMES, // -- 1205 }; 1206 EXPECT_VERIFIES(data); 1207} 1208 1209} // namespace wasm 1210} // namespace internal 1211} // namespace v8 1212