]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
env: reject bogus -u arguments
authorEric Blake <ebb9@byu.net>
Mon, 26 Oct 2009 13:10:51 +0000 (07:10 -0600)
committerEric Blake <ebb9@byu.net>
Tue, 27 Oct 2009 03:30:30 +0000 (21:30 -0600)
* src/env.c (main): Use unsetenv rather than putenv to remove
items from environ, and check for failure.
* bootstrap.conf (gnulib_modules): Add unsetenv.
* tests/misc/env: Test this.
* NEWS: Document it.

NEWS
bootstrap.conf
src/env.c
tests/misc/env

diff --git a/NEWS b/NEWS
index 53992299a74c064750e0b65297692128a42cd46a..abbeb2761b94649a74e29e47e2f00d88ebf88247 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   Even then, chcon may still be useful.
   [bug introduced in coreutils-8.0]
 
+  env -u A=B now fails, rather than silently adding A to the
+  environment.  [the bug dates back to the initial implementation]
+
   md5sum now prints checksums atomically so that concurrent
   processes will not intersperse their output.
   This also affected sum, sha1sum, sha224sum, sha384sum and sha512sum.
index f26dfcb4b2132db11d2fa87ff7dbb60a3071d0eb..4c0f4c7b062a7c66f7ac59de2217aa764e2186e7 100644 (file)
@@ -217,6 +217,7 @@ gnulib_modules="
   unistd-safer
   unlink-busy
   unlocked-io
+  unsetenv
   update-copyright
   uptime
   useless-if-before-free
index ee5e6b6ceb9a4d8085a4869eb6e563c09e4729f5..02d155d42f225240f3dc8cc9b6a41374e8867365 100644 (file)
--- a/src/env.c
+++ b/src/env.c
@@ -83,6 +83,7 @@
 
 #include "system.h"
 #include "error.h"
+#include "quote.h"
 
 /* The official name of this program (e.g., no `g' prefix).  */
 #define PROGRAM_NAME "env"
@@ -170,14 +171,19 @@ main (int argc, char **argv)
 
   optind = 0;                  /* Force GNU getopt to re-initialize. */
   while ((optc = getopt_long (argc, argv, "+iu:", longopts, NULL)) != -1)
-    if (optc == 'u')
-      putenv (optarg);         /* Requires GNU putenv. */
+    if (optc == 'u' && unsetenv (optarg))
+      error (EXIT_CANCELED, errno, _("cannot unset %s"), quote (optarg));
 
   if (optind < argc && STREQ (argv[optind], "-"))
     ++optind;
 
   while (optind < argc && strchr (argv[optind], '='))
-    putenv (argv[optind++]);
+    if (putenv (argv[optind++]))
+      {
+        char *name = argv[optind - 1];
+        *(strchr (name, '=')) = '\0';
+        error (EXIT_CANCELED, errno, _("cannot set %s"), quote (name));
+      }
 
   /* If no program is specified, print the environment and exit. */
   if (argc <= optind)
index 1e0a22eaef5d737622e25b4851b12d5f3459dc9f..07dd9e468c4e94cef807f46a8e3c94b7aba03510 100755 (executable)
@@ -48,7 +48,7 @@ env sh -c 'exit 2' # exit status propagation
 test $? = 2 || fail=2
 env . # invalid command
 test $? = 126 || fail=1
-env ... # no such command
+env no_such # no such command
 test $? = 127 || fail=1
 
 # Cygwin requires a minimal environment to launch new processes, so a
@@ -105,8 +105,10 @@ esac
 # test "x`env c=d echo fail`" = xfail || fail=1
 # test "x`env -- c=d echo fail`" = xpass || fail=1
 
-# FIXME - decide whether we like this behavior
-# test `env -i -u a=b` = a=b || fail=1
-# env -u '' true || fail=1
+# catch unsetenv failure, broken through coreutils 8.0
+env -u a=b true && fail=1
+test $? = 125 || fail=1
+env -u '' true && fail=1
+test $? = 125 || fail=1
 
 Exit $fail