]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
use anonymous files for here-documents if available and the document size exceeds...
authorChet Ramey <chet.ramey@case.edu>
Fri, 24 Jul 2026 16:13:30 +0000 (12:13 -0400)
committerChet Ramey <chet.ramey@case.edu>
Fri, 24 Jul 2026 16:13:30 +0000 (12:13 -0400)
19 files changed:
CWRU/CWRU.chlog
MANIFEST
aclocal.m4
builtins/printf.def
config.h.in
configure
configure.ac
doc/bash.1
doc/bashref.texi
examples/INDEX.html
examples/INDEX.txt
examples/startup-files/README
examples/startup-files/fix-output [new file with mode: 0644]
externs.h
include/shmbutil.h
lib/glob/glob.c
lib/readline/display.c
lib/sh/strtrans.c
redir.c

index ec2cf4b1be39109d132407be5e62ac4f7bb0472f..249683771ab7ec3ff1cad9f54054c8ca67c412e8 100644 (file)
@@ -13123,4 +13123,38 @@ configure.ac
          the pipe capacity down to 512 if the system as a whole is using too
          much pipe capacity (16 MB by default)
 
+                                  7/13
+                                  ----
+redir.c
+       - here_document_to_fd: use anon files (via redir_anonopen()) if
+         memfd_create() or shm_mkstemp() is available. Faster and we don't
+         touch the filesystem
+
+builtins/printf.def,lib/glob/glob.c,include/shmbutil.h
+       - HANDLE_MULTIBYTE: some fixes so build will work with this undefined
+         Report and fix from Shubham Chakraborty <chakrabortyshubham66@gmail.com>
+
+                                  7/17
+                                  ----
+builtins/printf.def,lib/sh/strtrans.c
+       - make sure to use a size_t to compute the allocated buffer size, in
+         case the length argument exceeds INT_MAX
+         Report from Denis Rastyogin <gerben@altlinux.org> via
+         https://savannah.gnu.org/bugs/?68534
 
+                                  7/23
+                                  ----
+aclocal.m4,config.h.in
+       - REPLACE_STRCHRNUL: define if we are using the strchrnul replacement
+         in lib/sh
+
+externs.h
+       - make the definition of strchrnul conditional on REPLACE_STRCHRNUL
+         From Rong Bao <rong.bao@csmantle.top> via https://savannah.gnu.org/patch/?10588
+
+                                  7/24
+                                  ----
+lib/readline/display.c
+       - rl_redisplay: make sure not to display any standout mode if the
+         region is zero-length (rl_point == rl_mark)
+         Report and fix from kurku <sandovin@mail.ru>
index f3bf6ecf3037af4cd8b1f7e5a4f7cd9b2e09cdef..3980f6a5f0702d1af78752284bdfb96b9f0e6a68 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -925,6 +925,7 @@ examples/startup-files/Bash_aliases f
 examples/startup-files/Bash_profile    f
 examples/startup-files/bash-profile    f
 examples/startup-files/bashrc  f
+examples/startup-files/fix-output      f
 #examples/startup-files/apple/README   f
 #examples/startup-files/apple/aliases  f
 #examples/startup-files/apple/bash.defaults    f
index 561465f584fda38a80aea81ceaaeb98959f47734..934b325f85f807e773a8ca59c5b159b35d8c0494 100644 (file)
@@ -2268,6 +2268,7 @@ AC_DEFUN([BASH_FUNC_STRCHRNUL],
 )])
 
 if test "$bash_cv_func_strchrnul_works" = "no"; then
+AC_DEFINE(REPLACE_STRCHRNUL)
 AC_LIBOBJ([strchrnul])
 fi
 ])
index 456a1beb83753f4240651d0525f0570cb72b7080..efae612268abac465888adbe0f39e384b2e8635b 100644 (file)
@@ -397,7 +397,9 @@ printf_builtin (WORD_LIST *list)
 
   garglist = orig_arglist = list->next;
 
+#if defined (HANDLE_MULTIBYTE)
   mb_cur_max = MB_CUR_MAX;
+#endif
 
   nfmt = xrealloc (nfmt, strlen (format) + 1); /* XXX error checking */
   nfmt[0] = '\0';
@@ -1358,8 +1360,9 @@ tescape (char *estart, char *cp, int *lenp, int *sawc)
 static char *
 bexpand (char *string, size_t len, int *sawc, size_t *lenp)
 {
-  int temp, c;
-  char *ret, *r, *s, *send;
+  int c, sc;
+  size_t temp;
+  char *ret, *r, *s, *send, cc;
 #if defined (HANDLE_MULTIBYTE)
   char mbch[25];
   int mbind, mblen;
@@ -1403,14 +1406,15 @@ bexpand (char *string, size_t len, int *sawc, size_t *lenp)
       else
        s++;            /* *s == '\\' */
 
-      temp = 0;
+      sc = 0;
 #if defined (HANDLE_MULTIBYTE)
       memset (mbch, '\0', sizeof (mbch));
-      s += tescape (s, mbch, &mblen, &temp);
+      s += tescape (s, mbch, &mblen, &sc);
 #else
-      s += tescape (s, &c, (int *)NULL, &temp);
+      s += tescape (s, &cc, (int *)NULL, &sc);
+      c = cc;
 #endif
-      if (temp)
+      if (sc)
        {
          if (sawc)
            *sawc = 1;
index 38578baf664a2d4b1b4a3ac5d2b7f8f804a25302..cab07dcc0a834bd0b7a8a31fde2f866975b765ac 100644 (file)
 /* Define if you have the strchr function.  */
 #undef HAVE_STRCHR
 
-/* Define if you have the strchrnul function.  */
-#undef HAVE_STRCHRNUL
-
 /* Define if you have the strcoll function.  */
 #undef HAVE_STRCOLL
 
 /* Define if you have the <varargs.h> header file.  */
 #undef HAVE_WCTYPE_H
 
+/* Define if we are using the strchrnul function in lib/sh/strchrnul.c.  */
+#undef REPLACE_STRCHRNUL
+
 /* Presence of certain system libraries. */
 
 #undef HAVE_LIBDL
index bd60a1a8d72337767c3dcb9548e7e4a64e8daa39..2b2068dc11548ac41c931850f9b03c26c65011e4 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.ac for Bash 5.3, version 5.083.
+# From configure.ac for Bash 5.3, version 5.084.
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.72 for bash 5.3-maint.
 #
@@ -19232,6 +19232,8 @@ fi
 printf "%s\n" "$bash_cv_func_strchrnul_works" >&6; }
 
 if test "$bash_cv_func_strchrnul_works" = "no"; then
+printf "%s\n" "#define REPLACE_STRCHRNUL 1" >>confdefs.h
+
 case " $LIBOBJS " in
   *" strchrnul.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS strchrnul.$ac_objext"
index d352dacbe5004aa5d75d112f540f361eef1cc32c..d8bb22f26cbe7b735b6afb204f5c0ef6a681eeda 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.083])dnl
+AC_REVISION([for Bash 5.3, version 5.084])dnl
 
 define(bashvers, 5.3)
 define(relstatus, maint)
index 7d3e997d8327f53686d16445e70c74a39bf7604b..02ee691f03c2f49d5826dc0131a87e8162bfb462 100644 (file)
@@ -921,9 +921,9 @@ The array variable
 .B BASH_REMATCH
 records which parts of the string matched the pattern.
 .B Bash
-unsets
+unsets each element of
 .B BASH_REMATCH
-before attempting the match, so if there is no match, it remains unset.
+before attempting the match, so if there is no match, it remains empty.
 The element of
 .SM
 .B BASH_REMATCH
index c76c69b325b8710b946c138e0859fd99bbeb6d1b..568e88eef18d8f415119eba071084f56136dc86f 100644 (file)
@@ -1379,8 +1379,8 @@ special pattern characters where that's necessary.
 
 The array variable @code{BASH_REMATCH} records which parts of the string
 matched the pattern.
-Bash unsets @code{BASH_REMATCH}
-before attempting the match, so if there is no match, it remains unset.
+Bash unsets each element of @code{BASH_REMATCH}
+before attempting the match, so if there is no match, it remains empty.
 The element of @code{BASH_REMATCH} with index 0 contains the portion of
 the string matching the entire regular expression.
 Substrings matched by parenthesized subexpressions within the regular
index bcca1f9e01fd188d439162264445d5f3cbf07a63..85789bd14fb86992888efd087004690d9963cf7b 100644 (file)
     <td>./startup-files/Bashrc.bfox</td>
     <td>Sample Bourne Again SHell init file (Fox).</td>
   </tr>
+ <tr>
+    <td>./startup-files/fix-output</td>
+    <td>A pair of functions that will add a newline if the previous command doesn't end with one.</td>
+  </tr>
   <tr>
     <td>./startup-files/README</td>
     <td>README</td>
index b47e2113a313e2a1b6c1474cafa9a108e26cc578..f3b5d3fcee9351ba3eb2cbc6fd412efbe677b142 100644 (file)
@@ -99,5 +99,5 @@ Path  Description     X-Ref
 ./startup-files/bash-profile   Sample startup file for bash login shells (Ramey).      
 ./startup-files/bashrc Sample Bourne Again SHell init file (Ramey).    
 ./startup-files/Bashrc.bfox    Sample Bourne Again SHell init file (Fox).      
+./startup-files/fix-output     A pair of functions that will add a newline if the previous command doesn't end with one.
 ./startup-files/README README  
-
index 00df0414dc5d10b09c0cb41cafbe207b20bfb801..e360ea4d2e2381c25d47608466dc16c782916c5d 100644 (file)
@@ -10,3 +10,9 @@ bash-profile  Sample startup file for bash login shells (Ramey).
 bashrc         Sample Bourne Again SHell init file (Ramey).
 Bashrc.bfox    Sample Bourne Again SHell init file (Fox).
 README         README
+
+These files are quite old.
+
+fix-output contains a pair of functions and an example assignment to
+PROMPT_COMMAND that will force a newline if a command does not leave the
+cursor at column 0.
diff --git a/examples/startup-files/fix-output b/examples/startup-files/fix-output
new file mode 100644 (file)
index 0000000..c6db67d
--- /dev/null
@@ -0,0 +1,26 @@
+# This is an example set of functions to call from PROMPT_COMMAND. If you
+# run commands that don't terminate their output with a newline, this can
+# detect it and add a newline before printing the readline prompt.
+
+# Readline assumes that it begins with the cursor in column 0 and makes
+# redisplay decisions based on that. If it does not start at column 0, for
+# example if the previous command does not end with a newline, it will lead
+# to display problems when the cursor is not where readline assumes.
+
+_fetch_cursor_position()
+{
+    local -a pos
+    IFS='[;' read -t 0.5 -p $'\e[6n' -d R -a pos -rs || {
+        echo "${FUNCNAME}: failed: $? ; ${pos[*]}" >&2
+        return 1
+    }
+    _cursor_row="${pos[1]}"
+    _cursor_col="${pos[2]}"
+}
+
+_prompt_command()
+{
+    _fetch_cursor_position && (( $_cursor_col > 1 )) && printf '\n'
+}
+
+PROMPT_COMMAND=_prompt_command
index fb57390078d4cd14557f06b14f4c3d33f66ccd52..9739e34d95b1a239d4bf8eb89eca4191c2679e19 100644 (file)
--- a/externs.h
+++ b/externs.h
@@ -392,7 +392,7 @@ extern char *strcasestr (const char *, const char *);
 #endif
 
 /* declarations for functions defined in lib/sh/strchrnul.c */
-#if ! HAVE_STRCHRNUL
+#if REPLACE_STRCHRNUL
 extern char *strchrnul (const char *, int);
 #endif
 
index 1feee8535a472e7c9473f750afb7b592476f041b..d1275d4d0922e00faa673bf0f3e90afd43c78bac 100644 (file)
@@ -1,6 +1,6 @@
 /* shmbutil.h -- utility functions for multibyte characters. */
 
-/* Copyright (C) 2002-2022 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2026 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -88,6 +88,8 @@ extern int locale_utf8locale; /* XXX */
 
 #define VALID_SINGLEBYTE_CHAR(c)  (1)
 
+extern int locale_utf8locale;  /* XXX */
+
 #endif /* !HANDLE_MULTIBYTE */
 
 /* Declare and initialize a multibyte state.  Call must be terminated
index 81d5aa5046b3ecf21064dc5dac53bad26a99ef82..089a038d5271f0ec730eb2d9eede284b5830df78 100644 (file)
@@ -120,10 +120,14 @@ static char **glob_dir_to_array (char *, char **, int);
 
 /* Make sure these names continue to agree with what's in smatch.c */
 extern char *glob_patscan (char *, char *, int, int);
+#if defined (HANDLE_MULTIBYTE)
 extern wchar_t *glob_patscan_wc (wchar_t *, wchar_t *, wint_t, int);
+#endif
 
 /* And this from gmisc.c/gm_loop.c */
+#if defined (HANDLE_MULTIBYTE)
 extern int wextglob_pattern_p (wchar_t *);
+#endif
 
 extern char *glob_dirscan (char *, int);
 
index 8da0dd7b2989fb0a4822eea490c4d1329fb0f286..2c3cc752eda5ebbd5896e03d42b61b00437b8dbd 100644 (file)
@@ -1065,7 +1065,9 @@ rl_redisplay (void)
   for (in = 0; in < rl_end; in++)
 #endif
     {
-      if (in == hl_begin)
+      if (hl_begin == hl_end)
+       cur_face = FACE_NORMAL;                 /* zero-length region/paste */
+      else if (in == hl_begin)
        cur_face = FACE_STANDOUT;
       else if (in == hl_end)
        cur_face = FACE_NORMAL;
index 16ca16dd2514b272b8a3ea1440a691a46d48db8c..cc5c3a1616e236d1c608215bf190fa193e45affe 100644 (file)
 char *
 ansicstr (const char *string, size_t len, int flags, int *sawc, size_t *rlen)
 {
-  int c, temp;
+  int c;
   char *ret, *r;
   const char *s;
   unsigned long v;
-  size_t clen;
+  size_t temp, clen;
   size_t mb_cur_max;
 #if defined (HANDLE_MULTIBYTE)
   wchar_t wc;
diff --git a/redir.c b/redir.c
index bd3fee8e79f2dbadc0bfdd66f995b0149a4dafcf..6893977b50b5901b628fc5867fd586f6c78a54ee 100644 (file)
--- a/redir.c
+++ b/redir.c
@@ -101,6 +101,7 @@ static int stdin_redirection (REDIRECT *);
 static int undoablefd (int);
 static int do_redirection_internal (REDIRECT *, int, char **);
 
+static int redir_anonopen (void);
 static char *heredoc_expand (WORD_DESC *, enum r_instruction, size_t *);
 static int heredoc_write (int, const char *, size_t);
 static int here_document_to_fd (WORD_DESC *, enum r_instruction);
@@ -422,6 +423,20 @@ heredoc_write (int fd, const char *heredoc, size_t herelen)
   return 0;
 }
 
+/* Open a file in memory for a here document. */
+static int
+redir_anonopen (void)
+{
+#if defined (HAVE_MEMFD_CREATE) || defined (HAVE_SHM_MKSTEMP)
+  int fd;
+
+  fd = anonopen ("sh-ahd", 0, (char **)NULL);
+  return fd;
+#else
+  return -1;
+#endif
+}
+
 /* Create a temporary file or pipe holding the text of the here document
    pointed to by REDIRECTEE, and return a file descriptor open for reading
    to it. Return -1 on any error, and make sure errno is set appropriately. */
@@ -430,6 +445,7 @@ here_document_to_fd (WORD_DESC *redirectee, enum r_instruction ri)
 {
   char *filename;
   int r, fd, fd2, herepipe[2];
+  int useanon;
   char *document;
   size_t document_len;
 #if HEREDOC_PARANOID
@@ -517,8 +533,14 @@ here_document_to_fd (WORD_DESC *redirectee, enum r_instruction ri)
 
 use_tempfile:
 
-  /* TAG: use anonfiles here in a future version. */
-  fd = sh_mktmpfd ("sh-thd", MT_USERANDOM|MT_USETMPDIR, &filename);
+  /* Use anonfiles here if we can do it in memory. If anonfiles falls back
+     to temporary files, don't use them because this code path does a little
+     more to ensure security. */
+  useanon = 0;
+  if ((fd = redir_anonopen ()) >= 0)
+    useanon = 1;
+  else
+    fd = sh_mktmpfd ("sh-thd", MT_USERANDOM|MT_USETMPDIR, &filename);
 
   /* If we failed for some reason other than the file existing, abort */
   if (fd < 0)
@@ -548,6 +570,13 @@ use_tempfile:
       return (-1);
     }
 
+  if (useanon)
+    {
+      /* rewind file back to the beginning for reading */
+      r = lseek (fd, 0, SEEK_SET);
+      return (r < 0) ? r : fd;
+    }
+
   /* In an attempt to avoid races, we close the first fd only after opening
      the second. */
   /* Make the document really temporary.  Also make it the input. */