fix for -c command ending with backslash; fix several small memory leaks; fix several uninitialized variables; compgen -V fix

This commit is contained in:
Chet Ramey
2023-06-26 16:23:10 -04:00
parent 293916f885
commit 81f7b44564
16 changed files with 133 additions and 18 deletions
+79
View File
@@ -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
View File
@@ -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;
}
+1
View File
@@ -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)
+1
View File
@@ -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
View File
@@ -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;
+1 -6
View File
@@ -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;
}
}
+6
View File
@@ -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
View File
@@ -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,
+1 -1
View File
@@ -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
+1
View File
@@ -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;
}
+1 -1
View File
@@ -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);
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
+18
View File
@@ -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);
+3 -1
View File
@@ -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