From 0bd25053b765ef04a7ad44ce320c7ebe34830854 Mon Sep 17 00:00:00 2001 From: ddidderr Date: Mon, 20 Jul 2026 17:26:36 +0200 Subject: [PATCH] fix(cli): preserve stdin directory probe traces The directory-source migration initially skipped its C probe for stdin because stdin can never be a directory from the CLI's normal marker path. The original C source-open callback nevertheless called `UTIL_isDirectory` for every source, including the stdin marker, and file-stat trace tests rely on those calls being observable. Always invoke the private C directory probe before source opening and keep the same positive-result rejection. This preserves the trace side effect for stdin while retaining Rust ownership of the rejection decision and the old source open ordering. Test Plan: - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings` -- passed - `ulimit -v 41943040; cargo +nightly fmt --manifest-path rust/Cargo.toml --all -- --check` -- passed - `git diff --cached --check` -- passed - The capped upstream run exposed two stdin file-stat trace mismatches; the suite will be rerun after this compatibility fix. --- rust/src/fileio_asyncio.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/rust/src/fileio_asyncio.rs b/rust/src/fileio_asyncio.rs index 72701e610..726a2becd 100644 --- a/rust/src/fileio_asyncio.rs +++ b/rust/src/fileio_asyncio.rs @@ -3080,13 +3080,11 @@ pub unsafe extern "C" fn FIO_rust_decompressFilename( assert!(!projection.dst_file_name.is_null()); assert!(!projection.src_file_name.is_null()); - if projection.source_is_stdin == 0 { - let source_is_directory = projection - .source_is_directory - .expect("source directory callback is required for named files"); - if unsafe { source_is_directory(projection.opaque, projection.src_file_name) } != 0 { - return 1; - } + let source_is_directory = projection + .source_is_directory + .expect("source directory callback is required"); + if unsafe { source_is_directory(projection.opaque, projection.src_file_name) } != 0 { + return 1; } let open_source = projection @@ -6067,6 +6065,16 @@ mod tests { assert!(state.events.is_empty()); } + #[test] + fn decompress_file_policy_probes_stdin_marker_before_opening_source() { + let mut state = DecompressPolicyState::default(); + let projection = decompress_policy_projection(&mut state, 0, 0, 1, 0, 0); + + assert_eq!(unsafe { FIO_rust_decompressFilename(&projection) }, 0); + assert_eq!(state.source_directory_checks, 1); + assert_eq!(state.events[0], DECOMPRESS_POLICY_OPEN_SOURCE); + } + #[test] fn decompress_file_policy_orders_cleanup_and_successful_source_removal() { let mut state = DecompressPolicyState {