@@ -612,7 +612,7 @@ mod windows {
612612 if let Ok ( entries) = std:: fs:: read_dir ( install_dir) {
613613 for entry in entries. flatten ( ) {
614614 let path = entry. path ( ) ;
615- if path. extension ( ) . is_some_and ( |ext| ext == "exe" ) {
615+ if path. extension ( ) . is_some_and ( |ext| ext == "exe" ) && is_pe_executable ( & path ) {
616616 let name = path
617617 . file_stem ( )
618618 . unwrap_or_default ( )
@@ -716,7 +716,7 @@ mod windows {
716716 for entry in entries. flatten ( ) {
717717 let path = entry. path ( ) ;
718718
719- if path. extension ( ) . is_some_and ( |ext| ext == "exe" ) {
719+ if path. extension ( ) . is_some_and ( |ext| ext == "exe" ) && is_pe_executable ( & path ) {
720720 let name = path
721721 . file_stem ( )
722722 . unwrap_or_default ( )
@@ -1185,6 +1185,22 @@ impl BrowserFactory {
11851185 }
11861186}
11871187
1188+ /// Check if a file is a valid PE executable by reading its magic bytes (MZ).
1189+ /// Returns false for archive files (.zip starts with PK, etc.) that were
1190+ /// incorrectly named with a .exe extension.
1191+ #[ cfg( target_os = "windows" ) ]
1192+ fn is_pe_executable ( path : & Path ) -> bool {
1193+ use std:: io:: Read ;
1194+ let Ok ( mut file) = std:: fs:: File :: open ( path) else {
1195+ return false ;
1196+ } ;
1197+ let mut magic = [ 0u8 ; 2 ] ;
1198+ if file. read_exact ( & mut magic) . is_err ( ) {
1199+ return false ;
1200+ }
1201+ magic == [ 0x4D , 0x5A ] // MZ
1202+ }
1203+
11881204// Factory function to create browser instances (kept for backward compatibility)
11891205pub fn create_browser ( browser_type : BrowserType ) -> Box < dyn Browser > {
11901206 BrowserFactory :: instance ( ) . create_browser ( browser_type)
0 commit comments