]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
fix up semantics of assigning to noassign variables; fix error message in arithmetic...
authorChet Ramey <chet.ramey@case.edu>
Mon, 3 Jul 2023 14:26:23 +0000 (10:26 -0400)
committerChet Ramey <chet.ramey@case.edu>
Mon, 3 Jul 2023 14:26:23 +0000 (10:26 -0400)
13 files changed:
CWRU/CWRU.chlog
arrayfunc.c
builtins/declare.def
config.h.in
configure
configure.ac
doc/bashref.texi
doc/version.texi
expr.c
lib/sh/anonfile.c
tests/array.right
tests/array.tests
variables.c

index 5529c78ef93da8507c3ecd2eb238af103be57835..b149c6199d26fbea41a3275a8108751e4ce4099f 100644 (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>
index a92063bc15b3846d2ca79175b6b5440a40ccde98..98e60d31df8a857f3a7fa40777bdb9840860214d 100644 (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] == '[')
        {
index 337e6755ec7acd102fa140f44be6f5c97a88b9d8..d3784855aa0e8f553144f65c6c04d1213acff6a4 100644 (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 ();
        }
 
index c2750a2a0751b9d5089ca790f5b1690b4140bb10..16103a8e5c7c785dbb1acaf582f5b89e05eebdd3 100644 (file)
 /* 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
 
index 518b6fc2fe09e08e157045bcd9d75b466f54f5bf..9176f1838ceb99f163916475c2219b6e1a204070 100755 (executable)
--- a/configure
+++ b/configure
@@ -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
index 29f5043874ab5fb70d1a0e712b734e0a6ccc002f..477b6ffaf7034dd7909136741250224fa5a0529f 100644 (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)
 
index b8cf474ed8cdc1ce3a403aaafc164fbfb27f92b6..37a0f5b802b24c99660637d9cc931f819e6d1160 100644 (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
index b9bc389b3803fd9fd5efd257cf7a9ed9b9fff4d7..159f956fe3d94c331960c6f69870e8abe212209a 100644 (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
diff --git a/expr.c b/expr.c
index 45fb2f3650cba0cc71667f40285074912f9009bb..9f711a9bac25f1310ef528bbfff0585923aa1394 100644 (file)
--- a/expr.c
+++ b/expr.c
@@ -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 */
index 9a805b2d53728d6ad7ba355086863560e8efe4cc..b3c8957cde6b41704a8b0702dda988d932da51ad 100644 (file)
 #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." */
@@ -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;
+}
index eebf1068172de54159bb54d526d44638f938606f..aebe24d2fd041fe05e4cb76d599356d18d71a975 100644 (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
index 126ced3bbf4c89ecebaec7755986fba52bf4e92e..7e5a6376ff09dbb6edcb81d4307dafe0a8e9ace6 100644 (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
 
index 2db4a457c7cc63137f094b00f747eb146451137f..05a0daa00555de9cabac9a9f33957f135d559517 100644 (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;