Pádraig Brady <[email protected]> writes:

> On 31/07/2026 18:27, Collin Funk wrote:
>> I haven't looked at the patches yet, but I guess 'id', 'who', etc. might
>> as well be changed while we are at it. User and group names can
>> theoretically have bytes that are invalid characters in the current
>> locale. In practice, if you are using non-ASCII characters you are
>> probably asking for trouble.
> Yes good point.
> Though \n and other control chars aren't allowed in practice,
> so I'm leaning towards not quoting those as it's redundant.
> I'll think a bit more about it.

I also considered whether it may be worth quoting output of 'env' and
'printenv', which could be made ambiguous.

E.g., in the following example only "a" is an environment variable:

    $ env -i $'a=b\nd=c' printenv
    a=b
    d=c

But, I am not sure the quoted output makes it more understandable:

    $ env -i $'a=b\nd=c' ./src/printenv
    'a=b'$'\n''d=c'

Also, if you can't trust your parent process not to insert slop into
your environment variables, you probably have larger problems.

Here was the patch I used, anyways:

diff --git a/src/printenv.c b/src/printenv.c
index c2b1c69cd..a8082b925 100644
--- a/src/printenv.c
+++ b/src/printenv.c
@@ -32,6 +32,7 @@
 #include <sys/types.h>
 #include <getopt.h>
 
+#include "argmatch.h"  /* argmatch($QUOTING_STYLE).  */
 #include "system.h"
 
 /* Exit status for syntax errors, etc.  */
@@ -44,6 +45,8 @@ enum { PRINTENV_FAILURE = 2 };
   proper_name ("David MacKenzie"), \
   proper_name ("Richard Mlynarik")
 
+static bool quote_output;
+
 static struct option const longopts[] =
 {
   {"null", no_argument, NULL, '0'},
@@ -107,12 +110,24 @@ main (int argc, char **argv)
         }
     }
 
+  if (!opt_nul_terminate_output && isatty (STDOUT_FILENO))
+    {
+      int qs = getenv_quoting_style ();
+      if (qs < 0)
+        qs = shell_escape_quoting_style;
+      if (qs != literal_quoting_style)
+        {
+          set_quoting_style (NULL, qs);
+          quote_output = true;
+        }
+    }
+
   bool ok;
   if (optind >= argc)
     {
       for (char **env = environ; *env != NULL; ++env)
         {
-          fputs (*env, stdout);
+          fputs (quote_output ? quoteN (*env) : *env, stdout);
           putchar (opt_nul_terminate_output ? '\0' : '\n');
         }
       ok = true;
@@ -137,7 +152,7 @@ main (int argc, char **argv)
                 {
                   if (*ep == '=' && *ap == '\0')
                     {
-                      fputs (ep + 1, stdout);
+                      fputs (quote_output ? quoteN (ep + 1) : ep, stdout);
                       putchar (opt_nul_terminate_output ? '\0' : '\n');
                       matched = true;
                       break;

Collin

Reply via email to