@@ -552,6 +552,54 @@ fn validate_pe(path: &Path, pe: &goblin::pe::PE) -> Result<Vec<String>> {
552
552
Ok ( errors)
553
553
}
554
554
555
+ /// Attempt to parse data as an object file and validate it.
556
+ fn validate_possible_object_file (
557
+ python_major_minor : & str ,
558
+ triple : & str ,
559
+ path : & Path ,
560
+ data : & [ u8 ] ,
561
+ ) -> Result < ( Vec < String > , BTreeSet < String > ) > {
562
+ let mut errors = vec ! [ ] ;
563
+ let mut seen_dylibs = BTreeSet :: new ( ) ;
564
+
565
+ if let Ok ( object) = goblin:: Object :: parse ( & data) {
566
+ match object {
567
+ goblin:: Object :: Elf ( elf) => {
568
+ errors. extend ( validate_elf (
569
+ triple,
570
+ python_major_minor,
571
+ path. as_ref ( ) ,
572
+ & elf,
573
+ & data,
574
+ ) ?) ;
575
+ }
576
+ goblin:: Object :: Mach ( mach) => match mach {
577
+ goblin:: mach:: Mach :: Binary ( macho) => {
578
+ let ( local_errors, local_seen_dylibs) =
579
+ validate_macho ( triple, path. as_ref ( ) , & macho, & data) ?;
580
+
581
+ errors. extend ( local_errors) ;
582
+ seen_dylibs. extend ( local_seen_dylibs) ;
583
+ }
584
+ goblin:: mach:: Mach :: Fat ( _) => {
585
+ if path. to_string_lossy ( ) != "python/build/lib/libclang_rt.osx.a" {
586
+ errors. push ( format ! ( "unexpected fat mach-o binary: {}" , path. display( ) ) ) ;
587
+ }
588
+ }
589
+ } ,
590
+ goblin:: Object :: PE ( pe) => {
591
+ // We don't care about the wininst-*.exe distutils executables.
592
+ if !path. to_string_lossy ( ) . contains ( "wininst-" ) {
593
+ errors. extend ( validate_pe ( path. as_ref ( ) , & pe) ?) ;
594
+ }
595
+ }
596
+ _ => { }
597
+ }
598
+ }
599
+
600
+ Ok ( ( errors, seen_dylibs) )
601
+ }
602
+
555
603
fn validate_json ( json : & PythonJsonMain , triple : & str ) -> Result < Vec < String > > {
556
604
let mut errors = vec ! [ ] ;
557
605
@@ -633,41 +681,33 @@ fn validate_distribution(dist_path: &Path) -> Result<Vec<String>> {
633
681
let mut data = Vec :: new ( ) ;
634
682
entry. read_to_end ( & mut data) ?;
635
683
636
- if let Ok ( object) = goblin:: Object :: parse ( & data) {
637
- match object {
638
- goblin:: Object :: Elf ( elf) => {
639
- errors. extend ( validate_elf (
640
- triple,
641
- python_major_minor,
642
- path. as_ref ( ) ,
643
- & elf,
644
- & data,
645
- ) ?) ;
646
- }
647
- goblin:: Object :: Mach ( mach) => match mach {
648
- goblin:: mach:: Mach :: Binary ( macho) => {
649
- let ( local_errors, local_seen_dylibs) =
650
- validate_macho ( triple, path. as_ref ( ) , & macho, & data) ?;
651
-
652
- errors. extend ( local_errors) ;
653
- seen_dylibs. extend ( local_seen_dylibs) ;
654
- }
655
- goblin:: mach:: Mach :: Fat ( _) => {
656
- if path. to_string_lossy ( ) != "python/build/lib/libclang_rt.osx.a" {
657
- errors
658
- . push ( format ! ( "unexpected fat mach-o binary: {}" , path. display( ) ) ) ;
659
- }
660
- }
661
- } ,
662
- goblin:: Object :: PE ( pe) => {
663
- // We don't care about the wininst-*.exe distutils executables.
664
- if path. to_string_lossy ( ) . contains ( "wininst-" ) {
665
- continue ;
666
- }
684
+ let ( local_errors, local_seen_dylibs) =
685
+ validate_possible_object_file ( python_major_minor, & triple, & path, & data) ?;
686
+ errors. extend ( local_errors) ;
687
+ seen_dylibs. extend ( local_seen_dylibs) ;
688
+
689
+ // Descend into archive files (static libraries are archive files and members
690
+ // are usually object files).
691
+ if let Ok ( archive) = goblin:: archive:: Archive :: parse ( & data) {
692
+ for member in archive. members ( ) {
693
+ let member_data = archive
694
+ . extract ( member, & data)
695
+ . with_context ( || format ! ( "extracting {} from {}" , member, path. display( ) ) ) ?;
696
+
697
+ let member_path = path. with_file_name ( format ! (
698
+ "{}:{}" ,
699
+ path. file_name( ) . unwrap( ) . to_string_lossy( ) ,
700
+ member
701
+ ) ) ;
667
702
668
- errors. extend ( validate_pe ( path. as_ref ( ) , & pe) ?) ;
669
- }
670
- _ => { }
703
+ let ( local_errors, local_seen_dylibs) = validate_possible_object_file (
704
+ python_major_minor,
705
+ & triple,
706
+ & member_path,
707
+ & member_data,
708
+ ) ?;
709
+ errors. extend ( local_errors) ;
710
+ seen_dylibs. extend ( local_seen_dylibs) ;
671
711
}
672
712
}
673
713
0 commit comments