]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
In posix mode, `command -v' should print absolute pathnames; sanitize command and...
authorChet Ramey <chet.ramey@case.edu>
Wed, 1 Jul 2026 14:49:08 +0000 (10:49 -0400)
committerChet Ramey <chet.ramey@case.edu>
Wed, 1 Jul 2026 14:49:08 +0000 (10:49 -0400)
18 files changed:
CWRU/CWRU.chlog
builtins/builtin.def
builtins/command.def
builtins/enable.def
builtins/evalfile.c
builtins/evalstring.c
builtins/exec.def
builtins/hash.def
builtins/help.def
builtins/history.def
builtins/source.def
builtins/type.def
doc/bash.1
doc/bashref.texi
execute_cmd.c
redir.c
shell.c
variables.c

index 1e52d76f4d88101f90e4667e02888e40b0200132..7d1e3999cac5324085f1a859112ef746bbb4c4d1 100644 (file)
@@ -13027,3 +13027,29 @@ arrayfunc.c
        - convert_var_to_{array,assoc}: only save the old value if the variable
          isn't an array; dispose old value appropriately
          Report and patch from Grisha Levit <grishalevit@gmail.com>
+
+                                  6/15
+                                  ----
+builtins/type.def
+       - describe_command: even if the command name contains a slash, if the
+         flags include CDESC_ABSPATH, convert to an absolute pathname if it
+         doesn't begin with a slash
+
+builtins/command.def
+       - command_builtin: in posix mode, `command -v' adds CDESC_ABSPATH
+         to the flags passed to describe_command() so it prints as an
+         absolute pathname
+         From a discussion on the dash mailing list about POSIX requirements
+
+redir.c
+       - redirection_error: make sure to sanitize command names using
+         printable_filename before printing error messages
+         Report from Vincent Lefevre <vincent@vinc17.net>
+
+execute_cmd.c,shell.c,variables.c
+builtins/evalfile.c,builtins/evalstring.c
+builtins/builtin.def,builtins/command.def,builtins/enable.def
+builtins/exec.def,builtins/hash.def,builtins/help.def,builtins/history.def
+builtins/source.def,builtins/type.def
+       - sanitize command and file names used in error messages by calling
+         printable_filename
index 70e5a5ce3a2c70a78909d6f1d5049feaeca31bb2..917ec4d79f87768d0ddd68527365592cfb2fca64 100644 (file)
@@ -53,7 +53,7 @@ int
 builtin_builtin (WORD_LIST *list)
 {
   sh_builtin_func_t *function;
-  register char *command;
+  char *command, *newname;
   int r;
 
   if (r = no_options (list))
@@ -72,7 +72,10 @@ builtin_builtin (WORD_LIST *list)
 
   if (function == 0)
     {
-      sh_notbuiltin (command);
+      newname = printable_filename (command, 0);
+      sh_notbuiltin (newname);
+      if (newname != command)
+       free (newname);
       return (EXECUTION_FAILURE);
     }
   else
index 21cc982b5837a3c1489c0bf9981597c4bb2e0e99..afb81ade6234a843550fa0162cc7c468599d33a9 100644 (file)
@@ -83,7 +83,7 @@ command_builtin (WORD_LIST *list)
          verbose = CDESC_SHORTDESC|CDESC_ABSPATH;      /* look in common.h for constants */
          break;
        case 'v':
-         verbose = CDESC_REUSABLE;     /* ditto */
+         verbose = CDESC_REUSABLE| (posixly_correct ? CDESC_ABSPATH : 0);      /* ditto */
          break;
        CASE_HELPOPT;
        default:
@@ -107,13 +107,19 @@ command_builtin (WORD_LIST *list)
   if (verbose)
     {
       int found, any_found;
+      char *newfn;
 
       for (any_found = 0; list; list = list->next)
        {
          found = describe_command (list->word->word, verbose|use_standard_path);
 
          if (found == 0 && verbose != CDESC_REUSABLE)
-           sh_notfound (list->word->word);
+           {
+             newfn = printable_filename (list->word->word, 0);
+             sh_notfound (newfn);
+             if (newfn != list->word->word)
+               free (newfn);
+           }
 
          any_found += found;
        }
index 72da559cfecc0b48bc93aa31017fc5d112d5ee1b..afcc87d622fa6b6553e778e221b96a7772d7e4e6 100644 (file)
@@ -1,7 +1,7 @@
 This file is enable.def, from which is created enable.c.
 It implements the builtin "enable" in Bash.
 
-Copyright (C) 1987-2024 Free Software Foundation, Inc. 
+Copyright (C) 1987-2026 Free Software Foundation, Inc. 
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -224,7 +224,7 @@ enable_builtin (WORD_LIST *list)
     {
       while (list)
        {
-         char *command;
+         char *command, *newname;
 
          command = list->word->word;
          opt = enable_shell_command (command, flags & NFLAG);
@@ -258,7 +258,10 @@ enable_builtin (WORD_LIST *list)
 
          if (opt == EX_NOTFOUND)
            {
-             sh_notbuiltin (command);
+             newname = printable_filename (command, 0);
+             sh_notbuiltin (newname);
+             if (newname != command)
+               free (newname);
              result = EXECUTION_FAILURE;
            }
          else if (opt != EXECUTION_SUCCESS)
@@ -405,7 +408,10 @@ dyn_load_builtin (WORD_LIST *list, int flags, char *filename)
       name = list->word->word;
       if (absolute_program (name))
        {
+         name = printable_filename (list->word->word, 0);
          builtin_error (_("%s: builtin names may not contain slashes"), name);
+         if (name != list->word->word)
+           free (name);
          continue;
        }
 
@@ -549,7 +555,7 @@ dyn_unload_builtin (char *name)
 {
   struct builtin *b;
   void *handle;
-  char *funcname;
+  char *funcname, *newname;
   sh_unload_func_t *unloadfunc;
   int ref, i;
   size_t size;
@@ -557,12 +563,18 @@ dyn_unload_builtin (char *name)
   b = builtin_address_internal (name, 1);
   if (b == 0)
     {
-      sh_notbuiltin (name);
+      newname = printable_filename (name, 0);
+      sh_notbuiltin (newname);
+      if (newname != name)
+       free (newname);
       return (EXECUTION_FAILURE);
     }
   if (b->flags & STATIC_BUILTIN)
     {
-      builtin_error (_("%s: not dynamically loaded"), name);
+      newname = printable_filename (name, 0);
+      builtin_error (_("%s: not dynamically loaded"), newname);
+      if (newname != name)
+       free (newname);
       return (EXECUTION_FAILURE);
     }
 
@@ -588,7 +600,10 @@ dyn_unload_builtin (char *name)
      using it drops to zero. */
   if (ref == 1 && local_dlclose (handle) != 0)
     {
-      builtin_error (_("%s: cannot delete: %s"), name, dlerror ());
+      newname = printable_filename (name, 0);
+      builtin_error (_("%s: cannot delete: %s"), newname, dlerror ());
+      if (newname != name)
+       free (newname);
       return (EXECUTION_FAILURE);
     }
 
index ea0a205ae289191ba8298dee24c8ffee4aef12e7..f3b2aa5bd18db698846d8955c6cddf2be0b37b27 100644 (file)
@@ -1,6 +1,6 @@
 /* evalfile.c - read and evaluate commands from a file or file descriptor */
 
-/* Copyright (C) 1996-2017,2022-2024 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2026 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -118,7 +118,12 @@ evalfile_internal (const char *filename, int flags)
 
 file_error_and_exit:
       if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)
-       file_error (filename);
+       {
+         t = printable_filename ((char *)filename, 0);
+         file_error (t);
+         if (t != filename)
+           free (t);
+       }
 
       if (flags & FEVAL_LONGJMP)
        {
@@ -134,13 +139,19 @@ file_error_and_exit:
 
   if (S_ISDIR (finfo.st_mode))
     {
-      (*errfunc) (_("%s: is a directory"), filename);
+      t = printable_filename ((char *)filename, 0);
+      (*errfunc) (_("%s: is a directory"), t);
+      if (t != filename)
+       free (t);
       close (fd);
       return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
     }
   else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0)
     {
-      (*errfunc) (_("%s: not a regular file"), filename);
+      t = printable_filename ((char *)filename, 0);
+      (*errfunc) (_("%s: not a regular file"), t);
+      if (t != filename)
+       free (t);
       close (fd);
       return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
     }
index b21cfba4d01933586d782d0bbf47a43ef43c7baa..4b1cc9eed8c127d89704766c576437575fbe5ddb 100644 (file)
@@ -1,6 +1,6 @@
 /* evalstring.c - evaluate a string as one or more shell commands. */
 
-/* Copyright (C) 1996-2025 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2026 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -761,7 +761,7 @@ out:
 int
 open_redir_file (REDIRECT *r, char **fnp)
 {
-  char *fn;
+  char *fn, *newfn;
   int fd;
 
   if (r->instruction != r_input_direction)
@@ -783,7 +783,10 @@ open_redir_file (REDIRECT *r, char **fnp)
   fd = open(fn, O_RDONLY);
   if (fd < 0)
     {
-      internal_error ("%s: %s", fn, strerror (errno));
+      newfn = printable_filename (fn, 0);
+      internal_error ("%s: %s", newfn, strerror (errno));
+      if (newfn != fn)
+       free (newfn);
       free (fn);
       if (fnp)
        *fnp = 0;
index 285f9ddfea992e43fdd6e546faeeef064f58a978..8bb9ed36c3263a72aa1d495605adf8b603b6f0f4 100644 (file)
@@ -1,7 +1,7 @@
 This file is exec.def, from which is created exec.c.
 It implements the builtin "exec" in Bash.
 
-Copyright (C) 1987-2021,2022,2024,2025 Free Software Foundation, Inc.
+Copyright (C) 1987-2021,2022,2024-2026 Free Software Foundation, Inc.
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -152,20 +152,23 @@ exec_builtin (WORD_LIST *list)
 
   if (command == 0)
     {
+      newname = printable_filename (args[0], 0);
       if (file_isdir (args[0]))
        {
 #if defined (EISDIR)
-         builtin_error ("%s: %s: %s", args[0], _("cannot execute"), strerror (EISDIR));
+         builtin_error ("%s: %s: %s", newname, _("cannot execute"), strerror (EISDIR));
 #else
-         builtin_error ("%s: %s: %s", args[0], _("cannot execute"), strerror (errno));
+         builtin_error ("%s: %s: %s", newname, _("cannot execute"), strerror (errno));
 #endif
          exit_value = EX_NOEXEC;
        }
       else
        {
-         sh_notfound (args[0]);
+         sh_notfound (newname);
          exit_value = EX_NOTFOUND;     /* As per Posix.2, 3.14.6 */
        }
+      if (newname != args[0])
+       free (newname);
       goto failed_exec;
     }
 
index fc96d59460f2b2ad75ba26f3d4a3b6e47c4e3024..57c3bb7fad433b1fd03005a31558f641e4b528f8 100644 (file)
@@ -1,7 +1,7 @@
 This file is hash.def, from which is created hash.c.
 It implements the builtin "hash" in Bash.
 
-Copyright (C) 1987-2024 Free Software Foundation, Inc.
+Copyright (C) 1987-2026 Free Software Foundation, Inc.
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -81,7 +81,7 @@ int
 hash_builtin (WORD_LIST *list)
 {
   int expunge_hash_table, list_targets, list_portably, delete, opt;
-  char *w, *pathname;
+  char *w, *pathname, *newfn;
 
   if (hashing_enabled == 0)
     {
@@ -158,15 +158,21 @@ hash_builtin (WORD_LIST *list)
     {
       if (absolute_program (pathname))
        {
-          sh_restricted (pathname);
-          return (EXECUTION_FAILURE);
+         newfn = printable_filename (pathname, 0);
+         sh_restricted (newfn);
+         if (newfn != pathname)
+           free (newfn);
+         return (EXECUTION_FAILURE);
        }
       /* If we are changing the hash table in a restricted shell, make sure the
         target pathname can be found using a $PATH search. */
       w = find_user_command (pathname);
       if (w == 0 || *w == 0 || executable_file (w) == 0)
        {
-         sh_notfound (pathname);
+         newfn = printable_filename (pathname, 0);
+         sh_notfound (newfn);
+         if (newfn != pathname)
+           free (newfn);
          free (w);
          return (EXECUTION_FAILURE);
        }
@@ -184,11 +190,14 @@ hash_builtin (WORD_LIST *list)
        {
          if (file_isdir (pathname))
            {
+             newfn = printable_filename (pathname, 0);
 #ifdef EISDIR
-             builtin_error ("%s: %s", pathname, strerror (EISDIR));
+             builtin_error ("%s: %s", newfn, strerror (EISDIR));
 #else
-             builtin_error (_("%s: is a directory"), pathname);
+             builtin_error (_("%s: is a directory"), newfn);
 #endif
+             if (newfn != pathname)
+               free (newfn);
              opt = EXECUTION_FAILURE;
            }
          else
@@ -198,7 +207,10 @@ hash_builtin (WORD_LIST *list)
        {
          if (phash_remove (w))
            {
-             sh_notfound (w);
+             newfn = printable_filename (w, 0);
+             sh_notfound (newfn);
+             if (newfn != w)
+               free (newfn);
              opt = EXECUTION_FAILURE;
            }
        }
@@ -214,7 +226,7 @@ static int
 add_hashed_command (char *w, int quiet)
 {
   int rv;
-  char *full_path;
+  char *full_path, *newfn;
 
   rv = 0;
   if (find_function (w) == 0 && find_shell_builtin (w) == 0)
@@ -226,7 +238,12 @@ add_hashed_command (char *w, int quiet)
       else
        {
          if (quiet == 0)
-           sh_notfound (w);
+           {
+             newfn = printable_filename (w, 0);
+             sh_notfound (newfn);
+             if (newfn != w)
+               free (newfn);
+           }
          rv++;
        }
       FREE (full_path);
@@ -273,7 +290,7 @@ static int
 list_hashed_filename_targets (WORD_LIST *list, int fmt)
 {
   int all_found, multiple;
-  char *target;
+  char *target, *fp, *fn;
   WORD_LIST *l;
 
   all_found = 1;
@@ -281,21 +298,32 @@ list_hashed_filename_targets (WORD_LIST *list, int fmt)
 
   for (l = list; l; l = l->next)
     {
+      fn = printable_filename (l->word->word, 1);
       target = phash_search (l->word->word);
       if (target == 0)
        {
          all_found = 0;
-         sh_notfound (l->word->word);
+         sh_notfound (fn);
+         if (fn != l->word->word)
+           free (fn);
          continue;
        }
+      fp = printable_filename (target, 1);
+      if (fp != target)
+       {
+         free (target);
+         target = fp;
+       }
       if (fmt)
-       printf ("builtin hash -p %s %s\n", target, l->word->word);
+       printf ("builtin hash -p %s %s\n", target, fn);
       else
        {
          if (multiple)
-           printf ("%s\t", l->word->word);
+           printf ("%s\t", fn);
          printf ("%s\n", target);
        }
+      if (fn != l->word->word)
+       free (fn);
       free (target);
     }
 
index f2a975bcb81ebd29dbc956ac636bb68604029675..7f0fd0cc1a75f7da213bc2763b1493b73cecb0db 100644 (file)
@@ -1,7 +1,7 @@
 This file is help.def, from which is created help.c.
 It implements the builtin "help" in Bash.
 
-Copyright (C) 1987-2025 Free Software Foundation, Inc.
+Copyright (C) 1987-2026 Free Software Foundation, Inc.
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -207,11 +207,15 @@ static int
 open_helpfile (const char *name)
 {
   int fd;
+  char *newfn;
 
   fd = open (name, O_RDONLY);
   if (fd == -1)
     {
-      builtin_error ("%s: %s: %s", name, _("cannot open"), strerror (errno));
+      newfn = printable_filename (name, 0);
+      builtin_error ("%s: %s: %s", newfn, _("cannot open"), strerror (errno));
+      if (newfn != name)
+       free (newfn);
       return -1;
     }
   return fd;
index 1aa1966c0bd051e0a77e4a4412394dd009fec3ce..9659dbcdde507a70d19a3827eff2cdf76816a6ad 100644 (file)
@@ -132,7 +132,7 @@ int
 history_builtin (WORD_LIST *list)
 {
   int flags, opt, result, old_history_lines, obase, ind;
-  char *filename, *delete_arg, *range;
+  char *filename, *newfn, *delete_arg, *range;
   intmax_t delete_offset;
 
   flags = 0;
@@ -281,7 +281,10 @@ history_builtin (WORD_LIST *list)
 #if defined (RESTRICTED_SHELL)
   if (restricted && absolute_program (filename))
     {
-      sh_restricted (filename);
+      newfn = printable_filename (filename, 0);
+      sh_restricted (newfn);
+      if (newfn != filename)
+       free (newfn);
       return (EXECUTION_FAILURE);
     }
 #endif
@@ -351,6 +354,8 @@ history_builtin (WORD_LIST *list)
 static void
 history_error (const char *filename, int e, int r)
 {
+  char *newfn;
+
   switch (e)
     {
       case ENOENT:
@@ -361,10 +366,13 @@ history_error (const char *filename, int e, int r)
 #if defined (EACCES)
       case EACCES:
 #endif
+       newfn = printable_filename ((char *)filename, 0);
        if (r)
-         builtin_error ("%s: %s: %s", filename, _("read error"), strerror (e));
+         builtin_error ("%s: %s: %s", newfn, _("read error"), strerror (e));
        else
-         builtin_error ("%s: %s: %s", filename, _("write error"), strerror (e));
+         builtin_error ("%s: %s: %s", newfn, _("write error"), strerror (e));
+       if (newfn != filename)
+         free (newfn);
        break;
 
       default:
index 4e292a902d6cf8002f353a3096267b1682c0fa17..687b15955044cfa33d22b8128c16aa15a8c4aa1b 100644 (file)
@@ -150,7 +150,10 @@ source_builtin (WORD_LIST *list)
 #if defined (RESTRICTED_SHELL)
   if (restricted && (pathstring || absolute_program (list->word->word)))
     {
-      sh_restricted (list->word->word);
+      filename = printable_filename (list->word->word, 0);
+      sh_restricted (filename);
+      if (filename != list->word->word)
+       free (filename);
       return (EXECUTION_FAILURE);
     }
 #endif
index 8e1931b20df4b70775ea1cef2fff5cb10dd68a54..84ecc5b0133b076942c8d338b0cbef766ac74dc9 100644 (file)
@@ -1,7 +1,7 @@
 This file is type.def, from which is created type.c.
 It implements the builtin "type" in Bash.
 
-Copyright (C) 1987-2023 Free Software Foundation, Inc.
+Copyright (C) 1987-2026 Free Software Foundation, Inc.
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -176,11 +176,17 @@ type_builtin (WORD_LIST *list)
   while (list)
     {
       int found;
+      char *newfn;
 
       found = describe_command (list->word->word, dflags);
 
       if (!found && (dflags & (CDESC_PATH_ONLY|CDESC_TYPE)) == 0)
-       sh_notfound (list->word->word);
+       {
+         newfn = printable_filename (list->word->word, 0);
+         sh_notfound (newfn);
+         if (newfn != list->word->word)
+           free (newfn);
+       }
 
       any_failed += found == 0;
       list = list->next;
@@ -335,12 +341,21 @@ describe_command (char *command, int dflags)
       f = file_status (command);
       if (f & FS_EXECABLE)
        {
+         /* convert to absolute pathname? */
+         if ((dflags & CDESC_ABSPATH) && ABSPATH (command) == 0)
+           full_path = sh_makepath ((char *)NULL, command, MP_DOCWD|MP_RMDOT);
+         else
+           full_path = command;
+             
          if (dflags & CDESC_TYPE)
            puts ("file");
          else if (dflags & CDESC_SHORTDESC)
-           printf (_("%s is %s\n"), command, command);
+           printf (_("%s is %s\n"), command, full_path);
          else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY))
-           printf ("%s\n", command);
+           printf ("%s\n", full_path);
+
+         if (full_path != command)
+           free (full_path);
 
          /* There's no use looking in the hash table or in $PATH,
             because they're not consulted when an absolute program
index 8a2f99bbd376b6b13a157a7425878a112930b877..e42b8adc72af06193072d720df24f7eb697acc2a 100644 (file)
@@ -6632,7 +6632,9 @@ A backslash.
 Begin a sequence of non-printing characters, which could be used to
 embed a terminal control sequence into the prompt.
 This escape is only useful when the prompt will be supplied to
-\fBreadline\fP, so it shouldn't be used in \fBPS0\fP or \fBPS4\fP
+\fBreadline\fP,
+and is ignored and removed otherwise,
+so it shouldn't be used in \fBPS0\fP or \fBPS4\fP
 or when line editing is not enabled.
 .TP
 .B \e]
index 3ff7683adc35c697a2dcb55c69bc042c1f0c081a..b6b9db4419d32d0bac64bbac5854d07ec82194aa 100644 (file)
@@ -9158,7 +9158,9 @@ Begin a sequence of non-printing characters.
 This could be used to
 embed a terminal control sequence into the prompt.
 This escape is only useful when the prompt will be supplied to
-Readline, so it shouldn't be used in @env{PS0} or @env{PS4},
+Readline,
+and is ignored and removed otherwise,
+so it shouldn't be used in @env{PS0} or @env{PS4},
 or when line editing is not enabled.
 
 @item \]
@@ -9613,6 +9615,10 @@ constructed from @code{$PWD} and the directory name supplied as an argument
 exceeds @code{PATH_MAX} when canonicalized, @code{cd} will
 attempt to use the supplied directory name.
 
+@item
+The @code{command} builtin prints command name arguments containing a
+slash as full pathnames when the @option{-v} option is supplied.
+
 @item
 When the @code{xpg_echo} option is enabled, Bash does not attempt to
 interpret any arguments to @code{echo} as options.
index 9cfe5b35939aa0ebb7491d555f1a8dc993a281d7..10c9ec46a16c6eac638a6204df90610a8edf0667 100644 (file)
@@ -5915,8 +5915,13 @@ execute_disk_command (WORD_LIST *words, REDIRECT *redirects, char *command_line,
   command = (char *)NULL;
   if (restricted && mbschr (pathname, '/'))
     {
+      char *newfn;
+
+      newfn = printable_filename (pathname, 0);
       internal_error (_("%s: restricted: cannot specify `/' in command names"),
-                   pathname);
+                   newfn);
+      if (newfn != pathname)
+       free (newfn);
       result = last_command_exit_value = EXECUTION_FAILURE;
 
       /* If we're not going to fork below, we must already be in a child
@@ -6291,7 +6296,7 @@ int
 shell_execve (char *command, char **args, char **env)
 {
   int i, fd, sample_len;
-  char sample[HASH_BANG_BUFSIZ];
+  char sample[HASH_BANG_BUFSIZ], *newfn;
   size_t larray;
 
   SETOSTYPE (0);               /* Some systems use for USG/POSIX semantics */
@@ -6306,22 +6311,24 @@ shell_execve (char *command, char **args, char **env)
     {
       /* make sure this is set correctly for file_error/report_error */
       last_command_exit_value = (i == ENOENT) ?  EX_NOTFOUND : EX_NOEXEC; /* XXX Posix.2 says that exit status is 126 */
+      newfn = printable_filename (command, 0);
+
       if (file_isdir (command))
 #if defined (EISDIR)
-       internal_error ("%s: %s", command, strerror (EISDIR));
+       internal_error ("%s: %s", newfn, strerror (EISDIR));
 #else
-       internal_error (_("%s: is a directory"), command);
+       internal_error (_("%s: is a directory"), newfn);
 #endif
       else if (executable_file (command) == 0)
        {
          errno = i;
-         file_error (command);
+         file_error (newfn);
        }
       /* errors not involving the path argument to execve. */
       else if (i == E2BIG || i == ENOMEM)
        {
          errno = i;
-         file_error (command);
+         file_error (newfn);
        }
       else
        {
@@ -6346,23 +6353,27 @@ shell_execve (char *command, char **args, char **env)
                  interp[ilen] = 'M';
                  interp[ilen + 1] = '\0';
                }
-             sys_error ("%s: %s: %s", command, interp, _("bad interpreter"));
+             sys_error ("%s: %s: %s", newfn, interp, _("bad interpreter"));
              FREE (interp);
-             return (EX_NOEXEC);
+             last_command_exit_value = EX_NOEXEC;
            }
          else
 #endif
          if (i == ENOENT)
            {
              errno = i;
-             internal_error (_("%s: cannot execute: required file not found"), command);
+             internal_error (_("%s: cannot execute: required file not found"), newfn);
            }
          else
            {
              errno = i;
-             file_error (command);
+             file_error (newfn);
            }
        }
+
+      if (newfn != command)
+       free (newfn);
+
       return (last_command_exit_value);
     }
 
@@ -6392,7 +6403,10 @@ shell_execve (char *command, char **args, char **env)
 #endif
       if (check_binary_file (sample, sample_len))
        {
-         internal_error ("%s: %s: %s", command, _("cannot execute binary file"), strerror (i));
+         newfn = printable_filename (command, 0);
+         internal_error ("%s: %s: %s", newfn, _("cannot execute binary file"), strerror (i));
+         if (newfn != command)
+           free (newfn);
          errno = i;
          return (EX_BINARY_FILE);
        }
diff --git a/redir.c b/redir.c
index 7c689ba83bf896069be199fc82ca37b581457fa9..4947fed73d0aecfbaab4c43e8e201faa3c2c6749 100644 (file)
--- a/redir.c
+++ b/redir.c
@@ -134,10 +134,11 @@ do { \
 void
 redirection_error (REDIRECT *temp, int error, char *fn)
 {
-  char *filename, *allocname;
+  char *filename, *allocname, *newfn;
   int oflags;
 
-  allocname = 0;
+  allocname = newfn = 0;
+
   if ((temp->rflags & REDIR_VARASSIGN) && error < 0)
     filename = allocname = savestring (temp->redirector.filename->word);
   else if ((temp->rflags & REDIR_VARASSIGN) == 0 && temp->redirector.dest < 0)
@@ -195,19 +196,21 @@ redirection_error (REDIRECT *temp, int error, char *fn)
   else
     filename = allocname = itos (temp->redirectee.dest);
 
+  newfn = printable_filename (filename, 0);
+
   switch (error)
     {
     case AMBIGUOUS_REDIRECT:
-      internal_error ("%s: %s", filename, _("ambiguous redirect"));
+      internal_error ("%s: %s", newfn, _("ambiguous redirect"));
       break;
 
     case NOCLOBBER_REDIRECT:
-      internal_error ("%s: %s", filename, _("cannot overwrite existing file"));
+      internal_error ("%s: %s", newfn, _("cannot overwrite existing file"));
       break;
 
 #if defined (RESTRICTED_SHELL)
     case RESTRICTED_REDIRECT:
-      internal_error ("%s: %s", filename, _("restricted: cannot redirect output"));
+      internal_error ("%s: %s", newfn, _("restricted: cannot redirect output"));
       break;
 #endif /* RESTRICTED_SHELL */
 
@@ -216,14 +219,17 @@ redirection_error (REDIRECT *temp, int error, char *fn)
       break;
 
     case BADVAR_REDIRECT:
-      internal_error ("%s: %s", filename, _("cannot assign fd to variable"));
+      internal_error ("%s: %s", newfn, _("cannot assign fd to variable"));
       break;
 
     default:
-      internal_error ("%s: %s", filename, strerror (error));
+      internal_error ("%s: %s", newfn, strerror (error));
       break;
     }
 
+  if (newfn != filename)
+    FREE (newfn);
+
   FREE (allocname);
 }
 
diff --git a/shell.c b/shell.c
index 5850c7e385810c90e6eb1f56492e691f90fd9ce7..ab0d1b6980c7b3bd770e83bf080264cefbe36973 100644 (file)
--- a/shell.c
+++ b/shell.c
@@ -1605,7 +1605,7 @@ open_shell_script (char *script_name)
   if (fd < 0)
     {
       e = errno;
-      file_error (filename);
+      file_error (printable_filename (filename, 0));
 #if defined (JOB_CONTROL)
       end_job_control ();      /* just in case we were run as bash -i script */
 #endif
@@ -1627,7 +1627,7 @@ open_shell_script (char *script_name)
 #else
       errno = EINVAL;
 #endif
-      file_error (filename);
+      file_error (printable_filename (filename, 0));
 #if defined (JOB_CONTROL)
       end_job_control ();      /* just in case we were run as bash -i script */
 #endif
@@ -1665,19 +1665,20 @@ open_shell_script (char *script_name)
       if (sample_len < 0)
        {
          e = errno;
+         t = printable_filename (filename, 0);
          if ((fstat (fd, &sb) == 0) && S_ISDIR (sb.st_mode))
            {
 #if defined (EISDIR)
              errno = EISDIR;
-             file_error (filename);
+             file_error (t);
 #else        
-             internal_error (_("%s: Is a directory"), filename);
+             internal_error (_("%s: Is a directory"), t);
 #endif
            }
          else
            {
              errno = e;
-             file_error (filename);
+             file_error (t);
            }
 #if defined (JOB_CONTROL)
          end_job_control ();   /* just in case we were run as bash -i script */
@@ -1686,7 +1687,8 @@ open_shell_script (char *script_name)
        }
       else if (sample_len > 0 && (check_binary_file (sample, sample_len)))
        {
-         internal_error ("%s: %s", filename, _("cannot execute binary file"));
+         t = printable_filename (filename, 0);
+         internal_error ("%s: %s", t, _("cannot execute binary file"));
 #if defined (JOB_CONTROL)
          end_job_control ();   /* just in case we were run as bash -i script */
 #endif
index 6b91a99764e4dd418e5c6faa8958cd90c0deebef..eb803efc2bc87b953e384d14ec3dc29135ad0271 100644 (file)
@@ -1719,13 +1719,16 @@ static SHELL_VAR *
 assign_hashcmd (SHELL_VAR *self, char *value, arrayind_t ind, char *key)
 {
 #if defined (RESTRICTED_SHELL)
-  char *full_path;
+  char *full_path, *newfn;
 
   if (restricted)
     {
       if (absolute_program (value))
        {
-         sh_restricted (value);
+         newfn = printable_filename (value, 0);
+         sh_restricted (newfn);
+         if (newfn != value)
+           free (newfn);
          return (SHELL_VAR *)NULL;
        }
       /* If we are changing the hash table in a restricted shell, make sure the
@@ -1733,7 +1736,10 @@ assign_hashcmd (SHELL_VAR *self, char *value, arrayind_t ind, char *key)
       full_path = find_user_command (value);
       if (full_path == 0 || *full_path == 0 || executable_file (full_path) == 0)
        {
-         sh_notfound (value);
+         newfn = printable_filename (value, 0);
+         sh_notfound (newfn);
+         if (newfn != value)
+           free (newfn);
          free (full_path);
          return ((SHELL_VAR *)NULL);
        }