mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-29 00:19:51 +02:00
fix for -c command ending with backslash; fix several small memory leaks; fix several uninitialized variables; compgen -V fix
This commit is contained in:
@@ -6797,3 +6797,82 @@ lib/sh/anonfile.c
|
||||
- anonopen: use memfd_create if it is available, fall through to
|
||||
traditional Unix/POSIX implementation if it fails
|
||||
|
||||
6/20
|
||||
----
|
||||
parse.y
|
||||
- yy_string_unget: don't push EOF back to a string, like the other
|
||||
unget functions
|
||||
|
||||
6/21
|
||||
----
|
||||
parse.y
|
||||
- read_a_line: don't push an EOF back into the string or line if the
|
||||
line ends in a backslash.
|
||||
From a report by Rob Landley <rob@landley.net>
|
||||
|
||||
6/22
|
||||
----
|
||||
lib/readline/input.c
|
||||
- rl_gather_tyi: make sure result is initialized
|
||||
|
||||
lib/readline/kill.c
|
||||
- _rl_read_bracketed_paste_prefix: make sure key is initialized
|
||||
|
||||
builtins/read.def
|
||||
- read_builtin: make sure pass_next and saw_escape are initialized
|
||||
before a possible goto
|
||||
- read_builtin: make sure to initialize prevset for very short
|
||||
timeouts
|
||||
|
||||
subst.c
|
||||
- function_substitute: make sure tflag is initialized even when we
|
||||
don't call read_comsub, since we return it in ret->flags
|
||||
All from a report by Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
builtins/complete.def
|
||||
- compgen_builtin: use array_from_argv to assign elements of the
|
||||
stringlist to the array variable.
|
||||
Update from Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
builtins/cd.def
|
||||
- bindpwd: fix seg fault from an unlikely set of circumstances
|
||||
From a report by Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
arrayfunc.h
|
||||
- convert_validarray_flags_to_arrayval_flags: initialize avflags
|
||||
From a report by Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
lib/sh/anonfile.c
|
||||
- anonopen: set *fn if memfd_create is used
|
||||
From a report by Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
6/23
|
||||
----
|
||||
arrayfunc.c
|
||||
- bind_assoc_var_internal: free key to fix small leak if assign_func
|
||||
used
|
||||
- quote_compound_array_word: free value to fix small leak
|
||||
|
||||
builtins/evalstring.c
|
||||
- parse_and_execute: free parsed command on failed function definition
|
||||
import
|
||||
- open_redir_file: free FN if we're not passing it back to the caller
|
||||
|
||||
subst.c
|
||||
- param_expand: free TEMP1 in code paths that don't do it now
|
||||
|
||||
|
||||
bashline.c
|
||||
- bash_command_name_stat_hook: if we modify *NAME, free the old value
|
||||
|
||||
examples/loadables/{kv,stat}.c
|
||||
- bind_assoc_variable is caller-free VALUE, so free when needed and
|
||||
don't allocate a new copy if not
|
||||
All from a report by Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
6/24
|
||||
----
|
||||
lib/readline/complete.c
|
||||
- rl_menu_complete: use _rl_free_match_list instead of just freeing
|
||||
MATCHES if we have too many possible completions to display.
|
||||
From a report by Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
+5
-1
@@ -206,7 +206,10 @@ bind_assoc_var_internal (SHELL_VAR *entry, HASH_TABLE *hash, char *key, const ch
|
||||
newval = make_array_variable_value (entry, 0, key, value, flags);
|
||||
|
||||
if (entry->assign_func)
|
||||
(*entry->assign_func) (entry, newval, 0, key);
|
||||
{
|
||||
(*entry->assign_func) (entry, newval, 0, key);
|
||||
FREE (key);
|
||||
}
|
||||
else
|
||||
assoc_insert (hash, key, newval);
|
||||
|
||||
@@ -958,6 +961,7 @@ quote_compound_array_word (char *w, int type)
|
||||
if (t != w+ind)
|
||||
free (t);
|
||||
strcpy (nword + i, value);
|
||||
free (value);
|
||||
|
||||
return nword;
|
||||
}
|
||||
|
||||
@@ -163,6 +163,7 @@ convert_validarray_flags_to_arrayval_flags (int vflags)
|
||||
{
|
||||
int avflags;
|
||||
|
||||
avflags = 0;
|
||||
if (vflags & VA_NOEXPAND)
|
||||
avflags |= AV_NOEXPAND;
|
||||
if (vflags & VA_ONEWORD)
|
||||
|
||||
@@ -1922,6 +1922,7 @@ bash_command_name_stat_hook (char **name)
|
||||
result = search_for_command (cname, 0);
|
||||
if (result)
|
||||
{
|
||||
FREE (*name);
|
||||
*name = result;
|
||||
return 1;
|
||||
}
|
||||
|
||||
+2
-3
@@ -158,10 +158,9 @@ bindpwd (int no_symlinks)
|
||||
pwdvar = get_string_value ("PWD");
|
||||
|
||||
tvar = bind_variable ("OLDPWD", pwdvar, 0);
|
||||
if (tvar && readonly_p (tvar))
|
||||
if (tvar == 0 || readonly_p (tvar))
|
||||
r = EXECUTION_FAILURE;
|
||||
|
||||
if (old_anm == 0 && array_needs_making && exported_p (tvar))
|
||||
else if (old_anm == 0 && array_needs_making && exported_p (tvar))
|
||||
{
|
||||
update_export_env_inplace ("OLDPWD=", 7, pwdvar);
|
||||
array_needs_making = 0;
|
||||
|
||||
@@ -678,7 +678,6 @@ compgen_builtin (WORD_LIST *list)
|
||||
int old_ind, old_completion, old_quoting, old_suppress;
|
||||
SHELL_VAR *var;
|
||||
char *varname;
|
||||
WORD_LIST *alist;
|
||||
|
||||
if (list == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
@@ -763,11 +762,7 @@ compgen_builtin (WORD_LIST *list)
|
||||
var = builtin_find_indexed_array (varname, 1);
|
||||
if (var && sl && sl->list && sl->list_len)
|
||||
{
|
||||
alist = strlist_to_word_list (sl, 0, 0);
|
||||
assign_array_var_from_word_list (var, alist, 0);
|
||||
free (sl);
|
||||
sl = (STRINGLIST *)NULL;
|
||||
dispose_words (alist);
|
||||
array_from_argv (array_cell (var), sl->list, sl->list_len);
|
||||
rval = EXECUTION_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,6 +415,7 @@ parse_and_execute (char *string, const char *from_file, int flags)
|
||||
run_unwind_frame ("pe_dispose");
|
||||
last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */
|
||||
set_pipestatus_from_exit (last_command_exit_value);
|
||||
|
||||
if (subshell_environment)
|
||||
{
|
||||
should_jump_to_top_level = 1;
|
||||
@@ -468,6 +469,8 @@ parse_and_execute (char *string, const char *from_file, int flags)
|
||||
should_jump_to_top_level = 0;
|
||||
last_result = last_command_exit_value = EX_BADUSAGE;
|
||||
set_pipestatus_from_exit (last_command_exit_value);
|
||||
dispose_command (command);
|
||||
global_command = (COMMAND *)NULL;
|
||||
reset_parser ();
|
||||
break;
|
||||
}
|
||||
@@ -766,6 +769,9 @@ open_redir_file (REDIRECT *r, char **fnp)
|
||||
|
||||
if (fnp)
|
||||
*fnp = fn;
|
||||
else
|
||||
free (fn);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
+7
-3
@@ -403,6 +403,9 @@ read_builtin (WORD_LIST *list)
|
||||
input_string = (char *)xmalloc (size = 112); /* XXX was 128 */
|
||||
input_string[0] = '\0';
|
||||
|
||||
pass_next = 0; /* Non-zero signifies last char was backslash. */
|
||||
saw_escape = 0; /* Non-zero signifies that we saw an escape char */
|
||||
|
||||
/* More input and options validation */
|
||||
if (nflag == 1 && nchars == 0)
|
||||
{
|
||||
@@ -428,6 +431,8 @@ read_builtin (WORD_LIST *list)
|
||||
sigemptyset (&chldset);
|
||||
sigprocmask (SIG_BLOCK, (sigset_t *)0, &chldset);
|
||||
sigaddset (&chldset, SIGCHLD);
|
||||
sigemptyset (&prevset);
|
||||
sigprocmask (SIG_SETMASK, (sigset_t *)0, &prevset);
|
||||
#endif
|
||||
|
||||
begin_unwind_frame ("read_builtin");
|
||||
@@ -463,9 +468,6 @@ read_builtin (WORD_LIST *list)
|
||||
add_unwind_protect (xfree, rlbuf);
|
||||
#endif
|
||||
|
||||
pass_next = 0; /* Non-zero signifies last char was backslash. */
|
||||
saw_escape = 0; /* Non-zero signifies that we saw an escape char */
|
||||
|
||||
if (tmsec > 0 || tmusec > 0)
|
||||
{
|
||||
/* Turn off the timeout if stdin is a regular file (e.g. from
|
||||
@@ -495,7 +497,9 @@ read_builtin (WORD_LIST *list)
|
||||
if (code)
|
||||
{
|
||||
reset_timeout ();
|
||||
#if defined (SIGCHLD)
|
||||
sigprocmask (SIG_SETMASK, &prevset, (sigset_t *)0);
|
||||
#endif
|
||||
|
||||
/* Tricky. The top of the unwind-protect stack is the free of
|
||||
input_string. We want to run all the rest and use input_string,
|
||||
|
||||
@@ -71,7 +71,7 @@ kvsplit (SHELL_VAR *v, char *line, char *dstring)
|
||||
else
|
||||
value = "";
|
||||
|
||||
return (bind_assoc_variable (v, name_cell (v), savestring (key), savestring (value), 0) != 0);
|
||||
return (bind_assoc_variable (v, name_cell (v), savestring (key), value, 0) != 0);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -330,6 +330,7 @@ loadstat (char *vname, SHELL_VAR *var, char *fname, int flags, char *fmt, struct
|
||||
key = savestring (arraysubs[i]);
|
||||
value = statval (i, fname, flags, fmt, sp);
|
||||
v = bind_assoc_variable (var, vname, key, value, ASS_FORCE);
|
||||
free (value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2868,7 +2868,7 @@ rl_menu_complete (int count, int ignore)
|
||||
if (rl_completion_query_items > 0 && match_list_size >= rl_completion_query_items)
|
||||
{
|
||||
rl_ding ();
|
||||
FREE (matches);
|
||||
_rl_free_match_list (matches);
|
||||
matches = (char **)0;
|
||||
full_completion = 1;
|
||||
return (0);
|
||||
|
||||
@@ -249,6 +249,7 @@ rl_gather_tyi (void)
|
||||
struct timeval timeout;
|
||||
#endif
|
||||
|
||||
result = -1;
|
||||
chars_avail = 0;
|
||||
input = 0;
|
||||
tty = fileno (rl_instream);
|
||||
|
||||
+1
-1
@@ -779,7 +779,7 @@ _rl_read_bracketed_paste_prefix (int c)
|
||||
pbpref = BRACK_PASTE_PREF; /* XXX - debugging */
|
||||
if (c != pbpref[0])
|
||||
return (0);
|
||||
pbuf[ind = 0] = c;
|
||||
pbuf[ind = 0] = key = c;
|
||||
while (ind < BRACK_PASTE_SLEN-1 &&
|
||||
(RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) &&
|
||||
_rl_pushed_input_available () == 0 &&
|
||||
|
||||
+5
-1
@@ -55,7 +55,11 @@ anonopen (const char *name, int flags, char **fn)
|
||||
/* "Names do not affect the behavior of the file descriptor." */
|
||||
fd = memfd_create ("anonopen", 0);
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
{
|
||||
if (fn)
|
||||
*fn = 0;
|
||||
return fd;
|
||||
}
|
||||
/* If memfd_create fails, we fall through to the unlinked-regular-file
|
||||
implementation. */
|
||||
#endif
|
||||
|
||||
@@ -1696,6 +1696,9 @@ yy_string_get (void)
|
||||
static int
|
||||
yy_string_unget (int c)
|
||||
{
|
||||
if (c == EOF && *bash_input.location.string == '\0')
|
||||
return EOF;
|
||||
|
||||
*(--bash_input.location.string) = c;
|
||||
return (c);
|
||||
}
|
||||
@@ -2162,6 +2165,21 @@ read_a_line (int remove_quoted_newline)
|
||||
line_number++;
|
||||
continue; /* Make the unquoted \<newline> pair disappear. */
|
||||
}
|
||||
else if (peekc == EOF)
|
||||
{
|
||||
/* Don't push EOF back. */
|
||||
#if 1
|
||||
/* Leave this in for now, relies on how the expansion code
|
||||
treats an unescaped backslash at the end of a word. */
|
||||
RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
|
||||
if (expanding_alias() == 0 &&
|
||||
(bash_input.type == st_string || bash_input.type == st_bstream ||
|
||||
(interactive == 0 && bash_input.type == st_stream)))
|
||||
line_buffer[indx++] = '\\'; /* like below in shell_getc */
|
||||
#endif
|
||||
line_buffer[indx++] = c;
|
||||
c = '\n'; /* force break below */
|
||||
}
|
||||
else
|
||||
{
|
||||
yy_ungetc (peekc);
|
||||
|
||||
@@ -7016,12 +7016,12 @@ function_substitute (char *string, int quoted, int flags)
|
||||
|
||||
/* rewind back to the start of the file and read the contents */
|
||||
|
||||
tflag = 0;
|
||||
if (valsub == 0)
|
||||
{
|
||||
/* We call anonclose as part of the outer nofork unwind-protects */
|
||||
BLOCK_SIGNAL (SIGINT, set, oset);
|
||||
lseek (afd, 0, SEEK_SET);
|
||||
tflag = 0;
|
||||
istring = read_comsub (afd, quoted, flags, &tflag);
|
||||
UNBLOCK_SIGNAL (oset);
|
||||
}
|
||||
@@ -10840,6 +10840,7 @@ comsub:
|
||||
{
|
||||
chk_atstar (temp, quoted, pflags, quoted_dollar_at_p, contains_dollar_at);
|
||||
tdesc = parameter_brace_expand_word (temp, SPECIAL_VAR (temp, 0), quoted, pflags, 0);
|
||||
free (temp1);
|
||||
if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
|
||||
return (tdesc);
|
||||
ret = tdesc;
|
||||
@@ -10852,6 +10853,7 @@ comsub:
|
||||
{
|
||||
set_exit_status (EXECUTION_FAILURE);
|
||||
report_error (_("%s: invalid variable name for name reference"), temp);
|
||||
free (temp1);
|
||||
return (&expand_wdesc_error); /* XXX */
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user