In posix mode, `command -v' should print absolute pathnames; sanitize command and filenames used in error messages so they don't contain non-printable characters

This commit is contained in:
Chet Ramey
2026-07-01 10:49:08 -04:00
parent 8085ee1396
commit 76037847c3
18 changed files with 237 additions and 76 deletions
+26
View 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
+5 -2
View 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
+8 -2
View 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;
}
+22 -7
View 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);
}
+15 -4
View 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);
}
+6 -3
View 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;
+7 -4
View 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;
}
+42 -14
View 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);
}
+6 -2
View 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;
+12 -4
View 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:
+4 -1
View 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
+19 -4
View 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
+3 -1
View 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]
+7 -1
View 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.
+25 -11
View 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);
}
+13 -7
View File
@@ -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);
}
+8 -6
View File
@@ -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
+9 -3
View 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);
}