- 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>
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);
if (t != w+ind)
free (t);
strcpy (nword + i, value);
+ free (value);
return nword;
}
{
int avflags;
+ avflags = 0;
if (vflags & VA_NOEXPAND)
avflags |= AV_NOEXPAND;
if (vflags & VA_ONEWORD)
result = search_for_command (cname, 0);
if (result)
{
+ FREE (*name);
*name = result;
return 1;
}
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;
int old_ind, old_completion, old_quoting, old_suppress;
SHELL_VAR *var;
char *varname;
- WORD_LIST *alist;
if (list == 0)
return (EXECUTION_SUCCESS);
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;
}
}
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;
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;
}
if (fnp)
*fnp = fn;
+ else
+ free (fn);
+
return fd;
}
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)
{
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");
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
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,
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
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;
}
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);
struct timeval timeout;
#endif
+ result = -1;
chars_avail = 0;
input = 0;
tty = fileno (rl_instream);
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 &&
/* "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
static int
yy_string_unget (int c)
{
+ if (c == EOF && *bash_input.location.string == '\0')
+ return EOF;
+
*(--bash_input.location.string) = c;
return (c);
}
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);
/* 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);
}
{
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;
{
set_exit_status (EXECUTION_FAILURE);
report_error (_("%s: invalid variable name for name reference"), temp);
+ free (temp1);
return (&expand_wdesc_error); /* XXX */
}
else