From 243f1b1c71136171a4da635a84f8e32ba3eb3c94 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Mon, 26 Oct 2009 07:10:51 -0600 Subject: env: reject bogus -u arguments * 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 | 3 +++ bootstrap.conf | 1 + src/env.c | 12 +++++++++--- tests/misc/env | 10 ++++++---- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 53992299a..abbeb2761 100644 --- 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. diff --git a/bootstrap.conf b/bootstrap.conf index f26dfcb4b..4c0f4c7b0 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -217,6 +217,7 @@ gnulib_modules=" unistd-safer unlink-busy unlocked-io + unsetenv update-copyright uptime useless-if-before-free diff --git a/src/env.c b/src/env.c index ee5e6b6ce..02d155d42 100644 --- 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) diff --git a/tests/misc/env b/tests/misc/env index 1e0a22eae..07dd9e468 100755 --- a/tests/misc/env +++ b/tests/misc/env @@ -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 -- cgit v1.2.3-70-g09d2