| 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-opcodes.h" | 8 #include "src/wasm/wasm-opcodes.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 struct LocalTypePair { | 39 struct LocalTypePair { |
| 40 uint8_t code; | 40 uint8_t code; |
| 41 LocalType type; | 41 LocalType type; |
| 42 } kLocalTypes[] = {{kLocalI32, kAstI32}, | 42 } kLocalTypes[] = {{kLocalI32, kAstI32}, |
| 43 {kLocalI64, kAstI64}, | 43 {kLocalI64, kAstI64}, |
| 44 {kLocalF32, kAstF32}, | 44 {kLocalF32, kAstF32}, |
| 45 {kLocalF64, kAstF64}}; | 45 {kLocalF64, kAstF64}}; |
| 46 | 46 |
| 47 | 47 |
| 48 // TODO(titzer): use these macros everywhere below. |
| 49 #define U32_LE(v) \ |
| 50 static_cast<byte>(v), static_cast<byte>((v) >> 8), \ |
| 51 static_cast<byte>((v) >> 16), static_cast<byte>((v) >> 24) |
| 52 |
| 53 |
| 54 #define U16_LE(v) static_cast<byte>(v), static_cast<byte>((v) >> 8) |
| 55 |
| 56 |
| 48 TEST_F(WasmModuleVerifyTest, DecodeEmpty) { | 57 TEST_F(WasmModuleVerifyTest, DecodeEmpty) { |
| 49 static const byte data[1]{kDeclEnd}; | 58 static const byte data[1]{kDeclEnd}; |
| 50 { | 59 { |
| 51 ModuleResult result = DecodeModule(data, data); | 60 ModuleResult result = DecodeModule(data, data); |
| 52 EXPECT_TRUE(result.ok()); | 61 EXPECT_TRUE(result.ok()); |
| 53 if (result.val) delete result.val; | 62 if (result.val) delete result.val; |
| 54 } | 63 } |
| 55 { | 64 { |
| 56 ModuleResult result = DecodeModule(data, data + 1); | 65 ModuleResult result = DecodeModule(data, data + 1); |
| 57 EXPECT_TRUE(result.ok()); | 66 EXPECT_TRUE(result.ok()); |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 EXPECT_EQ(2055, function->local_float64_count); | 465 EXPECT_EQ(2055, function->local_float64_count); |
| 457 | 466 |
| 458 EXPECT_FALSE(function->exported); | 467 EXPECT_FALSE(function->exported); |
| 459 EXPECT_FALSE(function->external); | 468 EXPECT_FALSE(function->external); |
| 460 | 469 |
| 461 if (result.val) delete result.val; | 470 if (result.val) delete result.val; |
| 462 } | 471 } |
| 463 | 472 |
| 464 | 473 |
| 465 TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) { | 474 TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) { |
| 466 static const byte kCodeStartOffset = 2 + kDeclGlobalSize + 4 + 2 + 17; | 475 static const byte kDeclMemorySize = 4; |
| 476 static const byte kCodeStartOffset = |
| 477 2 + kDeclMemorySize + kDeclGlobalSize + 4 + 2 + 17; |
| 467 static const byte kCodeEndOffset = kCodeStartOffset + 3; | 478 static const byte kCodeEndOffset = kCodeStartOffset + 3; |
| 468 | 479 |
| 469 static const byte data[] = { | 480 static const byte data[] = { |
| 481 kDeclMemory, 28, 28, 1, |
| 470 // global#0 -------------------------------------------------- | 482 // global#0 -------------------------------------------------- |
| 471 kDeclGlobals, 1, 0, 0, 0, 0, // name offset | 483 kDeclGlobals, 1, 0, 0, 0, 0, // name offset |
| 472 kMemU8, // memory type | 484 kMemU8, // memory type |
| 473 0, // exported | 485 0, // exported |
| 474 // sig#0 ----------------------------------------------------- | 486 // sig#0 ----------------------------------------------------- |
| 475 kDeclSignatures, 1, 0, 0, // void -> void | 487 kDeclSignatures, 1, 0, 0, // void -> void |
| 476 // func#0 ---------------------------------------------------- | 488 // func#0 ---------------------------------------------------- |
| 477 kDeclFunctions, 1, kDeclFunctionLocals | kDeclFunctionName, 0, | 489 kDeclFunctions, 1, kDeclFunctionLocals | kDeclFunctionName, 0, |
| 478 0, // signature index | 490 0, // signature index |
| 479 9, 0, 0, 0, // name offset | 491 9, 0, 0, 0, // name offset |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 EXPECT_EQ(5, segment->source_size); | 536 EXPECT_EQ(5, segment->source_size); |
| 525 EXPECT_TRUE(segment->init); | 537 EXPECT_TRUE(segment->init); |
| 526 | 538 |
| 527 if (result.val) delete result.val; | 539 if (result.val) delete result.val; |
| 528 } | 540 } |
| 529 } | 541 } |
| 530 | 542 |
| 531 | 543 |
| 532 TEST_F(WasmModuleVerifyTest, OneDataSegment) { | 544 TEST_F(WasmModuleVerifyTest, OneDataSegment) { |
| 533 const byte data[] = { | 545 const byte data[] = { |
| 534 kDeclDataSegments, | 546 kDeclMemory, 28, 28, 1, kDeclDataSegments, 1, 0xaa, 0xbb, 0x09, |
| 535 1, | |
| 536 0xaa, | |
| 537 0xbb, | |
| 538 0x09, | |
| 539 0, // dest addr | 547 0, // dest addr |
| 540 11, | 548 11, 0, 0, |
| 541 0, | |
| 542 0, | |
| 543 0, // source offset | 549 0, // source offset |
| 544 3, | 550 3, 0, 0, |
| 545 0, | |
| 546 0, | |
| 547 0, // source size | 551 0, // source size |
| 548 1, // init | 552 1, // init |
| 549 }; | 553 }; |
| 550 | 554 |
| 551 { | 555 { |
| 556 EXPECT_VERIFIES(data); |
| 552 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 557 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
| 553 EXPECT_TRUE(result.ok()); | 558 EXPECT_TRUE(result.ok()); |
| 554 EXPECT_EQ(0, result.val->globals->size()); | 559 EXPECT_EQ(0, result.val->globals->size()); |
| 555 EXPECT_EQ(0, result.val->functions->size()); | 560 EXPECT_EQ(0, result.val->functions->size()); |
| 556 EXPECT_EQ(1, result.val->data_segments->size()); | 561 EXPECT_EQ(1, result.val->data_segments->size()); |
| 557 | 562 |
| 558 WasmDataSegment* segment = &result.val->data_segments->back(); | 563 WasmDataSegment* segment = &result.val->data_segments->back(); |
| 559 | 564 |
| 560 EXPECT_EQ(0x9bbaa, segment->dest_addr); | 565 EXPECT_EQ(0x9bbaa, segment->dest_addr); |
| 561 EXPECT_EQ(11, segment->source_offset); | 566 EXPECT_EQ(11, segment->source_offset); |
| 562 EXPECT_EQ(3, segment->source_size); | 567 EXPECT_EQ(3, segment->source_size); |
| 563 EXPECT_TRUE(segment->init); | 568 EXPECT_TRUE(segment->init); |
| 564 | 569 |
| 565 if (result.val) delete result.val; | 570 if (result.val) delete result.val; |
| 566 } | 571 } |
| 567 | 572 |
| 568 for (size_t size = 1; size < arraysize(data); size++) { | 573 for (size_t size = 5; size < arraysize(data); size++) { |
| 569 // Should fall off end of module bytes. | 574 // Should fall off end of module bytes. |
| 570 ModuleResult result = DecodeModule(data, data + size); | 575 ModuleResult result = DecodeModule(data, data + size); |
| 571 EXPECT_FALSE(result.ok()); | 576 EXPECT_FALSE(result.ok()); |
| 572 if (result.val) delete result.val; | 577 if (result.val) delete result.val; |
| 573 } | 578 } |
| 574 } | 579 } |
| 575 | 580 |
| 576 | 581 |
| 577 TEST_F(WasmModuleVerifyTest, TwoDataSegments) { | 582 TEST_F(WasmModuleVerifyTest, TwoDataSegments) { |
| 578 const byte data[] = { | 583 const byte data[] = { |
| 579 kDeclDataSegments, | 584 kDeclMemory, 28, 28, 1, kDeclDataSegments, 2, 0xee, 0xff, 0x07, |
| 580 2, | |
| 581 0xee, | |
| 582 0xff, | |
| 583 0x07, | |
| 584 0, // dest addr | 585 0, // dest addr |
| 585 9, | 586 9, 0, 0, |
| 586 0, | |
| 587 0, | |
| 588 0, // #0: source offset | 587 0, // #0: source offset |
| 589 4, | 588 4, 0, 0, |
| 590 0, | |
| 591 0, | |
| 592 0, // source size | 589 0, // source size |
| 593 0, // init | 590 0, // init |
| 594 0xcc, | 591 0xcc, 0xdd, 0x06, |
| 595 0xdd, | |
| 596 0x06, | |
| 597 0, // #1: dest addr | 592 0, // #1: dest addr |
| 598 6, | 593 6, 0, 0, |
| 599 0, | |
| 600 0, | |
| 601 0, // source offset | 594 0, // source offset |
| 602 10, | 595 10, 0, 0, |
| 603 0, | |
| 604 0, | |
| 605 0, // source size | 596 0, // source size |
| 606 1, // init | 597 1, // init |
| 607 }; | 598 }; |
| 608 | 599 |
| 609 { | 600 { |
| 610 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 601 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
| 611 EXPECT_TRUE(result.ok()); | 602 EXPECT_TRUE(result.ok()); |
| 612 EXPECT_EQ(0, result.val->globals->size()); | 603 EXPECT_EQ(0, result.val->globals->size()); |
| 613 EXPECT_EQ(0, result.val->functions->size()); | 604 EXPECT_EQ(0, result.val->functions->size()); |
| 614 EXPECT_EQ(2, result.val->data_segments->size()); | 605 EXPECT_EQ(2, result.val->data_segments->size()); |
| 615 | 606 |
| 616 WasmDataSegment* s0 = &result.val->data_segments->at(0); | 607 WasmDataSegment* s0 = &result.val->data_segments->at(0); |
| 617 WasmDataSegment* s1 = &result.val->data_segments->at(1); | 608 WasmDataSegment* s1 = &result.val->data_segments->at(1); |
| 618 | 609 |
| 619 EXPECT_EQ(0x7ffee, s0->dest_addr); | 610 EXPECT_EQ(0x7ffee, s0->dest_addr); |
| 620 EXPECT_EQ(9, s0->source_offset); | 611 EXPECT_EQ(9, s0->source_offset); |
| 621 EXPECT_EQ(4, s0->source_size); | 612 EXPECT_EQ(4, s0->source_size); |
| 622 EXPECT_FALSE(s0->init); | 613 EXPECT_FALSE(s0->init); |
| 623 | 614 |
| 624 EXPECT_EQ(0x6ddcc, s1->dest_addr); | 615 EXPECT_EQ(0x6ddcc, s1->dest_addr); |
| 625 EXPECT_EQ(6, s1->source_offset); | 616 EXPECT_EQ(6, s1->source_offset); |
| 626 EXPECT_EQ(10, s1->source_size); | 617 EXPECT_EQ(10, s1->source_size); |
| 627 EXPECT_TRUE(s1->init); | 618 EXPECT_TRUE(s1->init); |
| 628 | 619 |
| 629 if (result.val) delete result.val; | 620 if (result.val) delete result.val; |
| 630 } | 621 } |
| 631 | 622 |
| 632 for (size_t size = 1; size < arraysize(data); size++) { | 623 for (size_t size = 5; size < arraysize(data); size++) { |
| 633 // Should fall off end of module bytes. | 624 // Should fall off end of module bytes. |
| 634 ModuleResult result = DecodeModule(data, data + size); | 625 ModuleResult result = DecodeModule(data, data + size); |
| 635 EXPECT_FALSE(result.ok()); | 626 EXPECT_FALSE(result.ok()); |
| 636 if (result.val) delete result.val; | 627 if (result.val) delete result.val; |
| 637 } | 628 } |
| 638 } | 629 } |
| 639 | 630 |
| 640 | 631 |
| 632 TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidSource) { |
| 633 const int dest_addr = 0x100; |
| 634 const byte mem_size_log2 = 15; |
| 635 const int kDataSize = 19; |
| 636 |
| 637 for (int source_offset = 0; source_offset < 5 + kDataSize; source_offset++) { |
| 638 for (int source_size = -1; source_size < 5 + kDataSize; source_size += 3) { |
| 639 byte data[] = { |
| 640 kDeclMemory, |
| 641 mem_size_log2, |
| 642 mem_size_log2, |
| 643 1, |
| 644 kDeclDataSegments, |
| 645 1, |
| 646 U32_LE(dest_addr), |
| 647 U32_LE(source_offset), |
| 648 U32_LE(source_size), |
| 649 1, // init |
| 650 }; |
| 651 |
| 652 STATIC_ASSERT(kDataSize == arraysize(data)); |
| 653 |
| 654 if (source_offset < kDataSize && source_size >= 0 && |
| 655 (source_offset + source_size) <= kDataSize) { |
| 656 EXPECT_VERIFIES(data); |
| 657 } else { |
| 658 EXPECT_FAILURE(data); |
| 659 } |
| 660 } |
| 661 } |
| 662 } |
| 663 |
| 664 |
| 665 TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidDest) { |
| 666 const int source_size = 3; |
| 667 const int source_offset = 11; |
| 668 |
| 669 for (byte mem_size_log2 = 12; mem_size_log2 < 20; mem_size_log2++) { |
| 670 int mem_size = 1 << mem_size_log2; |
| 671 |
| 672 for (int dest_addr = mem_size - source_size; |
| 673 dest_addr < mem_size + source_size; dest_addr++) { |
| 674 byte data[] = { |
| 675 kDeclMemory, |
| 676 mem_size_log2, |
| 677 mem_size_log2, |
| 678 1, |
| 679 kDeclDataSegments, |
| 680 1, |
| 681 U32_LE(dest_addr), |
| 682 U32_LE(source_offset), |
| 683 U32_LE(source_size), |
| 684 1, // init |
| 685 }; |
| 686 |
| 687 if (dest_addr <= (mem_size - source_size)) { |
| 688 EXPECT_VERIFIES(data); |
| 689 } else { |
| 690 EXPECT_FAILURE(data); |
| 691 } |
| 692 } |
| 693 } |
| 694 } |
| 695 |
| 696 |
| 641 // To make below tests for indirect calls much shorter. | 697 // To make below tests for indirect calls much shorter. |
| 642 #define FUNCTION(sig_index, external) \ | 698 #define FUNCTION(sig_index, external) \ |
| 643 kDeclFunctionImport, static_cast<byte>(sig_index), \ | 699 kDeclFunctionImport, static_cast<byte>(sig_index), \ |
| 644 static_cast<byte>(sig_index >> 8) | 700 static_cast<byte>(sig_index >> 8) |
| 645 | 701 |
| 646 | 702 |
| 647 TEST_F(WasmModuleVerifyTest, OneIndirectFunction) { | 703 TEST_F(WasmModuleVerifyTest, OneIndirectFunction) { |
| 648 static const byte data[] = { | 704 static const byte data[] = { |
| 649 // sig#0 ------------------------------------------------------- | 705 // sig#0 ------------------------------------------------------- |
| 650 kDeclSignatures, 1, 0, 0, // void -> void | 706 kDeclSignatures, 1, 0, 0, // void -> void |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 kDeclWLL, | 1004 kDeclWLL, |
| 949 0xfa, 0xff, 0xff, 0xff, 0x0f, // LEB128 0xfffffffa | 1005 0xfa, 0xff, 0xff, 0xff, 0x0f, // LEB128 0xfffffffa |
| 950 1, 2, 3, 4, // 4 byte section | 1006 1, 2, 3, 4, // 4 byte section |
| 951 }; | 1007 }; |
| 952 EXPECT_FAILURE(data); | 1008 EXPECT_FAILURE(data); |
| 953 } | 1009 } |
| 954 | 1010 |
| 955 } // namespace wasm | 1011 } // namespace wasm |
| 956 } // namespace internal | 1012 } // namespace internal |
| 957 } // namespace v8 | 1013 } // namespace v8 |
| OLD | NEW |