additional changes to avoid array subscript double expansion in arithmetic contexts

This commit is contained in:
Chet Ramey
2021-05-10 09:58:14 -04:00
parent 35bc7025c1
commit b304aabc92
15 changed files with 235 additions and 25 deletions
+26
View File
@@ -1026,3 +1026,29 @@ builtin_unbind_variable (vname)
}
return (unbind_variable (vname));
}
/* **************************************************************** */
/* */
/* External interface to manipulate shell options */
/* */
/* **************************************************************** */
#if defined (ARRAY_VARS)
int
set_expand_once (nval, uwp)
int nval, uwp;
{
int oa;
oa = assoc_expand_once;
#if 0 /* TAG:bash-5.2 */
if (shell_compatibility_level > 51)
#endif
{
if (uwp)
unwind_protect_int (assoc_expand_once);
assoc_expand_once = nval;
}
return oa;
}
#endif
+9
View File
@@ -138,6 +138,10 @@ extern sh_builtin_func_t *builtin_address PARAMS((char *));
extern sh_builtin_func_t *find_special_builtin PARAMS((char *));
extern void initialize_shell_builtins PARAMS((void));
#if defined (ARRAY_VARS)
extern int set_expand_once PARAMS((int, int));
#endif
/* Functions from exit.def */
extern void bash_logout PARAMS((void));
@@ -243,6 +247,11 @@ extern int loop_level;
/* variables from shift.def */
extern int print_shift_error;
/* variables from shopt.def */
#if defined (ARRAY_VARS)
extern int expand_once_flag;
#endif
/* variables from source.def */
extern int source_searches_cwd;
extern int source_uses_path;
+6
View File
@@ -408,6 +408,12 @@ declare_internal (list, local_var)
#else
assoc_noexpand = 0;
#endif
/* XXX - we allow unbalanced brackets if assoc_noexpand is set, we count
brackets and make sure they match if assoc_noexpand is not set. So we
need to make sure we're checking assoc_noexpand and expand_once_flag
for backwards compatibility. We also use assoc_noexpand below when
we call assign_array_element, so we need to make sure they're
consistent in how they count brackets. */
offset = assignment (name, assoc_noexpand ? 2 : 0);
aflags = 0;
created_var = 0;
+25 -3
View File
@@ -72,7 +72,8 @@ extern char *strcpy ();
#define BUILTIN_FLAG_SPECIAL 0x01
#define BUILTIN_FLAG_ASSIGNMENT 0x02
#define BUILTIN_FLAG_LOCALVAR 0x04
#define BUILTIN_FLAG_POSIX_BUILTIN 0x08
#define BUILTIN_FLAG_POSIX_BUILTIN 0x08
#define BUILTIN_FLAG_ARRAYREF_ARG 0x10
#define BASE_INDENT 4
@@ -173,11 +174,22 @@ char *posix_builtins[] =
(char *)NULL
};
/* The builtin commands that can take array references as arguments and pay
attention to `assoc_expand_once'. These are the ones that don't assign
values, but need to avoid double expansions. */
char *arrayvar_builtins[] =
{
"declare", "let", "local", "printf", "read", "test", "[",
"typeset", "unset", "wait", /*]*/
(char *)NULL
};
/* Forward declarations. */
static int is_special_builtin ();
static int is_assignment_builtin ();
static int is_localvar_builtin ();
static int is_posix_builtin ();
static int is_arrayvar_builtin ();
#if !defined (HAVE_RENAME)
static int rename ();
@@ -831,6 +843,8 @@ builtin_handler (self, defs, arg)
new->flags |= BUILTIN_FLAG_LOCALVAR;
if (is_posix_builtin (name))
new->flags |= BUILTIN_FLAG_POSIX_BUILTIN;
if (is_arrayvar_builtin (name))
new->flags |= BUILTIN_FLAG_ARRAYREF_ARG;
array_add ((char *)new, defs->builtins);
building_builtin = 1;
@@ -1111,7 +1125,7 @@ char *structfile_header[] = {
"/* This file is manufactured by ./mkbuiltins, and should not be",
" edited by hand. See the source to mkbuiltins for details. */",
"",
"/* Copyright (C) 1987-2015 Free Software Foundation, Inc.",
"/* Copyright (C) 1987-2021 Free Software Foundation, Inc.",
"",
" This file is part of GNU Bash, the Bourne Again SHell.",
"",
@@ -1250,12 +1264,13 @@ write_builtins (defs, structfile, externfile)
else
fprintf (structfile, "(sh_builtin_func_t *)0x0, ");
fprintf (structfile, "%s%s%s%s%s, %s_doc,\n",
fprintf (structfile, "%s%s%s%s%s%s, %s_doc,\n",
"BUILTIN_ENABLED | STATIC_BUILTIN",
(builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
(builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
(builtin->flags & BUILTIN_FLAG_LOCALVAR) ? " | LOCALVAR_BUILTIN" : "",
(builtin->flags & BUILTIN_FLAG_POSIX_BUILTIN) ? " | POSIX_BUILTIN" : "",
(builtin->flags & BUILTIN_FLAG_ARRAYREF_ARG) ? " | ARRAYREF_BUILTIN" : "",
document_name (builtin));
/* Don't translate short document summaries that are identical
@@ -1645,6 +1660,13 @@ is_posix_builtin (name)
return (_find_in_table (name, posix_builtins));
}
static int
is_arrayvar_builtin (name)
char *name;
{
return (_find_in_table (name, arrayvar_builtins));
}
#if !defined (HAVE_RENAME)
static int
rename (from, to)
+8 -1
View File
@@ -959,8 +959,15 @@ unset_builtin (list)
#if defined (ARRAY_VARS)
if (var && unset_array)
{
int tvflags;
tvflags = vflags;
#if 0 /* TAG:bash-5.2 */
if (shell_compatibility_level <= 51)
tvflags |= VA_ALLOWALL;
#endif
/* Let unbind_array_element decide what to do with non-array vars */
tem = unbind_array_element (var, t, vflags); /* XXX new third arg */
tem = unbind_array_element (var, t, tvflags); /* XXX new third arg */
if (tem == -2 && array_p (var) == 0 && assoc_p (var) == 0)
{
builtin_error (_("%s: not an array variable"), var->name);
+22 -3
View File
@@ -1,7 +1,7 @@
This file is shopt.def, from which is created shopt.c.
It implements the Bash `shopt' builtin.
Copyright (C) 1994-2020 Free Software Foundation, Inc.
Copyright (C) 1994-2021 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -120,6 +120,7 @@ extern int debugging_mode;
#if defined (ARRAY_VARS)
extern int assoc_expand_once;
extern int array_expand_once;
int expand_once_flag;
#endif
#if defined (SYSLOG_HISTORY)
@@ -140,6 +141,10 @@ static int shopt_enable_hostname_completion PARAMS((char *, int));
static int shopt_set_complete_direxpand PARAMS((char *, int));
#endif
#if defined (ARRAY_VARS)
static int set_assoc_expand PARAMS((char *, int));
#endif
static int shopt_set_debug_mode PARAMS((char *, int));
static int shopt_login_shell;
@@ -163,7 +168,7 @@ static struct {
} shopt_vars[] = {
{ "autocd", &autocd, (shopt_set_func_t *)NULL },
#if defined (ARRAY_VARS)
{ "assoc_expand_once", &assoc_expand_once, (shopt_set_func_t *)NULL },
{ "assoc_expand_once", &expand_once_flag, set_assoc_expand },
#endif
{ "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL },
{ "cdspell", &cdspelling, (shopt_set_func_t *)NULL },
@@ -362,7 +367,7 @@ reset_shopt_options ()
#endif
#if defined (ARRAY_VARS)
assoc_expand_once = 0;
expand_once_flag = assoc_expand_once = 0;
#endif
#if defined (HISTORY)
@@ -897,3 +902,17 @@ initialize_bashopts (no_bashopts)
/* Set up the $BASHOPTS variable. */
set_bashopts ();
}
#if defined (ARRAY_VARS)
static int
set_assoc_expand (option_name, mode)
char *option_name;
int mode;
{
#if 0 /* TAG: bash-5.2, fix shell_compatibility_level test */
if (shell_compatibility_level <= 51)
#endif
assoc_expand_once = expand_once_flag;
return 0;
}
#endif