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 |