bash: Update to 4.2.48

Fixes CVE-2014-6271.

Signed-off-by: Marcel Denia <naoir@gmx.net>
This commit is contained in:
Marcel Denia 2014-09-25 03:01:46 +02:00
parent 27b48028df
commit 96243ff2fc
21 changed files with 1602 additions and 2 deletions

View file

@ -1,5 +1,5 @@
#
# Copyright (C) 2007-2012 OpenWrt.org
# Copyright (C) 2007-2014 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=bash
PKG_VERSION:=4.2
PKG_RELEASE:=3
PKG_RELEASE:=4
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@GNU/bash

View file

@ -0,0 +1,461 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-029
Bug-Reported-by: "Michael Kalisz" <michael@kalisz.homelinux.net>
Bug-Reference-ID: <50241.78.69.11.112.1298585641.squirrel@kalisz.homelinux.net>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2011-02/msg00274.html
Bug-Description:
Bash-4.2 tries to leave completed directory names as the user typed them,
without expanding them to a full pathname. One effect of this is that
shell variables used in pathnames being completed (e.g., $HOME) are left
unchanged, but the `$' is quoted by readline because it is a special
character to the shell.
This patch introduces two things:
1. A new shell option, `direxpand', which, if set, attempts to emulate the
bash-4.1 behavior of expanding words to full pathnames during
completion;
2. A set of heuristics that reduce the number of times special characters
such as `$' are quoted when the directory name is not expanded.
Patch (apply with `patch -p0'):
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 28
+#define PATCHLEVEL 29
#endif /* _PATCHLEVEL_H_ */
--- a/bashline.c
+++ b/bashline.c
@@ -121,6 +121,9 @@ static int bash_directory_completion_hoo
static int filename_completion_ignore __P((char **));
static int bash_push_line __P((void));
+static rl_icppfunc_t *save_directory_hook __P((void));
+static void reset_directory_hook __P((rl_icppfunc_t *));
+
static void cleanup_expansion_error __P((void));
static void maybe_make_readline_line __P((char *));
static void set_up_new_line __P((char *));
@@ -243,10 +246,17 @@ int force_fignore = 1;
/* Perform spelling correction on directory names during word completion */
int dircomplete_spelling = 0;
+/* Expand directory names during word/filename completion. */
+int dircomplete_expand = 0;
+int dircomplete_expand_relpath = 0;
+
static char *bash_completer_word_break_characters = " \t\n\"'@><=;|&(:";
static char *bash_nohostname_word_break_characters = " \t\n\"'><=;|&(:";
/* )) */
+static const char *default_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/
+static char *custom_filename_quote_characters = 0;
+
static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL;
static int dot_in_path = 0;
@@ -501,7 +511,7 @@ initialize_readline ()
/* Tell the completer that we might want to follow symbolic links or
do other expansion on directory names. */
- rl_directory_rewrite_hook = bash_directory_completion_hook;
+ set_directory_hook ();
rl_filename_rewrite_hook = bash_filename_rewrite_hook;
@@ -529,7 +539,7 @@ initialize_readline ()
enable_hostname_completion (perform_hostname_completion);
/* characters that need to be quoted when appearing in filenames. */
- rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/
+ rl_filename_quote_characters = default_filename_quote_characters;
rl_filename_quoting_function = bash_quote_filename;
rl_filename_dequoting_function = bash_dequote_filename;
@@ -564,8 +574,10 @@ bashline_reset ()
tilde_initialize ();
rl_attempted_completion_function = attempt_shell_completion;
rl_completion_entry_function = NULL;
- rl_directory_rewrite_hook = bash_directory_completion_hook;
rl_ignore_some_completions_function = filename_completion_ignore;
+ rl_filename_quote_characters = default_filename_quote_characters;
+
+ set_directory_hook ();
}
/* Contains the line to push into readline. */
@@ -1279,6 +1291,9 @@ attempt_shell_completion (text, start, e
matches = (char **)NULL;
rl_ignore_some_completions_function = filename_completion_ignore;
+ rl_filename_quote_characters = default_filename_quote_characters;
+ set_directory_hook ();
+
/* Determine if this could be a command word. It is if it appears at
the start of the line (ignoring preceding whitespace), or if it
appears after a character that separates commands. It cannot be a
@@ -1591,6 +1606,12 @@ command_word_completion_function (hint_t
}
else
{
+ if (dircomplete_expand && dot_or_dotdot (filename_hint))
+ {
+ dircomplete_expand = 0;
+ set_directory_hook ();
+ dircomplete_expand = 1;
+ }
mapping_over = 4;
goto inner;
}
@@ -1791,6 +1812,9 @@ globword:
inner:
val = rl_filename_completion_function (filename_hint, istate);
+ if (mapping_over == 4 && dircomplete_expand)
+ set_directory_hook ();
+
istate = 1;
if (val == 0)
@@ -2693,6 +2717,52 @@ bash_filename_rewrite_hook (fname, fnlen
return conv;
}
+/* Functions to save and restore the appropriate directory hook */
+/* This is not static so the shopt code can call it */
+void
+set_directory_hook ()
+{
+ if (dircomplete_expand)
+ {
+ rl_directory_completion_hook = bash_directory_completion_hook;
+ rl_directory_rewrite_hook = (rl_icppfunc_t *)0;
+ }
+ else
+ {
+ rl_directory_rewrite_hook = bash_directory_completion_hook;
+ rl_directory_completion_hook = (rl_icppfunc_t *)0;
+ }
+}
+
+static rl_icppfunc_t *
+save_directory_hook ()
+{
+ rl_icppfunc_t *ret;
+
+ if (dircomplete_expand)
+ {
+ ret = rl_directory_completion_hook;
+ rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
+ }
+ else
+ {
+ ret = rl_directory_rewrite_hook;
+ rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
+ }
+
+ return ret;
+}
+
+static void
+restore_directory_hook (hookf)
+ rl_icppfunc_t *hookf;
+{
+ if (dircomplete_expand)
+ rl_directory_completion_hook = hookf;
+ else
+ rl_directory_rewrite_hook = hookf;
+}
+
/* Handle symbolic link references and other directory name
expansions while hacking completion. This should return 1 if it modifies
the DIRNAME argument, 0 otherwise. It should make sure not to modify
@@ -2702,20 +2772,31 @@ bash_directory_completion_hook (dirname)
char **dirname;
{
char *local_dirname, *new_dirname, *t;
- int return_value, should_expand_dirname;
+ int return_value, should_expand_dirname, nextch, closer;
WORD_LIST *wl;
struct stat sb;
- return_value = should_expand_dirname = 0;
+ return_value = should_expand_dirname = nextch = closer = 0;
local_dirname = *dirname;
- if (mbschr (local_dirname, '$'))
- should_expand_dirname = 1;
+ if (t = mbschr (local_dirname, '$'))
+ {
+ should_expand_dirname = '$';
+ nextch = t[1];
+ /* Deliberately does not handle the deprecated $[...] arithmetic
+ expansion syntax */
+ if (nextch == '(')
+ closer = ')';
+ else if (nextch == '{')
+ closer = '}';
+ else
+ nextch = 0;
+ }
else
{
t = mbschr (local_dirname, '`');
if (t && unclosed_pair (local_dirname, strlen (local_dirname), "`") == 0)
- should_expand_dirname = 1;
+ should_expand_dirname = '`';
}
#if defined (HAVE_LSTAT)
@@ -2739,6 +2820,23 @@ bash_directory_completion_hook (dirname)
free (new_dirname);
dispose_words (wl);
local_dirname = *dirname;
+ /* XXX - change rl_filename_quote_characters here based on
+ should_expand_dirname/nextch/closer. This is the only place
+ custom_filename_quote_characters is modified. */
+ if (rl_filename_quote_characters && *rl_filename_quote_characters)
+ {
+ int i, j, c;
+ i = strlen (default_filename_quote_characters);
+ custom_filename_quote_characters = xrealloc (custom_filename_quote_characters, i+1);
+ for (i = j = 0; c = default_filename_quote_characters[i]; i++)
+ {
+ if (c == should_expand_dirname || c == nextch || c == closer)
+ continue;
+ custom_filename_quote_characters[j++] = c;
+ }
+ custom_filename_quote_characters[j] = '\0';
+ rl_filename_quote_characters = custom_filename_quote_characters;
+ }
}
else
{
@@ -2758,11 +2856,31 @@ bash_directory_completion_hook (dirname)
local_dirname = *dirname = new_dirname;
}
+ /* no_symbolic_links == 0 -> use (default) logical view of the file system.
+ local_dirname[0] == '.' && local_dirname[1] == '/' means files in the
+ current directory (./).
+ local_dirname[0] == '.' && local_dirname[1] == 0 means relative pathnames
+ in the current directory (e.g., lib/sh).
+ XXX - should we do spelling correction on these? */
+
+ /* This is test as it was in bash-4.2: skip relative pathnames in current
+ directory. Change test to
+ (local_dirname[0] != '.' || (local_dirname[1] && local_dirname[1] != '/'))
+ if we want to skip paths beginning with ./ also. */
if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1]))
{
char *temp1, *temp2;
int len1, len2;
+ /* If we have a relative path
+ (local_dirname[0] != '/' && local_dirname[0] != '.')
+ that is canonical after appending it to the current directory, then
+ temp1 = temp2+'/'
+ That is,
+ strcmp (temp1, temp2) == 0
+ after adding a slash to temp2 below. It should be safe to not
+ change those.
+ */
t = get_working_directory ("symlink-hook");
temp1 = make_absolute (local_dirname, t);
free (t);
@@ -2797,7 +2915,15 @@ bash_directory_completion_hook (dirname)
temp2[len2 + 1] = '\0';
}
}
- return_value |= STREQ (local_dirname, temp2) == 0;
+
+ /* dircomplete_expand_relpath == 0 means we want to leave relative
+ pathnames that are unchanged by canonicalization alone.
+ *local_dirname != '/' && *local_dirname != '.' == relative pathname
+ (consistent with general.c:absolute_pathname())
+ temp1 == temp2 (after appending a slash to temp2) means the pathname
+ is not changed by canonicalization as described above. */
+ if (dircomplete_expand_relpath || ((local_dirname[0] != '/' && local_dirname[0] != '.') && STREQ (temp1, temp2) == 0))
+ return_value |= STREQ (local_dirname, temp2) == 0;
free (local_dirname);
*dirname = temp2;
free (temp1);
@@ -3002,12 +3128,13 @@ bash_complete_filename_internal (what_to
orig_func = rl_completion_entry_function;
orig_attempt_func = rl_attempted_completion_function;
- orig_dir_func = rl_directory_rewrite_hook;
orig_ignore_func = rl_ignore_some_completions_function;
orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
+
+ orig_dir_func = save_directory_hook ();
+
rl_completion_entry_function = rl_filename_completion_function;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
- rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
rl_ignore_some_completions_function = filename_completion_ignore;
rl_completer_word_break_characters = " \t\n\"\'";
@@ -3015,10 +3142,11 @@ bash_complete_filename_internal (what_to
rl_completion_entry_function = orig_func;
rl_attempted_completion_function = orig_attempt_func;
- rl_directory_rewrite_hook = orig_dir_func;
rl_ignore_some_completions_function = orig_ignore_func;
rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
+ restore_directory_hook (orig_dir_func);
+
return r;
}
--- a/bashline.h
+++ b/bashline.h
@@ -33,10 +33,15 @@ extern void bashline_reset __P((void));
extern void bashline_reinitialize __P((void));
extern int bash_re_edit __P((char *));
+extern void bashline_set_event_hook __P((void));
+extern void bashline_reset_event_hook __P((void));
+
extern int bind_keyseq_to_unix_command __P((char *));
extern char **bash_default_completion __P((const char *, int, int, int, int));
+void set_directory_hook __P((void));
+
/* Used by programmable completion code. */
extern char *command_word_completion_function __P((const char *, int));
extern char *bash_groupname_completion_function __P((const char *, int));
--- a/builtins/shopt.def
+++ b/builtins/shopt.def
@@ -61,6 +61,10 @@ $END
#include "common.h"
#include "bashgetopt.h"
+#if defined (READLINE)
+# include "../bashline.h"
+#endif
+
#if defined (HISTORY)
# include "../bashhist.h"
#endif
@@ -94,7 +98,7 @@ extern int extended_glob;
extern int hist_verify, history_reediting, perform_hostname_completion;
extern int no_empty_command_completion;
extern int force_fignore;
-extern int dircomplete_spelling;
+extern int dircomplete_spelling, dircomplete_expand;
extern int enable_hostname_completion __P((int));
#endif
@@ -121,6 +125,10 @@ static int set_compatibility_level __P((
static int set_restricted_shell __P((char *, int));
#endif
+#if defined (READLINE)
+static int shopt_set_complete_direxpand __P((char *, int));
+#endif
+
static int shopt_login_shell;
static int shopt_compat31;
static int shopt_compat32;
@@ -150,6 +158,7 @@ static struct {
{ "compat40", &shopt_compat40, set_compatibility_level },
{ "compat41", &shopt_compat41, set_compatibility_level },
#if defined (READLINE)
+ { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
{ "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
#endif
{ "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
@@ -535,6 +544,17 @@ set_compatibility_level (option_name, mo
return 0;
}
+#if defined (READLINE)
+static int
+shopt_set_complete_direxpand (option_name, mode)
+ char *option_name;
+ int mode;
+{
+ set_directory_hook ();
+ return 0;
+}
+#endif
+
#if defined (RESTRICTED_SHELL)
/* Don't allow the value of restricted_shell to be modified. */
--- a/doc/bash.1
+++ b/doc/bash.1
@@ -8948,6 +8948,16 @@ parameter expansion as a special charact
quoted. This is the behavior of posix mode through version 4.1.
The default bash behavior remains as in previous versions.
.TP 8
+.B direxpand
+If set,
+.B bash
+replaces directory names with the results of word expansion when performing
+filename completion. This changes the contents of the readline editing
+buffer.
+If not set,
+.B bash
+attempts to preserve what the user typed.
+.TP 8
.B dirspell
If set,
.B bash
--- a/doc/bashref.texi
+++ b/doc/bashref.texi
@@ -4535,6 +4535,13 @@ parameter expansion as a special charact
quoted. This is the behavior of @sc{posix} mode through version 4.1.
The default Bash behavior remains as in previous versions.
+@item direxpand
+If set, Bash
+replaces directory names with the results of word expansion when performing
+filename completion. This changes the contents of the readline editing
+buffer.
+If not set, Bash attempts to preserve what the user typed.
+
@item dirspell
If set, Bash
attempts spelling correction on directory names during word completion
--- a/tests/shopt.right
+++ b/tests/shopt.right
@@ -12,6 +12,7 @@ shopt -u compat31
shopt -u compat32
shopt -u compat40
shopt -u compat41
+shopt -u direxpand
shopt -u dirspell
shopt -u dotglob
shopt -u execfail
@@ -68,6 +69,7 @@ shopt -u compat31
shopt -u compat32
shopt -u compat40
shopt -u compat41
+shopt -u direxpand
shopt -u dirspell
shopt -u dotglob
shopt -u execfail
@@ -101,6 +103,7 @@ compat31 off
compat32 off
compat40 off
compat41 off
+direxpand off
dirspell off
dotglob off
execfail off

View file

@ -0,0 +1,147 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-030
Bug-Reported-by: Roman Rakus <rrakus@redhat.com>
Bug-Reference-ID: <4D7DD91E.7040808@redhat.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2011-03/msg00126.html
Bug-Description:
When attempting to glob strings in a multibyte locale, and those strings
contain invalid multibyte characters that cause mbsnrtowcs to return 0,
the globbing code loops infinitely.
Patch (apply with `patch -p0'):
--- a/lib/glob/xmbsrtowcs.c
+++ b/lib/glob/xmbsrtowcs.c
@@ -35,6 +35,8 @@
#if HANDLE_MULTIBYTE
+#define WSBUF_INC 32
+
#ifndef FREE
# define FREE(x) do { if (x) free (x); } while (0)
#endif
@@ -148,7 +150,7 @@ xdupmbstowcs2 (destp, src)
size_t wsbuf_size; /* Size of WSBUF */
size_t wcnum; /* Number of wide characters in WSBUF */
mbstate_t state; /* Conversion State */
- size_t wcslength; /* Number of wide characters produced by the conversion. */
+ size_t n, wcslength; /* Number of wide characters produced by the conversion. */
const char *end_or_backslash;
size_t nms; /* Number of multibyte characters to convert at one time. */
mbstate_t tmp_state;
@@ -171,7 +173,18 @@ xdupmbstowcs2 (destp, src)
/* Compute the number of produced wide-characters. */
tmp_p = p;
tmp_state = state;
- wcslength = mbsnrtowcs(NULL, &tmp_p, nms, 0, &tmp_state);
+
+ if (nms == 0 && *p == '\\') /* special initial case */
+ nms = wcslength = 1;
+ else
+ wcslength = mbsnrtowcs (NULL, &tmp_p, nms, 0, &tmp_state);
+
+ if (wcslength == 0)
+ {
+ tmp_p = p; /* will need below */
+ tmp_state = state;
+ wcslength = 1; /* take a single byte */
+ }
/* Conversion failed. */
if (wcslength == (size_t)-1)
@@ -186,7 +199,8 @@ xdupmbstowcs2 (destp, src)
{
wchar_t *wstmp;
- wsbuf_size = wcnum+wcslength+1; /* 1 for the L'\0' or the potential L'\\' */
+ while (wsbuf_size < wcnum+wcslength+1) /* 1 for the L'\0' or the potential L'\\' */
+ wsbuf_size += WSBUF_INC;
wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
if (wstmp == NULL)
@@ -199,10 +213,18 @@ xdupmbstowcs2 (destp, src)
}
/* Perform the conversion. This is assumed to return 'wcslength'.
- * It may set 'p' to NULL. */
- mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state);
+ It may set 'p' to NULL. */
+ n = mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state);
- wcnum += wcslength;
+ /* Compensate for taking single byte on wcs conversion failure above. */
+ if (wcslength == 1 && (n == 0 || n == (size_t)-1))
+ {
+ state = tmp_state;
+ p = tmp_p;
+ wsbuf[wcnum++] = *p++;
+ }
+ else
+ wcnum += wcslength;
if (mbsinit (&state) && (p != NULL) && (*p == '\\'))
{
@@ -230,8 +252,6 @@ xdupmbstowcs2 (destp, src)
If conversion is failed, the return value is (size_t)-1 and the values
of DESTP and INDICESP are NULL. */
-#define WSBUF_INC 32
-
size_t
xdupmbstowcs (destp, indicesp, src)
wchar_t **destp; /* Store the pointer to the wide character string */
--- a/lib/glob/glob.c
+++ b/lib/glob/glob.c
@@ -200,8 +200,11 @@ mbskipname (pat, dname, flags)
wchar_t *pat_wc, *dn_wc;
size_t pat_n, dn_n;
+ pat_wc = dn_wc = (wchar_t *)NULL;
+
pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
- dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
+ if (pat_n != (size_t)-1)
+ dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
ret = 0;
if (pat_n != (size_t)-1 && dn_n !=(size_t)-1)
@@ -221,6 +224,8 @@ mbskipname (pat, dname, flags)
(pat_wc[0] != L'\\' || pat_wc[1] != L'.'))
ret = 1;
}
+ else
+ ret = skipname (pat, dname, flags);
FREE (pat_wc);
FREE (dn_wc);
@@ -266,8 +271,11 @@ wdequote_pathname (pathname)
/* Convert the strings into wide characters. */
n = xdupmbstowcs (&wpathname, NULL, pathname);
if (n == (size_t) -1)
- /* Something wrong. */
- return;
+ {
+ /* Something wrong. Fall back to single-byte */
+ udequote_pathname (pathname);
+ return;
+ }
orig_wpathname = wpathname;
for (i = j = 0; wpathname && wpathname[i]; )
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 29
+#define PATCHLEVEL 30
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,62 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-031
Bug-Reported-by: Max Horn <max@quendi.de>
Bug-Reference-ID: <20CC5C60-07C3-4E41-9817-741E48D407C5@quendi.de>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-readline/2012-06/msg00005.html
Bug-Description:
A change between bash-4.1 and bash-4.2 to prevent the readline input hook
from being called too frequently had the side effect of causing delays
when reading pasted input on systems such as Mac OS X. This patch fixes
those delays while retaining the bash-4.2 behavior.
Patch (apply with `patch -p0'):
--- a/lib/readline/input.c
+++ b/lib/readline/input.c
@@ -409,7 +409,7 @@ rl_clear_pending_input ()
int
rl_read_key ()
{
- int c;
+ int c, r;
rl_key_sequence_length++;
@@ -429,14 +429,18 @@ rl_read_key ()
{
while (rl_event_hook)
{
- if (rl_gather_tyi () < 0) /* XXX - EIO */
+ if (rl_get_char (&c) != 0)
+ break;
+
+ if ((r = rl_gather_tyi ()) < 0) /* XXX - EIO */
{
rl_done = 1;
return ('\n');
}
+ else if (r == 1) /* read something */
+ continue;
+
RL_CHECK_SIGNALS ();
- if (rl_get_char (&c) != 0)
- break;
if (rl_done) /* XXX - experimental */
return ('\n');
(*rl_event_hook) ();
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 30
+#define PATCHLEVEL 31
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,62 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-032
Bug-Reported-by: Ruediger Kuhlmann <RKuhlmann@orga-systems.com>
Bug-Reference-ID: <OFDE975207.0C3622E5-ONC12579F3.00361A06-C12579F3.00365E39@orga-systems.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2012-05/msg00010.html
Bug-Description:
Bash-4.2 has problems with DEL characters in the expanded value of variables
used in the same quoted string as variables that expand to nothing.
Patch (apply with `patch -p0'):
--- a/subst.c
+++ b/subst.c
@@ -8151,6 +8151,14 @@ add_string:
temp = tword->word;
dispose_word_desc (tword);
+ /* Kill quoted nulls; we will add them back at the end of
+ expand_word_internal if nothing else in the string */
+ if (had_quoted_null && temp && QUOTED_NULL (temp))
+ {
+ FREE (temp);
+ temp = (char *)NULL;
+ }
+
goto add_string;
break;
@@ -8555,7 +8563,7 @@ finished_with_string:
tword->flags |= W_NOEXPAND; /* XXX */
if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
tword->flags |= W_QUOTED;
- if (had_quoted_null)
+ if (had_quoted_null && QUOTED_NULL (istring))
tword->flags |= W_HASQUOTEDNULL;
list = make_word_list (tword, (WORD_LIST *)NULL);
}
@@ -8586,7 +8594,7 @@ finished_with_string:
tword->flags |= W_NOGLOB;
if (word->flags & W_NOEXPAND)
tword->flags |= W_NOEXPAND;
- if (had_quoted_null)
+ if (had_quoted_null && QUOTED_NULL (istring))
tword->flags |= W_HASQUOTEDNULL; /* XXX */
list = make_word_list (tword, (WORD_LIST *)NULL);
}
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 31
+#define PATCHLEVEL 32
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,48 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-033
Bug-Reported-by: David Leverton <levertond@googlemail.com>
Bug-Reference-ID: <4FCCE737.1060603@googlemail.com>
Bug-Reference-URL:
Bug-Description:
Bash uses a static buffer when expanding the /dev/fd prefix for the test
and conditional commands, among other uses, when it should use a dynamic
buffer to avoid buffer overflow.
Patch (apply with `patch -p0'):
--- a/lib/sh/eaccess.c
+++ b/lib/sh/eaccess.c
@@ -82,6 +82,8 @@ sh_stat (path, finfo)
const char *path;
struct stat *finfo;
{
+ static char *pbuf = 0;
+
if (*path == '\0')
{
errno = ENOENT;
@@ -106,7 +108,7 @@ sh_stat (path, finfo)
trailing slash. Make sure /dev/fd/xx really uses DEV_FD_PREFIX/xx.
On most systems, with the notable exception of linux, this is
effectively a no-op. */
- char pbuf[32];
+ pbuf = xrealloc (pbuf, sizeof (DEV_FD_PREFIX) + strlen (path + 8));
strcpy (pbuf, DEV_FD_PREFIX);
strcat (pbuf, path + 8);
return (stat (pbuf, finfo));
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 32
+#define PATCHLEVEL 33
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,39 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-034
Bug-Reported-by: "Davide Brini" <dave_br@gmx.com>
Bug-Reference-ID: <20120604164154.69781EC04B@imaps.oficinas.atrapalo.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2012-06/msg00030.html
Bug-Description:
In bash-4.2, the history code would inappropriately add a semicolon to
multi-line compound array assignments when adding them to the history.
Patch (apply with `patch -p0'):
--- a/parse.y
+++ b/parse.y
@@ -4900,6 +4900,9 @@ history_delimiting_chars (line)
return (current_command_line_count == 2 ? "\n" : "");
}
+ if (parser_state & PST_COMPASSIGN)
+ return (" ");
+
/* First, handle some special cases. */
/*(*/
/* If we just read `()', assume it's a function definition, and don't
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 33
+#define PATCHLEVEL 34
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,56 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-035
Bug-Reported-by: Dan Douglas <ormaaj@gmail.com>
Bug-Reference-ID: <2766482.Ksm3GrSoYi@smorgbox>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2012-06/msg00071.html
Bug-Description:
When given a number of lines to read, `mapfile -n lines' reads one too many.
Patch (apply with `patch -p0'):
--- a/builtins/mapfile.def
+++ b/builtins/mapfile.def
@@ -195,13 +195,9 @@ mapfile (fd, line_count_goal, origin, ns
/* Reset the buffer for bash own stream */
interrupt_immediately++;
for (array_index = origin, line_count = 1;
- zgetline (fd, &line, &line_length, unbuffered_read) != -1;
- array_index++, line_count++)
+ zgetline (fd, &line, &line_length, unbuffered_read) != -1;
+ array_index++)
{
- /* Have we exceeded # of lines to store? */
- if (line_count_goal != 0 && line_count > line_count_goal)
- break;
-
/* Remove trailing newlines? */
if (flags & MAPF_CHOP)
do_chop (line);
@@ -217,6 +213,11 @@ mapfile (fd, line_count_goal, origin, ns
}
bind_array_element (entry, array_index, line, 0);
+
+ /* Have we exceeded # of lines to store? */
+ line_count++;
+ if (line_count_goal != 0 && line_count > line_count_goal)
+ break;
}
xfree (line);
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 34
+#define PATCHLEVEL 35
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,69 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-036
Bug-Reported-by: gregrwm <backuppc-users@whitleymott.net>
Bug-Reference-ID: <CAD+dB9B4JG+qUwZBQUwiQmVt0j6NDn=DDTxr9R+nkA8DL4KLJA@mail.gmail.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2012-05/msg00108.html
Bug-Description:
Bash-4.2 produces incorrect word splitting results when expanding
double-quoted $@ in the same string as and adjacent to other variable
expansions. The $@ should be split, the other expansions should not.
Patch (apply with `patch -p0'):
--- a/subst.c
+++ b/subst.c
@@ -7922,7 +7922,7 @@ expand_word_internal (word, quoted, isex
/* State flags */
int had_quoted_null;
- int has_dollar_at;
+ int has_dollar_at, temp_has_dollar_at;
int tflag;
int pflags; /* flags passed to param_expand */
@@ -8127,13 +8127,14 @@ add_string:
if (expanded_something)
*expanded_something = 1;
- has_dollar_at = 0;
+ temp_has_dollar_at = 0;
pflags = (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0;
if (word->flags & W_NOSPLIT2)
pflags |= PF_NOSPLIT2;
tword = param_expand (string, &sindex, quoted, expanded_something,
- &has_dollar_at, &quoted_dollar_at,
+ &temp_has_dollar_at, &quoted_dollar_at,
&had_quoted_null, pflags);
+ has_dollar_at += temp_has_dollar_at;
if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
{
@@ -8274,9 +8275,10 @@ add_twochars:
temp = (char *)NULL;
- has_dollar_at = 0;
+ temp_has_dollar_at = 0; /* XXX */
/* Need to get W_HASQUOTEDNULL flag through this function. */
- list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
+ list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &temp_has_dollar_at, (int *)NULL);
+ has_dollar_at += temp_has_dollar_at;
if (list == &expand_word_error || list == &expand_word_fatal)
{
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 35
+#define PATCHLEVEL 36
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,91 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-037
Bug-Reported-by: Jakub Filak
Bug-Reference-ID:
Bug-Reference-URL: https://bugzilla.redhat.com/show_bug.cgi?id=813289
Bug-Description:
Attempting to redo (using `.') the vi editing mode `cc', `dd', or `yy'
commands leads to an infinite loop.
Patch (apply with `patch -p0'):
--- a/lib/readline/vi_mode.c
+++ b/lib/readline/vi_mode.c
@@ -1234,11 +1234,19 @@ rl_vi_delete_to (count, key)
_rl_vimvcxt->motion = '$';
r = rl_domove_motion_callback (_rl_vimvcxt);
}
- else if (vi_redoing)
+ else if (vi_redoing && _rl_vi_last_motion != 'd') /* `dd' is special */
{
_rl_vimvcxt->motion = _rl_vi_last_motion;
r = rl_domove_motion_callback (_rl_vimvcxt);
}
+ else if (vi_redoing) /* handle redoing `dd' here */
+ {
+ _rl_vimvcxt->motion = _rl_vi_last_motion;
+ rl_mark = rl_end;
+ rl_beg_of_line (1, key);
+ RL_UNSETSTATE (RL_STATE_VIMOTION);
+ r = vidomove_dispatch (_rl_vimvcxt);
+ }
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
@@ -1316,11 +1324,19 @@ rl_vi_change_to (count, key)
_rl_vimvcxt->motion = '$';
r = rl_domove_motion_callback (_rl_vimvcxt);
}
- else if (vi_redoing)
+ else if (vi_redoing && _rl_vi_last_motion != 'c') /* `cc' is special */
{
_rl_vimvcxt->motion = _rl_vi_last_motion;
r = rl_domove_motion_callback (_rl_vimvcxt);
}
+ else if (vi_redoing) /* handle redoing `cc' here */
+ {
+ _rl_vimvcxt->motion = _rl_vi_last_motion;
+ rl_mark = rl_end;
+ rl_beg_of_line (1, key);
+ RL_UNSETSTATE (RL_STATE_VIMOTION);
+ r = vidomove_dispatch (_rl_vimvcxt);
+ }
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
@@ -1377,6 +1393,19 @@ rl_vi_yank_to (count, key)
_rl_vimvcxt->motion = '$';
r = rl_domove_motion_callback (_rl_vimvcxt);
}
+ else if (vi_redoing && _rl_vi_last_motion != 'y') /* `yy' is special */
+ {
+ _rl_vimvcxt->motion = _rl_vi_last_motion;
+ r = rl_domove_motion_callback (_rl_vimvcxt);
+ }
+ else if (vi_redoing) /* handle redoing `yy' here */
+ {
+ _rl_vimvcxt->motion = _rl_vi_last_motion;
+ rl_mark = rl_end;
+ rl_beg_of_line (1, key);
+ RL_UNSETSTATE (RL_STATE_VIMOTION);
+ r = vidomove_dispatch (_rl_vimvcxt);
+ }
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 36
+#define PATCHLEVEL 37
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,38 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-038
Bug-Reported-by: armandsl@gmail.com
Bug-Reference-ID: <20120822112810.8D14920040@windmill.latviatours.lv>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2012-08/msg00049.html
Bug-Description:
If a backslash-newline (which is removed) with no other input is given as
input to `read', the shell tries to dereference a null pointer and seg faults.
Patch (apply with `patch -p0'):
--- a/builtins/read.def
+++ b/builtins/read.def
@@ -791,7 +791,7 @@ assign_vars:
}
#endif
- if (saw_escape)
+ if (saw_escape && input_string && *input_string)
{
t = dequote_string (input_string);
var = bind_read_variable (list->word->word, t);
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 37
+#define PATCHLEVEL 38
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,53 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-039
Bug-Reported-by: Dan Douglas <ormaaj@gmail.com>
Bug-Reference-ID: <1498458.MpVlmOXDB7@smorgbox>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2012-09/msg00008.html
Bug-Description:
Under certain circumstances, bash attempts to expand variables in arithmetic
expressions even when evaluation is being suppressed.
Patch (apply with `patch -p0'):
--- a/expr.c
+++ b/expr.c
@@ -1009,6 +1009,12 @@ expr_streval (tok, e, lvalue)
arrayind_t ind;
#endif
+/*itrace("expr_streval: %s: noeval = %d", tok, noeval);*/
+ /* If we are suppressing evaluation, just short-circuit here instead of
+ going through the rest of the evaluator. */
+ if (noeval)
+ return (0);
+
/* [[[[[ */
#if defined (ARRAY_VARS)
v = (e == ']') ? array_variable_part (tok, (char **)0, (int *)0) : find_variable (tok);
@@ -1182,6 +1188,10 @@ readtok ()
#endif /* ARRAY_VARS */
*cp = '\0';
+ /* XXX - watch out for pointer aliasing issues here */
+ if (curlval.tokstr && curlval.tokstr == tokstr)
+ init_lvalue (&curlval);
+
FREE (tokstr);
tokstr = savestring (tp);
*cp = c;
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 38
+#define PATCHLEVEL 39
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,45 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-040
Bug-Reported-by: Andrey Zaitsev <jstcdr@gmail.com>
Bug-Reference-ID: <CAEZVQT5PJ1Mb_Zh8LT5qz8sv+-9Q6hGfQ5DU9ZxdJ+gV7xBUaQ@mail.gmail.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2012-04/msg00144.html
Bug-Description:
Output redirection applied to builtin commands missed I/O errors if
they happened when the file descriptor was closed, rather than on write
(e.g., like with an out-of-space error on a remote NFS file system).
Patch (apply with `patch -p0'):
--- a/redir.c
+++ b/redir.c
@@ -1091,10 +1091,12 @@ do_redirection_internal (redirect, flags
#if defined (BUFFERED_INPUT)
check_bash_input (redirector);
- close_buffered_fd (redirector);
+ r = close_buffered_fd (redirector);
#else /* !BUFFERED_INPUT */
- close (redirector);
+ r = close (redirector);
#endif /* !BUFFERED_INPUT */
+ if (r < 0 && (flags & RX_INTERNAL) && (errno == EIO || errno == ENOSPC))
+ REDIRECTION_ERROR (r, errno, -1);
}
break;
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 39
+#define PATCHLEVEL 40
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,42 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-041
Bug-Reported-by: Andrey Borzenkov <arvidjaar@gmail.com>
Bug-Reference-ID: <20121202205200.2134478e@opensuse.site>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2012-12/msg00008.html
Bug-Description:
Process substitution incorrectly inherited a flag that inhibited using the
(local) temporary environment for variable lookups if it was providing
the filename to a redirection. The intent the flag is to enforce the
Posix command expansion ordering rules.
Patch (apply with `patch -p0'):
--- a/subst.c
+++ b/subst.c
@@ -5124,6 +5124,10 @@ process_substitute (string, open_for_rea
dev_fd_list[parent_pipe_fd] = 0;
#endif /* HAVE_DEV_FD */
+ /* subshells shouldn't have this flag, which controls using the temporary
+ environment for variable lookups. */
+ expanding_redir = 0;
+
result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
#if !defined (HAVE_DEV_FD)
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 40
+#define PATCHLEVEL 41
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,47 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-042
Bug-Reported-by: Adam Pippin <adam@gp-inc.ca>
Bug-Reference-ID: <CAPYbNHr6ucZFOoWsRdUJj6KP3Ju0j1bkESa_cmb7iU+kZwdVpg@mail.gmail.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2012-11/msg00087.html
Bug-Description:
Compilation failed after specifying the `--enable-minimal-config' option to
configure (more specifically, specifying `--disable-alias').
Patch (apply with `patch -p0'):
--- a/parse.y
+++ b/parse.y
@@ -2393,6 +2393,7 @@ pop_alias:
is the last character). If it's not the last character, we need
to consume the quoted newline and move to the next character in
the expansion. */
+#if defined (ALIAS)
if (expanding_alias () && shell_input_line[shell_input_line_index+1] == '\0')
{
uc = 0;
@@ -2403,7 +2404,8 @@ pop_alias:
shell_input_line_index++; /* skip newline */
goto next_alias_char; /* and get next character */
}
- else
+ else
+#endif
goto restart_read;
}
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 41
+#define PATCHLEVEL 42
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,54 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-043
Bug-Reported-by: konsolebox <konsolebox@gmail.com>
Bug-Reference-ID: <CAJnmqwZuGKLgMsMwxRK4LL+2NN+HgvmKzrnode99QBGrcgX1Lw@mail.gmail.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2013-01/msg00138.html
Bug-Description:
When SIGCHLD is trapped, and a SIGCHLD trap handler runs when a pending
`read -t' invocation times out and generates SIGALRM, bash can crash with
a segmentation fault.
Patch (apply with `patch -p0'):
--- a/builtins/read.def
+++ b/builtins/read.def
@@ -385,10 +385,20 @@ read_builtin (list)
{
/* Tricky. The top of the unwind-protect stack is the free of
input_string. We want to run all the rest and use input_string,
- so we have to remove it from the stack. */
- remove_unwind_protect ();
- run_unwind_frame ("read_builtin");
+ so we have to save input_string temporarily, run the unwind-
+ protects, then restore input_string so we can use it later. */
+
input_string[i] = '\0'; /* make sure it's terminated */
+ if (i == 0)
+ {
+ t = (char *)xmalloc (1);
+ t[0] = 0;
+ }
+ else
+ t = savestring (input_string);
+
+ run_unwind_frame ("read_builtin");
+ input_string = t;
retval = 128+SIGALRM;
goto assign_vars;
}
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 42
+#define PATCHLEVEL 43
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,58 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-044
Bug-Reported-by: "Dashing" <dashing@hushmail.com>
Bug-Reference-ID: <20130211175049.D90786F446@smtp.hushmail.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2013-02/msg00030.html
Bug-Description:
When converting a multibyte string to a wide character string as part of
pattern matching, bash does not handle the end of the string correctly,
causing the search for the NUL to go beyond the end of the string and
reference random memory. Depending on the contents of that memory, bash
can produce errors or crash.
Patch (apply with `patch -p0'):
--- a/lib/glob/xmbsrtowcs.c
+++ b/lib/glob/xmbsrtowcs.c
@@ -216,12 +216,24 @@ xdupmbstowcs2 (destp, src)
It may set 'p' to NULL. */
n = mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state);
+ if (n == 0 && p == 0)
+ {
+ wsbuf[wcnum] = L'\0';
+ break;
+ }
+
/* Compensate for taking single byte on wcs conversion failure above. */
if (wcslength == 1 && (n == 0 || n == (size_t)-1))
{
state = tmp_state;
p = tmp_p;
- wsbuf[wcnum++] = *p++;
+ wsbuf[wcnum] = *p;
+ if (*p == 0)
+ break;
+ else
+ {
+ wcnum++; p++;
+ }
}
else
wcnum += wcslength;
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 43
+#define PATCHLEVEL 44
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,47 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-045
Bug-Reported-by: Stephane Chazelas <stephane.chazelas@gmail.com>
Bug-Reference-ID: <20130218195539.GA9620@chaz.gmail.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2013-02/msg00080.html
Bug-Description:
The <&n- and >&n- redirections, which move one file descriptor to another,
leave the file descriptor closed when applied to builtins or compound
commands.
Patch (apply with `patch -p0'):
--- a/redir.c
+++ b/redir.c
@@ -1007,6 +1007,16 @@ do_redirection_internal (redirect, flags
close (redirector);
REDIRECTION_ERROR (r, errno, -1);
}
+ if ((flags & RX_UNDOABLE) && (ri == r_move_input || ri == r_move_output))
+ {
+ /* r_move_input and r_move_output add an additional close()
+ that needs to be undone */
+ if (fcntl (redirector, F_GETFD, 0) != -1)
+ {
+ r = add_undo_redirect (redir_fd, r_close_this, -1);
+ REDIRECTION_ERROR (r, errno, -1);
+ }
+ }
#if defined (BUFFERED_INPUT)
check_bash_input (redirector);
#endif
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 44
+#define PATCHLEVEL 45
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,46 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-046
Bug-Reported-by: "Theodoros V. Kalamatianos" <thkala@gmail.com>
Bug-Reference-ID: <20140112011131.GE17667@infinity.metashade.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2014-01/msg00044.html
Bug-Description:
Bash-4.2 patch 32 introduced a problem with "$@" and arrays expanding empty
positional parameters or array elements when using substring expansion,
pattern substitution, or case modfication. The empty parameters or array
elements are removed instead of expanding to empty strings ("").
Patch (apply with `patch -p0'):
--- a/subst.c
+++ b/subst.c
@@ -7242,7 +7242,13 @@ parameter_brace_expand (string, indexp,
ret = alloc_word_desc ();
ret->word = temp1;
- if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
+ /* We test quoted_dollar_atp because we want variants with double-quoted
+ "$@" to take a different code path. In fact, we make sure at the end
+ of expand_word_internal that we're only looking at these flags if
+ quoted_dollar_at == 0. */
+ if (temp1 &&
+ (quoted_dollar_atp == 0 || *quoted_dollar_atp == 0) &&
+ QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
return ret;
}
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 45
+#define PATCHLEVEL 46
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,40 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-047
Bug-Reported-by: Matthew Riley <mattdr@google.com>
Bug-Reference-ID: <CA+NEdkwP3gw+gbcF5+xnR1pvcuzb1mDVzvmuJOpHRGHA9T7VFg@mail.gmail.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2013-03/msg00047.html
Bug-Description:
The function that shortens pathnames for $PS1 according to the value of
$PROMPT_DIRTRIM uses memcpy on potentially-overlapping regions of memory,
when it should use memmove. The result is garbled pathnames in prompt
strings.
Patch (apply with `patch -p0'):
--- a/general.c
+++ b/general.c
@@ -766,7 +766,7 @@ trim_pathname (name, maxlen)
*nbeg++ = '.';
nlen = nend - ntail;
- memcpy (nbeg, ntail, nlen);
+ memmove (nbeg, ntail, nlen);
nbeg[nlen] = '\0';
return name;
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 46
+#define PATCHLEVEL 47
#endif /* _PATCHLEVEL_H_ */

View file

@ -0,0 +1,95 @@
BASH PATCH REPORT
=================
Bash-Release: 4.2
Patch-ID: bash42-048
Bug-Reported-by: Stephane Chazelas <stephane.chazelas@gmail.com>
Bug-Reference-ID:
Bug-Reference-URL:
Bug-Description:
Under certain circumstances, bash will execute user code while processing the
environment for exported function definitions.
Patch (apply with `patch -p0'):
--- a/builtins/common.h
+++ b/builtins/common.h
@@ -35,6 +35,8 @@
#define SEVAL_NOLONGJMP 0x040
/* Flags for describe_command, shared between type.def and command.def */
+#define SEVAL_FUNCDEF 0x080 /* only allow function definitions */
+#define SEVAL_ONECMD 0x100 /* only allow a single command */
#define CDESC_ALL 0x001 /* type -a */
#define CDESC_SHORTDESC 0x002 /* command -V */
#define CDESC_REUSABLE 0x004 /* command -v */
--- a/builtins/evalstring.c
+++ b/builtins/evalstring.c
@@ -261,6 +261,14 @@ parse_and_execute (string, from_file, fl
{
struct fd_bitmap *bitmap;
+ if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def)
+ {
+ internal_warning ("%s: ignoring function definition attempt", from_file);
+ should_jump_to_top_level = 0;
+ last_result = last_command_exit_value = EX_BADUSAGE;
+ break;
+ }
+
bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
begin_unwind_frame ("pe_dispose");
add_unwind_protect (dispose_fd_bitmap, bitmap);
@@ -321,6 +329,9 @@ parse_and_execute (string, from_file, fl
dispose_command (command);
dispose_fd_bitmap (bitmap);
discard_unwind_frame ("pe_dispose");
+
+ if (flags & SEVAL_ONECMD)
+ break;
}
}
else
--- a/variables.c
+++ b/variables.c
@@ -347,12 +347,10 @@ initialize_shell_variables (env, privmod
temp_string[char_index] = ' ';
strcpy (temp_string + char_index + 1, string);
- parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
-
- /* Ancient backwards compatibility. Old versions of bash exported
- functions like name()=() {...} */
- if (name[char_index - 1] == ')' && name[char_index - 2] == '(')
- name[char_index - 2] = '\0';
+ /* Don't import function names that are invalid identifiers from the
+ environment. */
+ if (legal_identifier (name))
+ parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
if (temp_var = find_function (name))
{
@@ -361,10 +359,6 @@ initialize_shell_variables (env, privmod
}
else
report_error (_("error importing function definition for `%s'"), name);
-
- /* ( */
- if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')
- name[char_index - 2] = '('; /* ) */
}
#if defined (ARRAY_VARS)
# if 0
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 47
+#define PATCHLEVEL 48
#endif /* _PATCHLEVEL_H_ */