- assign_array_element_internal: if the assignment failed, as tested by
ASSIGN_DISALLOWED, free the assoc array key we allocated
Report from Grisha Levit <grishalevit@gmail.com>
+
+ 6/3
+ ---
+variables.c
+ - bind_function_def: don't copy the command tree if we're overwriting
+ a function definition; after function binding, the function_def
+ struct never uses the saved command anyway
+ From a report and patch by Koichi Murase <myoga.murase@gmail.com>
+
+parse.y
+ - make sure to free WORD in coproc WORD COMMAND after creating the
+ coproc struct
+ Report and patch from Grisha Levit <grishalevit@gmail.com>
+
+builtins/exec.def
+ - exec_builtin: we don't need to set args to NULL; if shell_execve
+ reallocates args to add more items at the front, it has committed
+ to longjmp back to the top level
+ Report and patch from Grisha Levit <grishalevit@gmail.com>
+
+subst.c
+ - expand_word_internal: dispose of the list used for $@ if we're not
+ splitting and save the space-separated list back to tword->word
+ Report and patch from Grisha Levit <grishalevit@gmail.com>
+
+parse.y
+ - read_token: if we try to parse a conditional command and get a syntax
+ error, make sure to dispose of the partial command we created
+ Report and patch from Grisha Levit <grishalevit@gmail.com>
+ - read_token: if we try to parse a conditional command and get a syntax
+ error because we read an unexpected WORD, dispose of the WORD_DESC
+ before returning -1
+ Report and patch from Grisha Levit <grishalevit@gmail.com>
+ - cond_term: if we read a WORD where we expect something else, dispose
+ of the WORD_DESC before returning COND_ERROR
+ Report and patch from Grisha Levit <grishalevit@gmail.com>
var = find_variable (name);
if (var && local_p (var) && var->context == variable_context)
return var;
+ /* XXX - add check for previous scopes here if wanted 6/4/2024 */
return (find_global_variable (name));
}
else
exit_value = shell_execve (command, args, env);
opt = errno;
- /* We have to set this to NULL because shell_execve has called realloc()
- to stuff more items at the front of the array, which may have caused
- the memory to be freed by realloc(). We don't want to free it twice. */
- args = (char **)NULL;
if (cleanenv == 0)
adjust_shell_level (1);
{
$$ = make_coproc_command ($2->word, $3);
$$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
+ dispose_word ($2);
}
| COPROC WORD shell_command redirection_list
{
tc->redirects = $4;
$$ = make_coproc_command ($2->word, $3);
$$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
+ dispose_word ($2);
}
| COPROC simple_command
{
#if defined (COND_COMMAND)
if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
{
+ COMMAND *cond_command;
parser_state &= ~PST_CMDBLTIN;
cond_lineno = line_number;
parser_state |= PST_CONDEXPR;
- yylval.command = parse_cond_command ();
+ cond_command = parse_cond_command ();
if (cond_token != COND_END)
{
cond_error ();
+ if (cond_token == WORD)
+ dispose_word (yylval.word);
+ dispose_command (cond_command);
return (-1);
}
+ yylval.command = cond_command;
token_to_read = COND_END;
parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
return (COND_CMD);
else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
{
if (tok == WORD)
- dispose_word (yylval.word); /* not needed */
+ dispose_word (yylval.word); /* word not needed */
term = cond_term ();
if (term)
term->flags ^= CMD_INVERT_RETURN;
else
parser_error (line_number, _("conditional binary operator expected"));
dispose_cond_node (tleft);
+ if (tok == WORD)
+ dispose_word (yylval.word);
COND_RETURN_ERROR ();
}
else if (mkglobal && variable_context)
{
v = chklocal ? find_variable (name) : 0;
+ /* XXX - if we want to make chklocal search previous scopes, change here 2024/06/04 */
if (v && (local_p (v) == 0 || v->context != variable_context))
v = 0;
if (v == 0)
return, we expect to be able to split the results, but the
space separation means the right split doesn't happen. */
tword->word = string_list (list);
+ dispose_words (list);
}
else
tword->word = istring;
if (tlist->word->flags & W_ASSNGLOBAL)
omap['g'] = 1;
if (tlist->word->flags & W_CHKLOCAL)
- omap['G'] = 1;
+ omap['G'] = 1; /* internal, undocumented */
/* If we have special handling note the integer attribute and others
that transform the value upon assignment. What we do is take all
if (entry && (flags & 1))
{
dispose_function_def_contents (entry);
+ cmd = value->command;
+ value->command = 0;
entry = copy_function_def_contents (value, entry);
+ value->command = cmd;
}
else if (entry)
return;