github.com/saferwall/pe@v1.5.2/dotnet_test.go (about) 1 // Copyright 2018 Saferwall. All rights reserved. 2 // Use of this source code is governed by Apache v2 license 3 // license that can be found in the LICENSE file. 4 5 package pe 6 7 import ( 8 "reflect" 9 "sort" 10 "strconv" 11 "testing" 12 ) 13 14 func TestClrDirectoryHeaders(t *testing.T) { 15 16 type TestClrHeaders struct { 17 clrHeader ImageCOR20Header 18 mdHeader MetadataHeader 19 mdStreamHeaders []MetadataStreamHeader 20 mdTablesStreamHeader MetadataTableStreamHeader 21 } 22 23 tests := []struct { 24 in string 25 out TestClrHeaders 26 }{ 27 { 28 getAbsoluteFilePath("test/mscorlib.dll"), 29 TestClrHeaders{ 30 clrHeader: ImageCOR20Header{ 31 Cb: 0x48, 32 MajorRuntimeVersion: 0x2, 33 MinorRuntimeVersion: 0x5, 34 MetaData: ImageDataDirectory{ 35 VirtualAddress: 0x2050, 36 Size: 0xae34, 37 }, 38 Flags: 0x9, 39 EntryPointRVAorToken: 0x0, 40 StrongNameSignature: ImageDataDirectory{ 41 VirtualAddress: 0xce84, 42 Size: 0x80, 43 }, 44 }, 45 mdHeader: MetadataHeader{ 46 Signature: 0x424a5342, 47 MajorVersion: 0x1, 48 MinorVersion: 0x1, 49 ExtraData: 0x0, 50 VersionString: 0xc, 51 Version: "v4.0.30319", 52 Flags: 0x0, 53 Streams: 0x5, 54 }, 55 mdStreamHeaders: []MetadataStreamHeader{ 56 { 57 Offset: 0x6c, 58 Size: 0x4c38, 59 Name: "#~", 60 }, 61 { 62 Offset: 0x4ca4, 63 Size: 0x5ed4, 64 Name: "#Strings", 65 }, 66 { 67 Offset: 0xab78, 68 Size: 0x4, 69 Name: "#US", 70 }, 71 { 72 Offset: 0xab7c, 73 Size: 0x10, 74 Name: "#GUID", 75 }, 76 { 77 Offset: 0xab8c, 78 Size: 0x2a8, 79 Name: "#Blob", 80 }, 81 }, 82 mdTablesStreamHeader: MetadataTableStreamHeader{ 83 Reserved: 0x0, 84 MajorVersion: 0x2, 85 MinorVersion: 0x0, 86 Heaps: 0x0, 87 RID: 0x1, 88 MaskValid: 0x8900005407, 89 Sorted: 0x16003301fa00, 90 }, 91 }, 92 }, 93 } 94 95 for _, tt := range tests { 96 t.Run(tt.in, func(t *testing.T) { 97 ops := Options{Fast: true} 98 file, err := New(tt.in, &ops) 99 if err != nil { 100 t.Fatalf("New(%s) failed, reason: %v", tt.in, err) 101 } 102 103 err = file.Parse() 104 if err != nil { 105 t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err) 106 } 107 108 var va, size uint32 109 switch file.Is64 { 110 case true: 111 oh64 := file.NtHeader.OptionalHeader.(ImageOptionalHeader64) 112 dirEntry := oh64.DataDirectory[ImageDirectoryEntryCLR] 113 va = dirEntry.VirtualAddress 114 size = dirEntry.Size 115 case false: 116 oh32 := file.NtHeader.OptionalHeader.(ImageOptionalHeader32) 117 dirEntry := oh32.DataDirectory[ImageDirectoryEntryCLR] 118 va = dirEntry.VirtualAddress 119 size = dirEntry.Size 120 } 121 122 err = file.parseCLRHeaderDirectory(va, size) 123 if err != nil { 124 t.Fatalf("parseCLRHeaderDirectory(%s) failed, reason: %v", tt.in, err) 125 } 126 clr := file.CLR 127 if clr.CLRHeader != tt.out.clrHeader { 128 t.Errorf("CLR header assertion failed, got %v, want %v", 129 clr.CLRHeader, tt.out.clrHeader) 130 } 131 132 if clr.MetadataHeader != tt.out.mdHeader { 133 t.Errorf("CLR metadata header assertion failed, got %v, want %v", 134 clr.MetadataHeader, tt.out.mdHeader) 135 } 136 137 if !reflect.DeepEqual(clr.MetadataStreamHeaders, tt.out.mdStreamHeaders) { 138 t.Errorf("CLR metadata stream headers assertion failed, got %v, want %v", 139 clr.MetadataStreamHeaders, tt.out.mdStreamHeaders) 140 } 141 }) 142 } 143 } 144 145 func TestClrDirectoryMetadataTables(t *testing.T) { 146 147 type TestClrMetadataTable struct { 148 tableKind int 149 table MetadataTable 150 } 151 152 tests := []struct { 153 in string 154 out []TestClrMetadataTable 155 }{ 156 { 157 getAbsoluteFilePath("test/mscorlib.dll"), 158 []TestClrMetadataTable{ 159 { 160 tableKind: Module, 161 table: MetadataTable{ 162 Name: "Module", 163 CountCols: 0x1, 164 Content: []ModuleTableRow{ 165 { 166 Generation: 0x0, 167 Name: 0x2cd7, 168 Mvid: 0x1, 169 EncID: 0x0, 170 EncBaseID: 0x0, 171 }, 172 }, 173 }, 174 }, 175 176 { 177 tableKind: TypeRef, 178 table: MetadataTable{ 179 Name: "TypeRef", 180 CountCols: 19, 181 Content: []TypeRefTableRow{ 182 { 183 ResolutionScope: 0x6, 184 TypeName: 0x22bd, 185 TypeNamespace: 0x4d80, 186 }, 187 }, 188 }, 189 }, 190 191 { 192 tableKind: MemberRef, 193 table: MetadataTable{ 194 Name: "MemberRef", 195 CountCols: 17, 196 Content: []MemberRefTableRow{ 197 { 198 Class: 0x9, 199 Name: 0x4c76, 200 Signature: 0x1, 201 }, 202 }, 203 }, 204 }, 205 206 { 207 tableKind: CustomAttribute, 208 table: MetadataTable{ 209 Name: "CustomAttribute", 210 CountCols: 19, 211 Content: []CustomAttributeTableRow{ 212 { 213 Parent: 0x27, 214 Type: 0x83, 215 Value: 0x2a1, 216 }, 217 }, 218 }, 219 }, 220 221 { 222 tableKind: DeclSecurity, 223 table: MetadataTable{ 224 Name: "DeclSecurity", 225 CountCols: 1, 226 Content: []DeclSecurityTableRow{ 227 { 228 Action: 0x8, 229 Parent: 0x6, 230 PermissionSet: 0x52, 231 }, 232 }, 233 }, 234 }, 235 236 { 237 tableKind: Assembly, 238 table: MetadataTable{ 239 Name: "Assembly", 240 CountCols: 1, 241 Content: []AssemblyTableRow{ 242 { 243 HashAlgId: 0x8004, 244 MajorVersion: 0x4, 245 MinorVersion: 0x0, 246 BuildNumber: 0x0, 247 RevisionNumber: 0x0, 248 Flags: 0x1, 249 PublicKey: 0x41, 250 Name: 0x704, 251 Culture: 0x0, 252 }, 253 }, 254 }, 255 }, 256 257 { 258 tableKind: AssemblyRef, 259 table: MetadataTable{ 260 Name: "AssemblyRef", 261 CountCols: 30, 262 Content: []AssemblyRefTableRow{ 263 { 264 MajorVersion: 0x0, 265 MinorVersion: 0x0, 266 BuildNumber: 0x0, 267 RevisionNumber: 0x0, 268 Flags: 0x0, 269 PublicKeyOrToken: 0x26, 270 Name: 0x6ed, 271 Culture: 0x0, 272 HashValue: 0x0, 273 }, 274 }, 275 }, 276 }, 277 278 { 279 tableKind: ExportedType, 280 table: MetadataTable{ 281 Name: "ExportedType", 282 CountCols: 1319, 283 Content: []ExportedTypeTableRow{ 284 { 285 Flags: 0x200000, 286 TypeDefId: 0x0, 287 TypeName: 0x5d85, 288 TypeNamespace: 0x316, 289 Implementation: 0x9, 290 }, 291 }, 292 }, 293 }, 294 }, 295 }, 296 297 { 298 getAbsoluteFilePath("test/pspluginwkr.dll"), 299 []TestClrMetadataTable{ 300 { 301 tableKind: Module, 302 table: MetadataTable{ 303 Name: "Module", 304 CountCols: 0x1, 305 Content: []ModuleTableRow{ 306 { 307 Generation: 0x0, 308 Name: 0x8bdf, 309 Mvid: 0x1, 310 EncID: 0x0, 311 EncBaseID: 0x0, 312 }, 313 }, 314 }, 315 }, 316 317 { 318 tableKind: TypeRef, 319 table: MetadataTable{ 320 Name: "TypeRef", 321 CountCols: 140, 322 Content: []TypeRefTableRow{ 323 { 324 ResolutionScope: 0x6, 325 TypeName: 0x1103, 326 TypeNamespace: 0x1113, 327 }, 328 }, 329 }, 330 }, 331 332 { 333 tableKind: TypeDef, 334 table: MetadataTable{ 335 Name: "TypeDef", 336 CountCols: 169, 337 Content: []TypeDefTableRow{ 338 { 339 Flags: 0x0, 340 TypeName: 0x1, 341 TypeNamespace: 0x0, 342 Extends: 0x0, 343 FieldList: 0x1, 344 MethodList: 0x1, 345 }, 346 }, 347 }, 348 }, 349 350 { 351 tableKind: Field, 352 table: MetadataTable{ 353 Name: "Field", 354 CountCols: 325, 355 Content: []FieldTableRow{ 356 { 357 Flags: 0x113, 358 Name: 0x4af1, 359 Signature: 0xea9, 360 }, 361 }, 362 }, 363 }, 364 365 { 366 tableKind: MethodDef, 367 table: MetadataTable{ 368 Name: "MethodDef", 369 CountCols: 434, 370 Content: []MethodDefTableRow{ 371 { 372 RVA: 0x1d414, 373 ImplFlags: 0x0, 374 Flags: 0x13, 375 Name: 0x1b7f, 376 Signature: 0x125, 377 ParamList: 0x1, 378 }, 379 }, 380 }, 381 }, 382 383 { 384 tableKind: Param, 385 table: MetadataTable{ 386 Name: "Param", 387 CountCols: 679, 388 Content: []ParamTableRow{ 389 { 390 Flags: 0x2000, 391 Sequence: 0x0, 392 Name: 0x0, 393 }, 394 }, 395 }, 396 }, 397 398 { 399 tableKind: InterfaceImpl, 400 table: MetadataTable{ 401 Name: "InterfaceImpl", 402 CountCols: 3, 403 Content: []InterfaceImplTableRow{ 404 { 405 Class: 0x6c, 406 Interface: 0xa9, 407 }, 408 }, 409 }, 410 }, 411 412 { 413 tableKind: MemberRef, 414 table: MetadataTable{ 415 Name: "MemberRef", 416 CountCols: 256, 417 Content: []MemberRefTableRow{ 418 { 419 Class: 0x29, 420 Name: 0x79f8, 421 Signature: 0x11e2, 422 }, 423 }, 424 }, 425 }, 426 427 { 428 tableKind: Constant, 429 table: MetadataTable{ 430 Name: "Constant", 431 CountCols: 2, 432 Content: []ConstantTableRow{ 433 { 434 Type: 0xe, 435 Parent: 0x464, 436 Value: 0x1aa8, 437 }, 438 }, 439 }, 440 }, 441 442 { 443 tableKind: CustomAttribute, 444 table: MetadataTable{ 445 Name: "CustomAttribute", 446 CountCols: 622, 447 Content: []CustomAttributeTableRow{ 448 { 449 Parent: 0x2e, 450 Type: 0x7db, 451 Value: 0x2c02, 452 }, 453 }, 454 }, 455 }, 456 457 { 458 tableKind: FieldMarshal, 459 table: MetadataTable{ 460 Name: "FieldMarshal", 461 CountCols: 33, 462 Content: []FieldMarshalTableRow{ 463 { 464 Parent: 0x3, 465 NativeType: 0x1ca6, 466 }, 467 }, 468 }, 469 }, 470 471 { 472 tableKind: DeclSecurity, 473 table: MetadataTable{ 474 Name: "DeclSecurity", 475 CountCols: 4, 476 Content: []DeclSecurityTableRow{ 477 { 478 Action: 0x8, 479 Parent: 0x6, 480 PermissionSet: 0x2d81, 481 }, 482 }, 483 }, 484 }, 485 486 { 487 tableKind: ClassLayout, 488 table: MetadataTable{ 489 Name: "ClassLayout", 490 CountCols: 144, 491 Content: []ClassLayoutTableRow{ 492 { 493 PackingSize: 0x0, 494 ClassSize: 0x10, 495 Parent: 0x2, 496 }, 497 }, 498 }, 499 }, 500 501 { 502 tableKind: StandAloneSig, 503 table: MetadataTable{ 504 Name: "StandAloneSig", 505 CountCols: 358, 506 Content: []StandAloneSigTableRow{ 507 { 508 Signature: 0x1caa, 509 }, 510 }, 511 }, 512 }, 513 514 { 515 tableKind: EventMap, 516 table: MetadataTable{ 517 Name: "EventMap", 518 CountCols: 2, 519 Content: []EventMapTableRow{ 520 { 521 Parent: 0x7f, 522 EventList: 0x1, 523 }, 524 }, 525 }, 526 }, 527 528 { 529 tableKind: Event, 530 table: MetadataTable{ 531 Name: "Event", 532 CountCols: 2, 533 Content: []EventTableRow{ 534 { 535 EventFlags: 0x200, 536 Name: 0x7eeb, 537 EventType: 0x16, 538 }, 539 }, 540 }, 541 }, 542 543 { 544 tableKind: PropertyMap, 545 table: MetadataTable{ 546 Name: "PropertyMap", 547 CountCols: 2, 548 Content: []PropertyMapTableRow{ 549 { 550 Parent: 0x49, 551 PropertyList: 0x1, 552 }, 553 }, 554 }, 555 }, 556 557 { 558 tableKind: Property, 559 table: MetadataTable{ 560 Name: "Property", 561 CountCols: 2, 562 Content: []PropertyTableRow{ 563 { 564 Flags: 0x0, 565 Name: 0x7a8a, 566 Type: 0x11d7, 567 }, 568 }, 569 }, 570 }, 571 572 { 573 tableKind: MethodSemantics, 574 table: MetadataTable{ 575 Name: "MethodSemantics", 576 CountCols: 9, 577 Content: []MethodSemanticsTableRow{ 578 { 579 Semantics: 0x10, 580 Method: 0x153, 581 Association: 0x2, 582 }, 583 }, 584 }, 585 }, 586 587 { 588 tableKind: ModuleRef, 589 table: MetadataTable{ 590 Name: "ModuleRef", 591 CountCols: 1, 592 Content: []ModuleRefTableRow{ 593 { 594 Name: 0x0, 595 }, 596 }, 597 }, 598 }, 599 600 { 601 tableKind: TypeSpec, 602 table: MetadataTable{ 603 Name: "TypeSpec", 604 CountCols: 17, 605 Content: []TypeSpecTableRow{ 606 { 607 Signature: 0x85, 608 }, 609 }, 610 }, 611 }, 612 613 { 614 tableKind: ImplMap, 615 table: MetadataTable{ 616 Name: "ImplMap", 617 CountCols: 51, 618 Content: []ImplMapTableRow{ 619 { 620 MappingFlags: 0x240, 621 MemberForwarded: 0x1cb, 622 ImportName: 0x0, 623 ImportScope: 0x1, 624 }, 625 }, 626 }, 627 }, 628 629 { 630 tableKind: FieldRVA, 631 table: MetadataTable{ 632 Name: "FieldRVA", 633 CountCols: 265, 634 Content: []FieldRVATableRow{ 635 { 636 RVA: 0x11e4, 637 Field: 0x1, 638 }, 639 }, 640 }, 641 }, 642 643 { 644 tableKind: Assembly, 645 table: MetadataTable{ 646 Name: "Assembly", 647 CountCols: 1, 648 Content: []AssemblyTableRow{ 649 { 650 HashAlgId: 0x8004, 651 MajorVersion: 0x1, 652 MinorVersion: 0x0, 653 BuildNumber: 0x0, 654 RevisionNumber: 0x0, 655 Flags: 0x1, 656 PublicKey: 0x2b03, 657 Name: 0x8bd3, 658 Culture: 0x0, 659 }, 660 }, 661 }, 662 }, 663 664 { 665 tableKind: AssemblyRef, 666 table: MetadataTable{ 667 Name: "AssemblyRef", 668 CountCols: 5, 669 Content: []AssemblyRefTableRow{ 670 { 671 MajorVersion: 0x2, 672 MinorVersion: 0x0, 673 BuildNumber: 0x0, 674 RevisionNumber: 0x0, 675 Flags: 0x0, 676 PublicKeyOrToken: 0x1, 677 Name: 0x10b9, 678 Culture: 0x0, 679 HashValue: 0xa, 680 }, 681 }, 682 }, 683 }, 684 685 { 686 tableKind: NestedClass, 687 table: MetadataTable{ 688 Name: "NestedClass", 689 CountCols: 7, 690 Content: []NestedClassTableRow{ 691 { 692 NestedClass: 0x7, 693 EnclosingClass: 0x6, 694 }, 695 }, 696 }, 697 }, 698 }, 699 }, 700 } 701 702 for _, tt := range tests { 703 t.Run(tt.in, func(t *testing.T) { 704 ops := Options{Fast: true} 705 file, err := New(tt.in, &ops) 706 if err != nil { 707 t.Fatalf("New(%s) failed, reason: %v", tt.in, err) 708 } 709 710 err = file.Parse() 711 if err != nil { 712 t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err) 713 } 714 715 var va, size uint32 716 switch file.Is64 { 717 case true: 718 oh64 := file.NtHeader.OptionalHeader.(ImageOptionalHeader64) 719 dirEntry := oh64.DataDirectory[ImageDirectoryEntryCLR] 720 va = dirEntry.VirtualAddress 721 size = dirEntry.Size 722 case false: 723 oh32 := file.NtHeader.OptionalHeader.(ImageOptionalHeader32) 724 dirEntry := oh32.DataDirectory[ImageDirectoryEntryCLR] 725 va = dirEntry.VirtualAddress 726 size = dirEntry.Size 727 } 728 729 err = file.parseCLRHeaderDirectory(va, size) 730 if err != nil { 731 t.Fatalf("parseCLRHeaderDirectory(%s) failed, reason: %v", tt.in, err) 732 } 733 734 clr := file.CLR 735 for _, tbl := range tt.out { 736 mdTable := clr.MetadataTables[tbl.tableKind] 737 if mdTable.CountCols != tbl.table.CountCols { 738 t.Errorf("CLR metadata tables assertion failed on %s table, got %v, want %v", 739 tbl.table.Name, mdTable.CountCols, tbl.table.CountCols) 740 } 741 if mdTable.Name != tbl.table.Name { 742 t.Errorf("CLR metadata tables assertion failed on %s table, got %v, want %v", 743 tbl.table.Name, mdTable.Name, tbl.table) 744 } 745 746 var got, want interface{} 747 switch mdTable.Content.(type) { 748 case []ModuleTableRow: 749 got = mdTable.Content.([]ModuleTableRow)[0] 750 want = tbl.table.Content.([]ModuleTableRow)[0] 751 case []TypeRefTableRow: 752 got = mdTable.Content.([]TypeRefTableRow)[0] 753 want = tbl.table.Content.([]TypeRefTableRow)[0] 754 case []TypeDefTableRow: 755 got = mdTable.Content.([]TypeDefTableRow)[0] 756 want = tbl.table.Content.([]TypeDefTableRow)[0] 757 case []MemberRefTableRow: 758 got = mdTable.Content.([]MemberRefTableRow)[0] 759 want = tbl.table.Content.([]MemberRefTableRow)[0] 760 case []CustomAttributeTableRow: 761 got = mdTable.Content.([]CustomAttributeTableRow)[0] 762 want = tbl.table.Content.([]CustomAttributeTableRow)[0] 763 case []DeclSecurityTableRow: 764 got = mdTable.Content.([]DeclSecurityTableRow)[0] 765 want = tbl.table.Content.([]DeclSecurityTableRow)[0] 766 case []AssemblyTableRow: 767 got = mdTable.Content.([]AssemblyTableRow)[0] 768 want = tbl.table.Content.([]AssemblyTableRow)[0] 769 case []AssemblyRefTableRow: 770 got = mdTable.Content.([]AssemblyRefTableRow)[0] 771 want = tbl.table.Content.([]AssemblyRefTableRow)[0] 772 case []ExportedTypeTableRow: 773 got = mdTable.Content.([]ExportedTypeTableRow)[0] 774 want = tbl.table.Content.([]ExportedTypeTableRow)[0] 775 case []FieldTableRow: 776 got = mdTable.Content.([]FieldTableRow)[0] 777 want = tbl.table.Content.([]FieldTableRow)[0] 778 case []MethodDefTableRow: 779 got = mdTable.Content.([]MethodDefTableRow)[0] 780 want = tbl.table.Content.([]MethodDefTableRow)[0] 781 case []ParamTableRow: 782 got = mdTable.Content.([]ParamTableRow)[0] 783 want = tbl.table.Content.([]ParamTableRow)[0] 784 case []InterfaceImplTableRow: 785 got = mdTable.Content.([]InterfaceImplTableRow)[0] 786 want = tbl.table.Content.([]InterfaceImplTableRow)[0] 787 case []ConstantTableRow: 788 got = mdTable.Content.([]ConstantTableRow)[0] 789 want = tbl.table.Content.([]ConstantTableRow)[0] 790 case []FieldMarshalTableRow: 791 got = mdTable.Content.([]FieldMarshalTableRow)[0] 792 want = tbl.table.Content.([]FieldMarshalTableRow)[0] 793 case []ClassLayoutTableRow: 794 got = mdTable.Content.([]ClassLayoutTableRow)[0] 795 want = tbl.table.Content.([]ClassLayoutTableRow)[0] 796 case []StandAloneSigTableRow: 797 got = mdTable.Content.([]StandAloneSigTableRow)[0] 798 want = tbl.table.Content.([]StandAloneSigTableRow)[0] 799 case []EventMapTableRow: 800 got = mdTable.Content.([]EventMapTableRow)[0] 801 want = tbl.table.Content.([]EventMapTableRow)[0] 802 case []EventTableRow: 803 got = mdTable.Content.([]EventTableRow)[0] 804 want = tbl.table.Content.([]EventTableRow)[0] 805 case []PropertyMapTableRow: 806 got = mdTable.Content.([]PropertyMapTableRow)[0] 807 want = tbl.table.Content.([]PropertyMapTableRow)[0] 808 case []PropertyTableRow: 809 got = mdTable.Content.([]PropertyTableRow)[0] 810 want = tbl.table.Content.([]PropertyTableRow)[0] 811 case []MethodSemanticsTableRow: 812 got = mdTable.Content.([]MethodSemanticsTableRow)[0] 813 want = tbl.table.Content.([]MethodSemanticsTableRow)[0] 814 case []ModuleRefTableRow: 815 got = mdTable.Content.([]ModuleRefTableRow)[0] 816 want = tbl.table.Content.([]ModuleRefTableRow)[0] 817 case []TypeSpecTableRow: 818 got = mdTable.Content.([]TypeSpecTableRow)[0] 819 want = tbl.table.Content.([]TypeSpecTableRow)[0] 820 case []ImplMapTableRow: 821 got = mdTable.Content.([]ImplMapTableRow)[0] 822 want = tbl.table.Content.([]ImplMapTableRow)[0] 823 case []FieldRVATableRow: 824 got = mdTable.Content.([]FieldRVATableRow)[0] 825 want = tbl.table.Content.([]FieldRVATableRow)[0] 826 case []NestedClassTableRow: 827 got = mdTable.Content.([]NestedClassTableRow)[0] 828 want = tbl.table.Content.([]NestedClassTableRow)[0] 829 default: 830 got = "bad type" 831 want = "good type" 832 } 833 if !reflect.DeepEqual(got, want) { 834 t.Errorf("CLR metadata tables assertion failed on %s table, got %v, want %v", 835 tbl.table.Name, got, want) 836 } 837 838 } 839 }) 840 } 841 } 842 843 func TestClrDirectorCOMImageFlagsType(t *testing.T) { 844 845 tests := []struct { 846 in int 847 out []string 848 }{ 849 { 850 0x9, 851 []string{"IL Only", "Strong Name Signed"}, 852 }, 853 } 854 855 for _, tt := range tests { 856 t.Run("CaseFlagsEqualTo_"+strconv.Itoa(tt.in), func(t *testing.T) { 857 got := COMImageFlagsType(tt.in).String() 858 sort.Strings(got) 859 sort.Strings(tt.out) 860 if !reflect.DeepEqual(got, tt.out) { 861 t.Errorf("CLR header flags assertion failed, got %v, want %v", 862 got, tt.out) 863 } 864 }) 865 } 866 }