mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-11 22:20:49 +02:00
fix issue with break in nofork comsub when expanding for command word list; add error message if the value of a nameref variable expands to an invalid variable name
This commit is contained in:
@@ -11563,3 +11563,26 @@ subst.c
|
||||
expand_word_leave_quoted: if call_expand_word_internal returns an
|
||||
error, return a NULL WORD_LIST *
|
||||
Fixes bug with PS1 expansion reported by smart.outfit080@8shield.net
|
||||
|
||||
config.h.in
|
||||
- MAJOR_IN_MKDEV: fix typo
|
||||
|
||||
8/8
|
||||
---
|
||||
execute_cmd.c
|
||||
- CHECK_BREAK_AND_CONTINUE: macro to encapsulate common code for
|
||||
testing `breaking' and `continuing' while in loops
|
||||
- execute_for_command,execute_arith_for_command,execute_select_command,
|
||||
execute_while_or_until: replace common code with CHECK_BREAK_AND_CONTINUE
|
||||
- execute_for_command,execute_select_command: add call to
|
||||
CHECK_BREAK_AND_CONTINUE after binding variable, in case it contains
|
||||
a nofork comsub that executes break or continue
|
||||
Report from Oğuz <oguzismailuysal@gmail.com>
|
||||
|
||||
8/11
|
||||
----
|
||||
builtins/declare.def
|
||||
- declare_internal: if the value of an assignment statement expands to
|
||||
an invalid value for a nameref variable, but the original value is
|
||||
valid, add an error message for the assignment error
|
||||
Report from Oğuz <oguzismailuysal@gmail.com>
|
||||
|
||||
@@ -1032,6 +1032,9 @@ restart_new_var_name:
|
||||
{
|
||||
if (valid_nameref_value (value, 1) == 0)
|
||||
sh_invalidid (value);
|
||||
/* what else can cause this to fail? */
|
||||
else if (flags_on & att_integer)
|
||||
builtin_error ("%s: expands to invalid variable name for name reference", value);
|
||||
assign_error++;
|
||||
/* XXX - unset this variable? or leave it as normal var? */
|
||||
if (created_var)
|
||||
|
||||
+1
-1
@@ -294,7 +294,7 @@
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define if major/minor/makedev is defined in <sys/mkdev.h> */
|
||||
#undef MAJOR_IN_MAKEDEV
|
||||
#undef MAJOR_IN_MKDEV
|
||||
|
||||
/* Define if major/minor/makedev is defined in <sys/sysmacros.h> */
|
||||
#undef MAJOR_IN_SYSMACROS
|
||||
|
||||
+24
-59
@@ -320,6 +320,21 @@ do { \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Common code to check whether `break' or `continue' was executed. */
|
||||
#define CHECK_BREAK_AND_CONTINUE() \
|
||||
if (breaking) \
|
||||
{ \
|
||||
breaking--; \
|
||||
break; \
|
||||
} \
|
||||
if (continuing) \
|
||||
{ \
|
||||
continuing--; \
|
||||
if (continuing) \
|
||||
break; \
|
||||
} \
|
||||
do { } while (0)
|
||||
|
||||
/* A sort of function nesting level counter */
|
||||
int funcnest = 0;
|
||||
int funcnest_max = 0;
|
||||
@@ -3079,6 +3094,8 @@ execute_for_command (FOR_COM *for_command)
|
||||
else
|
||||
v = bind_variable (identifier, list->word->word, 0);
|
||||
|
||||
CHECK_BREAK_AND_CONTINUE();
|
||||
|
||||
if (v == 0 || ASSIGN_DISALLOWED (v, 0))
|
||||
{
|
||||
line_number = save_line_number;
|
||||
@@ -3105,18 +3122,7 @@ execute_for_command (FOR_COM *for_command)
|
||||
REAP ();
|
||||
QUIT;
|
||||
|
||||
if (breaking)
|
||||
{
|
||||
breaking--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (continuing)
|
||||
{
|
||||
continuing--;
|
||||
if (continuing)
|
||||
break;
|
||||
}
|
||||
CHECK_BREAK_AND_CONTINUE();
|
||||
}
|
||||
|
||||
loop_level--; interrupt_execution--; retain_fifos--;
|
||||
@@ -3249,17 +3255,7 @@ execute_arith_for_command (ARITH_FOR_COM *arith_for_command)
|
||||
/* If the step or test expressions execute `break' or `continue' in a
|
||||
nofork command substitution or by some other means, break the loop
|
||||
here. */
|
||||
if (breaking)
|
||||
{
|
||||
breaking--;
|
||||
break;
|
||||
}
|
||||
if (continuing)
|
||||
{
|
||||
continuing--;
|
||||
if (continuing)
|
||||
break;
|
||||
}
|
||||
CHECK_BREAK_AND_CONTINUE();
|
||||
|
||||
if (expok == 0)
|
||||
break;
|
||||
@@ -3274,18 +3270,7 @@ execute_arith_for_command (ARITH_FOR_COM *arith_for_command)
|
||||
QUIT;
|
||||
|
||||
/* Handle any `break' or `continue' commands executed by the body. */
|
||||
if (breaking)
|
||||
{
|
||||
breaking--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (continuing)
|
||||
{
|
||||
continuing--;
|
||||
if (continuing)
|
||||
break;
|
||||
}
|
||||
CHECK_BREAK_AND_CONTINUE();
|
||||
|
||||
/* Evaluate the step expression. */
|
||||
line_number = arith_lineno;
|
||||
@@ -3601,23 +3586,14 @@ execute_select_command (SELECT_COM *select_command)
|
||||
|
||||
stupidly_hack_special_variables (identifier);
|
||||
|
||||
CHECK_BREAK_AND_CONTINUE();
|
||||
|
||||
retval = execute_command (select_command->action);
|
||||
|
||||
REAP ();
|
||||
QUIT;
|
||||
|
||||
if (breaking)
|
||||
{
|
||||
breaking--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (continuing)
|
||||
{
|
||||
continuing--;
|
||||
if (continuing)
|
||||
break;
|
||||
}
|
||||
CHECK_BREAK_AND_CONTINUE();
|
||||
|
||||
#if defined (KSH_COMPATIBLE_SELECT)
|
||||
show_menu = 0;
|
||||
@@ -3837,18 +3813,7 @@ execute_while_or_until (WHILE_COM *while_command, int type)
|
||||
|
||||
REAP ();
|
||||
|
||||
if (breaking)
|
||||
{
|
||||
breaking--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (continuing)
|
||||
{
|
||||
continuing--;
|
||||
if (continuing)
|
||||
break;
|
||||
}
|
||||
CHECK_BREAK_AND_CONTINUE();
|
||||
}
|
||||
loop_level--; interrupt_execution--;
|
||||
|
||||
|
||||
@@ -7514,8 +7514,13 @@ array_length_reference (const char *s)
|
||||
|
||||
/* If unbound variables should generate an error, report one and return
|
||||
failure. */
|
||||
#if 0 /*TAG:bash-5.4 myoga.murase@gmail.com 4/7/2025 */
|
||||
if ((var == 0 || invisible_p (var)) && unbound_vars_is_error)
|
||||
#else
|
||||
if ((var == 0 || invisible_p (var) || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error)
|
||||
#endif
|
||||
{
|
||||
unbound_array_error:
|
||||
set_exit_status (EXECUTION_FAILURE);
|
||||
#if 1
|
||||
/* If the array isn't subscripted with `@' or `*', it's an error. */
|
||||
@@ -7536,6 +7541,11 @@ array_length_reference (const char *s)
|
||||
/* We support a couple of expansions for variables that are not arrays.
|
||||
We'll return the length of the value for v[0], and 1 for v[@] or
|
||||
v[*]. Return 0 for everything else. */
|
||||
#if 0 /*TAG:bash-5.4 myoga.murase@gmail.com 4/7/2025 */
|
||||
/* If the variable is set, but not an array or assoc variable, nounset is
|
||||
enabled, and the subscript is not one of @, *, or 0, it is an error
|
||||
treated the same as in previous versions. */
|
||||
#endif
|
||||
|
||||
array = array_p (var) ? array_cell (var) : (ARRAY *)NULL;
|
||||
h = assoc_p (var) ? assoc_cell (var) : (HASH_TABLE *)NULL;
|
||||
@@ -7546,6 +7556,10 @@ array_length_reference (const char *s)
|
||||
return (h ? assoc_num_elements (h) : 0);
|
||||
else if (array_p (var))
|
||||
return (array ? array_num_elements (array) : 0);
|
||||
#if 0 /*TAG:bash-5.4 myoga.murase@gmail.com 4/7/2025 */
|
||||
else if (unbound_vars_is_error && var_isset (var) == 0)
|
||||
goto unbound_array_error; /* still non-fatal error */
|
||||
#endif
|
||||
else
|
||||
return (var_isset (var) ? 1 : 0);
|
||||
}
|
||||
@@ -7585,6 +7599,11 @@ array_length_reference (const char *s)
|
||||
}
|
||||
if (array_p (var))
|
||||
t = array_reference (array, ind);
|
||||
#if 0 /*TAG:bash-5.4 myoga.murase@gmail.com 4/7/2025 */
|
||||
/* if nounset is enabled, scalar variables may only be indexed with 0 */
|
||||
else if (unbound_vars_is_error && (var_isset (var) == 0 || ind != 0))
|
||||
goto unbound_array_error; /* still fatal error */
|
||||
#endif
|
||||
else
|
||||
t = (ind == 0) ? value_cell (var) : (char *)NULL;
|
||||
}
|
||||
|
||||
@@ -99,6 +99,11 @@ funsub
|
||||
in here-documents
|
||||
after all they work here
|
||||
and work here
|
||||
after for
|
||||
uname
|
||||
after arith for
|
||||
1) a[${ break;}]
|
||||
#? after select
|
||||
a b c == 1 2 3
|
||||
== 1 2 3
|
||||
before return
|
||||
|
||||
@@ -77,3 +77,21 @@ exec 4<&-
|
||||
|
||||
echo after all they ${word-$(echo work here)}
|
||||
echo and ${word-${ echo work here; }}
|
||||
|
||||
unset x
|
||||
|
||||
set -- 'a[${ break;}]'
|
||||
declare -in x
|
||||
|
||||
for x do :; done
|
||||
echo after for
|
||||
|
||||
true; for (( ; $? == 0; ${ ! break;} )); do echo uname; done
|
||||
echo after arith for
|
||||
|
||||
declare -i z
|
||||
select z in 'a[${ break;}]'
|
||||
do
|
||||
echo $z
|
||||
done <<<1
|
||||
echo after select
|
||||
|
||||
@@ -144,6 +144,11 @@ typedef struct _vlist {
|
||||
|
||||
#define attmask_scope 0x0f00000
|
||||
|
||||
/* Internal attributes used for variable state management. */
|
||||
#define att_assigning 0x1000000
|
||||
|
||||
#define attmask_state 0xf000000
|
||||
|
||||
#define exported_p(var) ((((var)->attributes) & (att_exported)))
|
||||
#define readonly_p(var) ((((var)->attributes) & (att_readonly)))
|
||||
#define array_p(var) ((((var)->attributes) & (att_array)))
|
||||
|
||||
Reference in New Issue
Block a user