From 5aa61abc103e1e11832008c453b301fb30070947 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sat, 29 Nov 2025 15:17:51 +0000 Subject: [PATCH] Remove pelite dependency The advantages of using the built-in implementation instead of pelite are: - It's much faster on average: for Starfield.exe (~ 100 MB) it is 2.8x faster and 4% slower reading file and product versions respectively, and for sfse_1_15_222.dll it is 3.35x faster and < 1% slower respectively. - It reduces the transitive dependency count by 8 - It uses ~ 700 lines of first-party code that only depends on the standard library, instead of 240715 lines of unaudited third-party code - pelite hasn't had a release in 3 years, and my PR for replacing winapi hasn't had any response in the month and a half it's been open, so the built-in implementation is probably less of a maintenance risk. --- Cargo.lock | 63 -------------------------- Cargo.toml | 1 - src/function/version.rs | 96 +--------------------------------------- supply-chain/config.toml | 32 -------------- 4 files changed, 2 insertions(+), 190 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6175c1..a23b871 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -179,21 +179,6 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" -[[package]] -name = "dataview" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50eb3a329e19d78c3a3dfa4ec5a51ecb84fa3a20c06edad04be25356018218f9" -dependencies = [ - "derive_pod", -] - -[[package]] -name = "derive_pod" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ea6706d74fca54e15f1d40b5cf7fe7f764aaec61352a9fcec58fe27e042fc8" - [[package]] name = "either" version = "1.15.0" @@ -310,7 +295,6 @@ dependencies = [ "criterion", "esplugin", "nom", - "pelite", "regex", "tempfile", "unicase", @@ -330,12 +314,6 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "no-std-compat" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" - [[package]] name = "nom" version = "8.0.0" @@ -366,25 +344,6 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" -[[package]] -name = "pelite" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88dccf4bd32294364aeb7bd55d749604450e9db54605887551f21baea7617685" -dependencies = [ - "dataview", - "libc", - "no-std-compat", - "pelite-macros", - "winapi", -] - -[[package]] -name = "pelite-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a7cf3f8ecebb0f4895f4892a8be0a0dc81b498f9d56735cb769dc31bf00815b" - [[package]] name = "plotters" version = "0.3.7" @@ -685,22 +644,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" version = "0.1.11" @@ -710,12 +653,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-link" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index a34cc40..2f2a1a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,6 @@ edition.workspace = true crc32fast = "1" esplugin = "6" nom = "8" -pelite = ">= 0.9.0, < 0.11" regex = ">= 0.2.7, < 2" unicase = "2" diff --git a/src/function/version.rs b/src/function/version.rs index 336451d..495b5cc 100644 --- a/src/function/version.rs +++ b/src/function/version.rs @@ -3,9 +3,6 @@ mod pe; use std::cmp::Ordering; use std::path::Path; -use pelite::resources::version_info::VersionInfo; -use pelite::resources::{FindError, Resources}; - use crate::error::Error; use pe::{read_file_version, read_pe_version, read_product_version}; @@ -113,105 +110,16 @@ pub(super) struct Version { impl Version { pub(super) fn read_file_version(file_path: &Path) -> Result, Error> { - let version = read_pe_version(file_path, read_file_version)?; - - let pelite_version = Self::read_version(file_path, |v| { - v.fixed().map(|f| { - format!( - "{}.{}.{}.{}", - f.dwFileVersion.Major, - f.dwFileVersion.Minor, - f.dwFileVersion.Patch, - f.dwFileVersion.Build - ) - }) - }); - - compare_versions(file_path, version, pelite_version) + read_pe_version(file_path, read_file_version) } pub(super) fn read_product_version(file_path: &Path) -> Result, Error> { - let version = read_pe_version(file_path, read_product_version)?; - - let pelite_version = Self::read_version(file_path, |v| { - v.translation() - .first() - .and_then(|language| v.value(*language, "ProductVersion")) - }); - - compare_versions(file_path, version, pelite_version) + read_pe_version(file_path, read_product_version) } pub(super) fn is_readable(file_path: &Path) -> bool { read_pe_version(file_path, |_| Ok(None)).is_ok() } - - fn read_version Option>( - file_path: &Path, - formatter: F, - ) -> Result, Error> { - #[cfg(any(windows, unix))] - let result = { - let file_map = pelite::FileMap::open(file_path) - .map_err(|e| Error::IoError(file_path.to_path_buf(), e))?; - - get_pe_version_info(file_map.as_ref()).map(formatter) - }; - - #[cfg(not(any(windows, unix)))] - let result = { - let bytes = - std::fs::read(file_path).map_err(|e| Error::IoError(file_path.to_path_buf(), e))?; - - get_pe_version_info(&bytes).map(formatter) - }; - - match result { - Ok(s) => Ok(s.map(Version::from)), - Err(FindError::NotFound) => Ok(None), - Err(e) => Err(Error::PeParsingError(file_path.to_path_buf(), Box::new(e))), - } - } -} - -fn compare_versions( - file_path: &Path, - version: Option, - pelite_version: Result, Error>, -) -> Result, Error> { - match pelite_version { - Ok(pv) if pv == version => Ok(version), - Ok(pv) => Err(Error::PeParsingError( - file_path.to_path_buf(), - format!("Versions parsed by object and pelite don't match: {version:?} != {pv:?}") - .into(), - )), - Err(e) => Err(Error::PeParsingError( - file_path.to_path_buf(), - format!("pelite errored when parsing version but built-in parser did not: {e}").into(), - )), - } -} - -fn get_pe_version_info(bytes: &[u8]) -> Result, FindError> { - get_pe_resources(bytes)?.version_info() -} - -fn get_pe_resources(bytes: &[u8]) -> Result, pelite::Error> { - use pelite::pe64; - match pe64::PeFile::from_bytes(bytes) { - Ok(file) => { - use pelite::pe64::Pe; - - file.resources() - } - Err(pelite::Error::PeMagic) => { - use pelite::pe32::{Pe, PeFile}; - - PeFile::from_bytes(bytes)?.resources() - } - Err(e) => Err(e), - } } fn is_separator(c: char) -> bool { diff --git a/supply-chain/config.toml b/supply-chain/config.toml index ecac627..8925d7a 100644 --- a/supply-chain/config.toml +++ b/supply-chain/config.toml @@ -38,14 +38,6 @@ criteria = "safe-to-run" version = "0.6.0" criteria = "safe-to-run" -[[exemptions.dataview]] -version = "1.0.1" -criteria = "safe-to-deploy" - -[[exemptions.derive_pod]] -version = "0.1.2" -criteria = "safe-to-deploy" - [[exemptions.errno]] version = "0.3.14" criteria = "safe-to-run" @@ -68,22 +60,10 @@ notes = "At time of review this was only built if targeting WASM, which is not a version = "2.7.4" criteria = "safe-to-deploy" -[[exemptions.no-std-compat]] -version = "0.4.1" -criteria = "safe-to-deploy" - [[exemptions.nom]] version = "8.0.0" criteria = "safe-to-deploy" -[[exemptions.pelite]] -version = "0.10.0" -criteria = "safe-to-deploy" - -[[exemptions.pelite-macros]] -version = "0.1.1" -criteria = "safe-to-deploy" - [[exemptions.plotters]] version = "0.3.7" criteria = "safe-to-run" @@ -157,15 +137,3 @@ version = "0.3.77" criteria = "safe-to-run" suggest = false notes = "At time of review this was only built if targeting WASM, which is not an intended target." - -[[exemptions.winapi]] -version = "0.3.9" -criteria = "safe-to-deploy" - -[[exemptions.winapi-i686-pc-windows-gnu]] -version = "0.4.0" -criteria = "safe-to-deploy" - -[[exemptions.winapi-x86_64-pc-windows-gnu]] -version = "0.4.0" -criteria = "safe-to-deploy"