Repository: uutils/coreutils (language: rust)

Issue:
printf: should warn on excess arguments but doesn't
Environment: Ubuntu 20.04, uutils `main` branch (git commit ceb0785f8d89e82dabe347ff6d368f310977dce0), GNU coreutils v9.6.3-3189c-dirty

Steps to reproduce:
```
printf "B\n" 1
```

What happens now: uutils `printf` prints B with no warning:
```
B
```

What I expected to happen: GNU `printf` prints B with a warning about the excess argument 1:
```
B
printf: warning: ignoring excess arguments, starting with ‘1’
```

Notes: this is causing a failure in GNU test file `tests/printf/printf-cov.pl`.


Discussion / hints:

Fix patch:
diff --git a/src/uu/printf/src/printf.rs b/src/uu/printf/src/printf.rs
index f278affaede..bbcc50c005d 100644
--- a/src/uu/printf/src/printf.rs
+++ b/src/uu/printf/src/printf.rs
@@ -7,7 +7,7 @@ use std::io::stdout;
 use std::ops::ControlFlow;
 use uucore::error::{UResult, UUsageError};
 use uucore::format::{parse_spec_and_escape, FormatArgument, FormatItem};
-use uucore::{format_usage, help_about, help_section, help_usage};
+use uucore::{format_usage, help_about, help_section, help_usage, show_warning};
 
 const VERSION: &str = "version";
 const HELP: &str = "help";
@@ -48,6 +48,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
     // Without format specs in the string, the iter would not consume any args,
     // leading to an infinite loop. Thus, we exit early.
     if !format_seen {
+        if let Some(arg) = args.next() {
+            use FormatArgument::*;
+            let Unparsed(arg_str) = arg else {
+                unreachable!("All args are transformed to Unparsed")
+            };
+            show_warning!("ignoring excess arguments, starting with '{arg_str}'");
+        }
         return Ok(());
     }
 
@@ -59,6 +66,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
             };
         }
     }
+
     Ok(())
 }
 


Test patch:
diff --git a/tests/by-util/test_printf.rs b/tests/by-util/test_printf.rs
index 9b29c404ca8..044817214c0 100644
--- a/tests/by-util/test_printf.rs
+++ b/tests/by-util/test_printf.rs
@@ -679,7 +679,11 @@ fn char_as_byte() {
 
 #[test]
 fn no_infinite_loop() {
-    new_ucmd!().args(&["a", "b"]).succeeds().stdout_only("a");
+    new_ucmd!()
+        .args(&["a", "b"])
+        .succeeds()
+        .stdout_is("a")
+        .stderr_contains("warning: ignoring excess arguments, starting with 'b'");
 }
 
 #[test]