- 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
----
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>
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)
{
{
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))
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));
}
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);
}
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))
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] == '[')
{
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 ();
}
/* 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
#! /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.
#
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
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
# 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)
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
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)
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
@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
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
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);
}
e = ']';
}
else
- evalerror (bash_badsub_errmsg);
+ evalerror (_(bash_badsub_errmsg));
}
#endif /* ARRAY_VARS */
#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)
{
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 */
#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;
+ return (shm_unlink (fn));
+}
- r = unlink (fn);
- return r;
+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." */
*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;
}
r = close (fd);
return r;
}
+
+static int
+anonunlink (const char *fn)
+{
+ int r;
+
+ r = unlink (fn);
+ return r;
+}
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
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
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;
/* 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;