From 77523de3b92d39b9e30a60bb6c638c2c016fc4d3 Mon Sep 17 00:00:00 2001 From: Christopher Dryden Date: Thu, 15 Jan 2026 00:02:08 +0000 Subject: [PATCH 1/2] du: fix double-counting hard links across multiple arguments --- src/uu/du/src/du.rs | 6 +++--- tests/by-util/test_du.rs | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 3ad6e07f916..158a2a6b9fb 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -1080,6 +1080,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let (print_tx, rx) = mpsc::channel::>(); let printing_thread = thread::spawn(move || stat_printer.print_stats(&rx)); + // Track seen inodes across all arguments to avoid double-counting hard links + let mut seen_inodes: HashSet = HashSet::new(); + 'loop_file: for path in files { // Skip if we don't want to ignore anything if !&traversal_options.excludes.is_empty() { @@ -1098,9 +1101,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } } - // Check existence of path provided in argument - let mut seen_inodes: HashSet = HashSet::new(); - // Determine which traversal method to use #[cfg(all(unix, not(target_os = "redox")))] let use_safe_traversal = traversal_options.dereference != Deref::All; diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index 38d64d5b8b8..d32375053c5 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -532,6 +532,22 @@ fn du_hard_link(s: &str) { } } +#[cfg(unix)] +#[test] +fn test_du_hard_link_multiple_args() { + let (at, mut ucmd) = at_and_ucmd!(); + at.mkdir("dir1"); + at.mkdir("dir2"); + at.write("dir1/file", &"x".repeat(10000)); + at.hard_link("dir1/file", "dir2/file"); + + let result = ucmd.args(&["-b", "dir1", "dir2"]).succeeds(); + let lines: Vec<&str> = result.stdout_str().lines().collect(); + let size = |i: usize| lines[i].split('\t').next().unwrap().parse::().unwrap(); + assert!(size(0) >= 10000); + assert!(size(1) < 1000); +} + #[test] #[cfg(not(target_os = "openbsd"))] fn test_du_d_flag() { From 954ceeff4064e391ef63f6fb70b5df84cf29d316 Mon Sep 17 00:00:00 2001 From: Christopher Dryden Date: Thu, 15 Jan 2026 02:57:12 +0000 Subject: [PATCH 2/2] du: skip hard link test on Android (no hard link support) --- tests/by-util/test_du.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index d32375053c5..e94ec52831c 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -532,7 +532,7 @@ fn du_hard_link(s: &str) { } } -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "android")))] #[test] fn test_du_hard_link_multiple_args() { let (at, mut ucmd) = at_and_ucmd!();