Repository: uutils/coreutils (Rust)

Issue:
`env -u=2EKt` should generate an error
Found working on a fuzzer.
With our impl, it returns the env variable:

```
$  ./target/debug/coreutils env -u=2EKt  
ALACRITTY_LOG=/tmp/Alacritty-56177.log
[...]
```

With GNU:
```
$ LANG=C /usr/bin/env -u=2EKt
/usr/bin/env: cannot unset '=2EKt': Invalid argument
```


Discussion:
Hey folks, I'm new here and was thinking of picking this up as a first effort. Please let me know if I should do otherwise!
Karl
@karlmcdowall sure, go ahead :)
I see similar discrepancies on other tools between the Rust and GNU implementations. e.g...

#### Tail
Rust
<code>
$ ./target/debug/tail -n=1
pedantic = { level = "deny", priority = -1 }
</code>
GNU
<code>
$ /usr/bin/tail -n=1
/usr/bin/tail: invalid number of lines: ‘=1’
</code>

#### Touch
Rust
<code>
~/Rust/coreutils$ ./target/debug/touch -r=Cargo.lock Cargo.toml
</code>
GNU
<code>
$ /usr/bin/tail -n=1
~/Rust/coreutils$ /usr/bin/touch -r=Cargo.lock Cargo.toml
touch: failed to get attributes of '=Cargo.lock': No such file or directory
</code>

Seems there's a difference between clap and GNU-getopts. Worth raising as a bug/feature-request on clap??
Raised a discussion about this on the clap discussion board [here](https://github.com/clap-rs/clap/discussions/5824)



Patch:
diff --git a/src/uu/env/src/env.rs b/src/uu/env/src/env.rs
index 9e2e56d06c0..ea31c01079e 100644
--- a/src/uu/env/src/env.rs
+++ b/src/uu/env/src/env.rs
@@ -370,6 +370,19 @@ impl EnvAppData {
                     self.had_string_argument = true;
                 }
                 _ => {
+                    let arg_str = arg.to_string_lossy();
+
+                    // Short unset option (-u) is not allowed to contain '='
+                    if arg_str.contains('=')
+                        && arg_str.starts_with("-u")
+                        && !arg_str.starts_with("--")
+                    {
+                        return Err(USimpleError::new(
+                            125,
+                            format!("cannot unset '{}': Invalid argument", &arg_str[2..]),
+                        ));
+                    }
+
                     all_args.push(arg.clone());
                 }
             }


Test patch:
diff --git a/tests/by-util/test_env.rs b/tests/by-util/test_env.rs
index a1b13e02037..2b33f725dbe 100644
--- a/tests/by-util/test_env.rs
+++ b/tests/by-util/test_env.rs
@@ -882,6 +882,29 @@ fn test_env_arg_ignore_signal_empty() {
         .no_stderr()
         .stdout_contains("hello");
 }
+
+#[test]
+fn disallow_equals_sign_on_short_unset_option() {
+    let ts = TestScenario::new(util_name!());
+
+    ts.ucmd()
+        .arg("-u=")
+        .fails()
+        .code_is(125)
+        .stderr_contains("env: cannot unset '=': Invalid argument");
+    ts.ucmd()
+        .arg("-u=A1B2C3")
+        .fails()
+        .code_is(125)
+        .stderr_contains("env: cannot unset '=A1B2C3': Invalid argument");
+    ts.ucmd().arg("--split-string=A1B=2C3=").succeeds();
+    ts.ucmd()
+        .arg("--unset=")
+        .fails()
+        .code_is(125)
+        .stderr_contains("env: cannot unset '': Invalid argument");
+}
+
 #[cfg(test)]
 mod tests_split_iterator {