mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-08 12:50:49 +02:00
additional changes to avoid array subscript double expansion in arithmetic contexts
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user