use anonymous files for here-documents if available and the document size exceeds pipe capacity; fixes to build if multibyte characters are unavailable; fix potential overflow with extrememly long $'...' strings; fix for readline redisplay highlighting with a zero-length region

This commit is contained in:
Chet Ramey
2026-07-24 12:13:30 -04:00
parent 03e7298d1e
commit 9b6349ef40
19 changed files with 138 additions and 23 deletions
+34
View 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>
+1
View File
@@ -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
Vendored
+1
View 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
])
+10 -6
View 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;
+3 -3
View File
@@ -892,9 +892,6 @@
/* 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
@@ -1176,6 +1173,9 @@
/* 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
Vendored
+3 -1
View File
@@ -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"
+1 -1
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.083])dnl
AC_REVISION([for Bash 5.3, version 5.084])dnl
define(bashvers, 5.3)
define(relstatus, maint)
+2 -2
View 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
+2 -2
View 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
+4
View File
@@ -417,6 +417,10 @@
<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>
+1 -1
View 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
+6
View 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.
+26
View File
@@ -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
+1 -1
View File
@@ -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
+3 -1
View 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
+4
View 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);
+3 -1
View 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;
+2 -2
View File
@@ -50,11 +50,11 @@
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;
+31 -2
View File
@@ -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. */