From 0695e984af3b20b782562d752303bf16bbaca6e8 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Tue, 16 Dec 2025 12:16:47 +0100 Subject: [PATCH 1/2] Exclude test DLL's from published package During a dependency review we noticed that the libloading crate includes various dll files used for testing. These shouldn't be there as building the crate itself doesn't require these files. As of now they prevent any downstream user from enabling the `[bans.build.executable option]` option of cargo deny. I opted for using an explicit include list instead of an exclude list to prevent these files from being included in the published packages to make sure that everything that's included is an conscious choice. --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 1cd7b7b28..25f0db762 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["dlopen", "load", "shared", "dylib"] categories = ["api-bindings"] rust-version = "1.88.0" edition = "2021" +include = ["Cargo.toml", "LICENSE", "README.mkd", "src/**/*.rs"] [features] default = ["std"] From a208a9c031d39387920bc19e8e9054b29dc6dec8 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Mon, 5 Jan 2026 15:43:17 +0100 Subject: [PATCH 2/2] Replace prebuild binary dll's with a version build at test time This commit replaces the prebuild bin dlls with using a dll build at test time. --- Cargo.toml | 8 +++++++- src/test_helpers.rs | 9 +++++++-- tests/functions.rs | 11 +++++++---- tests/lib.rs | 5 +++++ tests/nagisa32.dll | Bin 3072 -> 0 bytes tests/nagisa64.dll | Bin 2560 -> 0 bytes tests/ordinals.def | 9 +++++++++ tests/windows.rs | 29 +++++++++-------------------- 8 files changed, 44 insertions(+), 27 deletions(-) create mode 100644 tests/lib.rs delete mode 100644 tests/nagisa32.dll delete mode 100644 tests/nagisa64.dll create mode 100644 tests/ordinals.def diff --git a/Cargo.toml b/Cargo.toml index 25f0db762..e5592ecc9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,8 @@ keywords = ["dlopen", "load", "shared", "dylib"] categories = ["api-bindings"] rust-version = "1.88.0" edition = "2021" -include = ["Cargo.toml", "LICENSE", "README.mkd", "src/**/*.rs"] +autotests = false +include = ["Cargo.toml", "LICENSE", "README.mkd", "src/**/*.rs", "tests/**/*.rs", "tests/ordinals.def"] [features] default = ["std"] @@ -43,3 +44,8 @@ unexpected_cfgs = { level = "warn", check-cfg = [ 'cfg(libloading_docs)', 'cfg(target_os, values("cygwin"))', ] } + +[[test]] +path = "tests/lib.rs" +name = "integration-tests" +harness = true diff --git a/src/test_helpers.rs b/src/test_helpers.rs index 9e3e9924f..8b02458a6 100644 --- a/src/test_helpers.rs +++ b/src/test_helpers.rs @@ -1,6 +1,6 @@ //! This is a separate file containing helpers for tests of this library. It is built into a //! dynamic library by the build.rs script. -#![crate_type="cdylib"] +#![crate_type = "cdylib"] #[no_mangle] pub static mut TEST_STATIC_U32: u32 = 0; @@ -18,7 +18,7 @@ pub struct S { a: u64, b: u32, c: u16, - d: u8 + d: u8, } #[no_mangle] @@ -35,3 +35,8 @@ pub unsafe extern "C" fn test_get_static_u32() -> u32 { pub unsafe extern "C" fn test_check_static_ptr() -> bool { TEST_STATIC_PTR == (&mut TEST_STATIC_PTR as *mut *mut _ as *mut _) } + +#[unsafe(no_mangle)] +pub extern "C" fn test_ordinals() -> *const std::ffi::c_char { + "bunny\0".as_ptr().cast() +} diff --git a/tests/functions.rs b/tests/functions.rs index 6f4fc2755..0ee2af971 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -1,10 +1,10 @@ use libloading::{Library, Symbol}; -use std::os::raw::c_void; const TARGET_DIR: Option<&'static str> = option_env!("CARGO_TARGET_DIR"); const TARGET_TMPDIR: Option<&'static str> = option_env!("CARGO_TARGET_TMPDIR"); +const MANIFEST_DIR: &'static str = env!("CARGO_MANIFEST_DIR"); -fn lib_path() -> std::path::PathBuf { +pub fn lib_path() -> std::path::PathBuf { [ TARGET_TMPDIR.unwrap_or(TARGET_DIR.unwrap_or("target")), "libtest_helpers.module", @@ -13,7 +13,7 @@ fn lib_path() -> std::path::PathBuf { .collect() } -fn make_helpers() { +pub fn make_helpers() { static ONCE: ::std::sync::Once = ::std::sync::Once::new(); ONCE.call_once(|| { if std::env::var_os("PRECOMPILED_TEST_HELPER").is_some() { @@ -31,6 +31,9 @@ fn make_helpers() { } else { eprintln!("WARNING: $TARGET NOT SPECIFIED! BUILDING HELPER MODULE FOR NATIVE TARGET."); } + if cfg!(target_env = "msvc") { + cmd.arg(format!("-Clink-arg=/DEF:{MANIFEST_DIR}/tests/ordinals.def")); + } assert!(cmd .status() .expect("could not compile the test helpers!") @@ -194,7 +197,7 @@ fn test_try_into_ptr() { unsafe { let lib = Library::new(lib_path()).unwrap(); let f: Symbol u32> = lib.get(b"test_identity_u32\0").unwrap(); - let ptr: *mut c_void = f.try_as_raw_ptr().unwrap(); + let ptr: *mut std::ffi::c_void = f.try_as_raw_ptr().unwrap(); assert!(!ptr.is_null()); let ptr_casted: extern "C" fn(u32) -> u32 = std::mem::transmute(ptr); assert_eq!(42, ptr_casted(42)); diff --git a/tests/lib.rs b/tests/lib.rs new file mode 100644 index 000000000..c1250ef53 --- /dev/null +++ b/tests/lib.rs @@ -0,0 +1,5 @@ +mod constants; +mod functions; +mod library_filename; +mod markers; +mod windows; diff --git a/tests/nagisa32.dll b/tests/nagisa32.dll deleted file mode 100644 index 0a6218ade9c051e3ebc34c5ad4a687c44263fb33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3072 zcmeHHK}!Nr5S}%SvJ?*;gP!1dkvw@@qM(D3SrG+`uI{1>`ZiX@@-GC{wf|utoun>Z z`~?#91G;qUW;1X1gooe83O zpTP0eTOZPp(4TOX8EE>WxV7`%cF^ApCm=O6hBZrQHHIby5@WevKwiOE+AhX9v^*MV zQIR}wqiQ#e%%*DA>(H^e>2#XJBQS?_OK4cC!3D>JUV+prhB4`@YI(v$y_6^xdY0;T ryJoqHG2U6BSyI1<3NZZy%5Basr#}{)_$w2@f07hGjQ>-B|2Kh8N)2p9 diff --git a/tests/nagisa64.dll b/tests/nagisa64.dll deleted file mode 100644 index bacaa4b969411958776c0aad5a848114b1b7bf51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2560 zcmeHH&r1SP5FRzd3dLiGz-R1v35>v-2LlgAVnP&%ySkza`Zm^;%2TJnLqD$l9|qDX z@X{gw0_lIKTb*p??LJxvLXU>S&dkpDzW10n?0yHQ_YeYr74+#8V2GJ4BjVqIxUs}j z3vQCreGU!_I80Ve4&H(>b>sR;@F;%bCep_V9?cEu*eRqw9)y^hY@L_GpxE zrBBi)cLS^^>9UtAA{WhClQ^=Y!ajg;9fH*7!?DEPVVi9PV*o)!=t5}mI0f-~6%YUh zTwfK?PZk&U_5?vgs=G<1-?fV{29Wd4nkgZFYbN4sB-N>3I7k)qq?UbmmnSd)O|=c( z(E(lvL_qN55C}ud;G?=UcRo7^(s>bdpJf1^edY3XfhUl=34bL3Mz5ab`&nhPUsB?^ zeqMt~bn%zPGCy ztrnb{+_26&grgycbV_KJ(&hqVt{h2yVpx-&s&!Y0s27cDp0JO0T8z5#EZZ?*sc diff --git a/tests/ordinals.def b/tests/ordinals.def new file mode 100644 index 000000000..1352bf958 --- /dev/null +++ b/tests/ordinals.def @@ -0,0 +1,9 @@ +LIBRARY test_helpers +EXPORTS + test_ordinals @1 NONAME + test_identity_u32 @2 + test_identity_struct @3 + test_check_static_ptr @4 + test_get_static_u32 @5 + TEST_STATIC_U32 @6 + TEST_STATIC_PTR @7 diff --git a/tests/windows.rs b/tests/windows.rs index 13a414502..f6f4bb159 100644 --- a/tests/windows.rs +++ b/tests/windows.rs @@ -3,27 +3,15 @@ extern crate libloading; use libloading::os::windows::*; use std::ffi::CStr; use std::os::raw::c_void; -// The ordinal DLL contains exactly one function (other than DllMain, that is) with ordinal number -// 1. This function has the sugnature `fn() -> *const c_char` and returns a string "bunny\0" (in -// reference to WindowsBunny). -// -// Both x86_64 and x86 versions of the .dll are functionally the same. Ideally we would compile the -// dlls with well known ordinals from our own testing helpers library, but rustc does not allow -// specifying a custom .def file (https://github.com/rust-lang/rust/issues/35089) -// -// The DLLs were kindly compiled by WindowsBunny (aka. @retep998). -#[cfg(target_arch = "x86")] -fn load_ordinal_lib() -> Library { - unsafe { Library::new("tests/nagisa32.dll").expect("nagisa32.dll") } -} - -#[cfg(target_arch = "x86_64")] +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn load_ordinal_lib() -> Library { - unsafe { Library::new("tests/nagisa64.dll").expect("nagisa64.dll") } + let path = super::functions::lib_path(); + super::functions::make_helpers(); + unsafe { Library::new(path.display().to_string()).expect("Windows test dll not found") } } -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_env = "msvc"))] #[test] fn test_ordinal() { let lib = load_ordinal_lib(); @@ -33,7 +21,7 @@ fn test_ordinal() { } } -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_env = "msvc"))] #[test] fn test_try_into_ptr() { let lib = load_ordinal_lib(); @@ -44,12 +32,13 @@ fn test_try_into_ptr() { } } -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_env = "msvc"))] #[test] fn test_ordinal_missing_fails() { let lib = load_ordinal_lib(); unsafe { - let r: Result *const i8>, _> = lib.get_ordinal(2); + // there are a few other symbols in the test DLL + let r: Result *const i8>, _> = lib.get_ordinal(8); r.err().unwrap(); let r: Result *const i8>, _> = lib.get_ordinal(!0); r.err().unwrap();