fix up semantics of assigning to noassign variables; fix error message in arithmetic noeval mode; add shared memory option to anonymous files; fix static linking config in configure

This commit is contained in:
Chet Ramey
2023-07-03 10:26:23 -04:00
parent fa98070927
commit 6a9e77e881
13 changed files with 189 additions and 44 deletions
+31
View File
@@ -6952,6 +6952,7 @@ arrayfunc.c
- assign_compound_array_list: check for integer overflow if the max
index of the array is already INT_MAX.
From a report from Emanuele Torre <torreemanuele6@gmail.com>
- assign_array_var_from_word_list: ditto
6/28
----
@@ -6973,3 +6974,33 @@ bashline.c
doc/bash.1,doc/bashref.texi
- BASH_ARGC,BASH_ARGV,BASH_SOURCE,BASH_LINENO: note that these variables
may not be assigned to or unset
6/29
----
builtins/declare.def
- declare_internal: attempting to assign to a noassign variable is no
longer an assignment error; the attempt is just ignored
arrayfunc.c
- find_or_make_array_variable: take a new flag value, 4: means to
return noassign variables as themselves instead of NULL without
performing the assignment so the caller can handle them differently.
- assign_array_from_string: pass flags & 4 to find_or_make_array_variable
so we can simply ignore attempted assignments to noassign array
variables instead of treating them as assignment errors
From a report by Kerin Millar <kfm@plushkava.net>
expr.c
- exppower: only report negative exponent error if noeval == 0.
Fixes issue reported by Steffen Nurpmeso <steffen@sdaoden.eu>
6/30
----
lib/sh/anonfile.c
- anonopen: add support for using shm_open or shm_mkstemp to create
an anonymous file using POSIX shared memory
configure.ac
- if --enable-static-link is supplied, add -static to LDFLAGS on
Linux if opt_profiling isn't enabled
From a report from Emanuele Torre <torreemanuele6@gmail.com>
+26 -12
View File
@@ -445,7 +445,8 @@ assign_array_element_internal (SHELL_VAR *entry, const char *name, char *vname,
convert it to an indexed array. If FLAGS&1 is non-zero, an existing
variable is checked for the readonly or noassign attribute in preparation
for assignment (e.g., by the `read' builtin). If FLAGS&2 is non-zero, we
create an associative array. */
create an associative array. If FLAGS&4 is non-zero, we return noassign
variables instead of NULL because the caller wants to handle them. */
SHELL_VAR *
find_or_make_array_variable (const char *name, int flags)
{
@@ -479,6 +480,8 @@ find_or_make_array_variable (const char *name, int flags)
{
if (readonly_p (var))
err_readonly (name);
if ((flags & 4) && noassign_p (var))
return (var);
return ((SHELL_VAR *)NULL);
}
else if ((flags & 2) && array_p (var))
@@ -506,10 +509,11 @@ assign_array_from_string (const char *name, char *value, int flags)
vflags = 1;
if (flags & ASS_MKASSOC)
vflags |= 2;
vflags |= 4; /* we want to handle noassign variables ourselves */
var = find_or_make_array_variable (name, vflags);
if (var == 0)
return ((SHELL_VAR *)NULL);
if (var == 0 || noassign_p (var))
return (var);
return (assign_array_var_from_string (var, value, flags));
}
@@ -525,6 +529,15 @@ assign_array_var_from_word_list (SHELL_VAR *var, WORD_LIST *list, int flags)
a = array_cell (var);
i = (flags & ASS_APPEND) ? array_max_index (a) + 1 : 0;
if (a && i < 0) /* overflow */
{
char *num;
num = itos (i);
report_error ("%s[%s]: %s", var->name, num, bash_badsub_errmsg);
free (num);
return (var); /* XXX */
}
for (l = list; l; l = l->next, i++)
bind_array_var_internal (var, i, 0, l->word->word, flags & ~ASS_APPEND);
@@ -705,15 +718,6 @@ assign_compound_array_list (SHELL_VAR *var, WORD_LIST *nlist, int flags)
}
last_ind = (a && (flags & ASS_APPEND)) ? array_max_index (a) + 1 : 0;
if (a && last_ind < 0) /* overflow */
{
char *num;
num = itos (last_ind);
report_error ("%s[%s]: %s", var->name, num, bash_badsub_errmsg);
free (num);
return;
}
#if ASSOC_KVPAIR_ASSIGNMENT
if (assoc_p (var) && kvpair_assignment_p (nlist))
@@ -737,6 +741,16 @@ assign_compound_array_list (SHELL_VAR *var, WORD_LIST *nlist, int flags)
iflags = flags & ~ASS_APPEND;
w = list->word->word;
if (array_p (var) && last_ind < 0) /* overflow */
{
char *num;
num = itos (last_ind);
report_error ("%s[%s]: %s", var->name, num, bash_badsub_errmsg);
free (num);
return;
}
/* We have a word of the form [ind]=value */
if ((list->word->flags & W_ASSIGNMENT) && w[0] == '[')
{
+6 -2
View File
@@ -844,8 +844,12 @@ restart_new_var_name:
else if ((readonly_p (var) || noassign_p (var)) && offset)
{
if (readonly_p (var))
sh_readonly (name);
assign_error++;
{
sh_readonly (name);
assign_error++;
}
/* just ignore attempts to assign to noassign variables; returning
EXECUTION_FAILURE would cause set -e to exit the shell. */
NEXT_VARIABLE ();
}
+3
View File
@@ -1226,6 +1226,9 @@
/* Define if you have the `munmap' function. */
#undef HAVE_MUNMAP
/* Define if you have the `nanosleep' function. */
#undef HAVE_NANOSLEEP
/* Define if you have the `nl_langinfo' function. */
#undef HAVE_NL_LANGINFO
Vendored
+9 -2
View File
@@ -1,5 +1,5 @@
#! /bin/sh
# From configure.ac for Bash 5.3, version 5.054.
# From configure.ac for Bash 5.3, version 5.055.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for bash 5.3-devel.
#
@@ -5335,7 +5335,8 @@ if test "$opt_static_link" = yes; then
if test "$GCC" = "yes"; then
STATIC_LD="-static"
case "$host_os" in
solaris2*|linux*) ;;
solaris2*) ;;
linux*) test "$opt_profiling" = "no" && LDFLAGS="$LDFLAGS -static" ;;
*) LDFLAGS="$LDFLAGS -static" ;; # XXX experimental
esac
fi
@@ -14959,6 +14960,12 @@ if test "x$ac_cv_func_lstat" = xyes
then :
printf "%s\n" "#define HAVE_LSTAT 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep"
if test "x$ac_cv_func_nanosleep" = xyes
then :
printf "%s\n" "#define HAVE_NANOSLEEP 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "pselect" "ac_cv_func_pselect"
if test "x$ac_cv_func_pselect" = xyes
+5 -3
View File
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AC_REVISION([for Bash 5.3, version 5.054])dnl
AC_REVISION([for Bash 5.3, version 5.055])dnl
define(bashvers, 5.3)
define(relstatus, devel)
@@ -515,7 +515,8 @@ if test "$opt_static_link" = yes; then
if test "$GCC" = "yes"; then
STATIC_LD="-static"
case "$host_os" in
solaris2*|linux*) ;;
solaris2*) ;;
linux*) test "$opt_profiling" = "no" && LDFLAGS="$LDFLAGS -static" ;;
*) LDFLAGS="$LDFLAGS -static" ;; # XXX experimental
esac
fi
@@ -843,7 +844,8 @@ AC_CHECK_FUNC(mkfifo, AC_DEFINE(HAVE_MKFIFO), AC_DEFINE(MKFIFO_MISSING))
dnl checks for system calls
AC_CHECK_FUNCS(dup2 eaccess fcntl getdtablesize getentropy getgroups \
gethostname getpagesize getpeername getrandom getrlimit \
getrusage gettimeofday kill killpg lstat pselect readlink \
getrusage gettimeofday kill killpg lstat nanosleep \
pselect readlink \
select setdtablesize setitimer tcgetpgrp uname ulimit waitpid)
AC_REPLACE_FUNCS(rename)
+1 -4
View File
@@ -1953,7 +1953,7 @@ command substitution.
After these expansions are performed, quote characters present in the
original word are removed unless they have been quoted themselves
(@dfn{quote removal}).
(@dfn{quote removal}). @xref{Quote Removal} for more details.
Only brace expansion, word splitting, and filename expansion
can increase the number of words of the expansion; other expansions
@@ -1963,9 +1963,6 @@ The only exceptions to this are the expansions of
@code{"$@{@var{name}[@@]@}"} and @code{$@{@var{name}[*]@}}
(@pxref{Arrays}).
After all expansions, @code{quote removal} (@pxref{Quote Removal})
is performed.
@node Brace Expansion
@subsection Brace Expansion
@cindex brace expansion
+2 -2
View File
@@ -2,10 +2,10 @@
Copyright (C) 1988-2023 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Wed Jun 28 14:06:44 EDT 2023
@set LASTCHANGE Thu Jun 29 16:25:08 EDT 2023
@set EDITION 5.3
@set VERSION 5.3
@set UPDATED 28 June 2023
@set UPDATED 29 June 2023
@set UPDATED-MONTH June 2023
+15 -11
View File
@@ -960,11 +960,16 @@ exppower (void)
readtok ();
val2 = exppower (); /* exponentiation is right-associative */
lasttok = NUM;
if (val2 == 0)
return (1);
if (val2 < 0)
evalerror (_("exponent less than 0"));
val1 = ipow (val1, val2);
if (noeval == 0)
{
if (val2 == 0)
return (1);
if (val2 < 0)
evalerror (_("exponent less than 0"));
val1 = ipow (val1, val2);
}
else
val1 = 1;
}
return (val1);
}
@@ -1342,7 +1347,7 @@ readtok (void)
e = ']';
}
else
evalerror (bash_badsub_errmsg);
evalerror (_(bash_badsub_errmsg));
}
#endif /* ARRAY_VARS */
@@ -1442,11 +1447,10 @@ readtok (void)
#endif
{
/* This catches something like --FOO++ */
/* TAG:bash-5.3 add gettext calls here or make this a separate function */
if (c == '-')
evalerror ("--: assignment requires lvalue");
evalerror (_("--: assignment requires lvalue"));
else
evalerror ("++: assignment requires lvalue");
evalerror (_("++: assignment requires lvalue"));
}
else if ((c == '-' || c == '+') && c1 == c)
{
@@ -1465,9 +1469,9 @@ readtok (void)
preinc and predec. */
/* This catches something like --4++ */
if (c == '-')
evalerror ("--: assignment requires lvalue");
evalerror (_("--: assignment requires lvalue"));
else
evalerror ("++: assignment requires lvalue");
evalerror (_("++: assignment requires lvalue"));
}
#else
cp--; /* not preinc or predec, so unget the character */
+74 -7
View File
@@ -35,21 +35,72 @@
#include <shell.h>
#include <bashansi.h>
/* Placeholder for future use of memfd_create/shm_open/shm_mkstemp */
static int anonunlink (const char *);
#if defined (HAVE_SHM_OPEN)
#ifndef O_NOFOLLOW
# define O_NOFOLLOW 0
#endif
static int
anonunlink (const char *fn)
anonshmunlink (const char *fn)
{
int r;
r = unlink (fn);
return r;
return (shm_unlink (fn));
}
static int
anonshmopen (const char *name, int flags, char **fn)
{
int fd;
char *fname;
fd = -1;
if (fn)
*fn = 0;
#if defined (HAVE_SHM_MKSTEMP)
fname = savestring ("/shm-XXXXXXXXXX");
fd = shm_mkstemp (fname);
if (fd < 0)
free (fname);
#endif
if (fd < 0)
{
fname = sh_mktmpname (name, flags);
fd = shm_open (fname, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600);
}
if (fd < 0)
{
free (fname);
return fd;
}
if (shm_unlink (fname) < 0)
{
int o;
o = errno;
free (fname);
close (fd);
errno = o;
return -1;
}
if (fn)
*fn = fname;
else
free (fname);
return fd;
}
#endif
int
anonopen (const char *name, int flags, char **fn)
{
int fd, flag;
char *fname;
#if defined (HAVE_MEMFD_CREATE)
/* "Names do not affect the behavior of the file descriptor." */
@@ -60,12 +111,19 @@ anonopen (const char *name, int flags, char **fn)
*fn = 0;
return fd;
}
/* If memfd_create fails, we fall through to the unlinked-regular-file
/* If memfd_create fails, we fall through to the unlinked-shm-or-regular-file
implementation. */
#endif
/* Heuristic */
flag = (name && *name == '/') ? MT_TEMPLATE : MT_USETMPDIR;
#if defined (HAVE_SHM_OPEN)
fd = anonshmopen (name, flag, fn);
if (fd >= 0)
return fd; /* anonshmopen sets *FN appropriately */
#endif
fd = sh_mktmpfd (name, flag|MT_USERANDOM|MT_READWRITE|MT_UNLINK, fn);
return fd;
}
@@ -78,3 +136,12 @@ anonclose (int fd, const char *name)
r = close (fd);
return r;
}
static int
anonunlink (const char *fn)
{
int r;
r = unlink (fn);
return r;
}
+6
View File
@@ -206,6 +206,12 @@ e
b c
$0
declare -a A=([0]="X=a" [1]="b")
FIN1:0
FIN2:0
FIN3:0
FIN4:0
FIN5:0
FIN6:0
t
[3]=abcde r s t u v
e
+8
View File
@@ -397,6 +397,14 @@ Z='a b'
A=( X=$Z )
declare -p A
# tests for assigning to noassign array variables
BASH_ARGC=(xxx) ; echo FIN1:$?
BASH_ARGC=foio ; echo FIN2:$?
declare BASH_ARGC=(xxx) ; echo FIN3:$?
declare BASH_ARGC=foio ; echo FIN4:$?
BASH_ARGV[1]=foo ; echo FIN5:$?
declare BASH_ARGV[1]=foo ; echo FIN6:$?
# tests for bash-3.1 problems
${THIS_SH} ./array5.sub
+3 -1
View File
@@ -464,7 +464,7 @@ initialize_shell_variables (char **env, int privmode)
temp_string = extract_array_assignment_list (string, &string_length);
temp_var = assign_array_from_string (tname, temp_string, 0);
FREE (temp_string);
if (temp_var)
if (temp_var && noassign_p (temp_var) == 0)
{
VSETATTR (temp_var, (att_exported | att_imported));
array_needs_making = 1;
@@ -484,6 +484,8 @@ initialize_shell_variables (char **env, int privmode)
/* need to make sure it exists as an associative array first */
temp_var = find_or_make_array_variable (tname, 2);
if (temp_var && noassign_p (temp_var))
temp_var = 0;
if (temp_var)
{
string_length = 1;