- Update bash to 4.4.18 - Enable PKG_CHECK_FORMAT_SECURITY - Use shared libreadline - Enable job control Fixes #5796, Closes #5858 Signed-off-by: Daniel Engberg <daniel.engberg.lists@pyret.net> Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>lilik-openwrt-22.03
@ -1,17 +0,0 @@ | |||||
Index: bash-4.4/execute_cmd.c | |||||
=================================================================== | |||||
--- bash-4.4.orig/execute_cmd.c | |||||
+++ bash-4.4/execute_cmd.c | |||||
@@ -2459,7 +2459,11 @@ execute_pipeline (command, asynchronous, | |||||
/* If the `lastpipe' option is set with shopt, and job control is not | |||||
enabled, execute the last element of non-async pipelines in the | |||||
current shell environment. */ | |||||
- if (lastpipe_opt && job_control == 0 && asynchronous == 0 && pipe_out == NO_PIPE && prev > 0) | |||||
+ if (lastpipe_opt && | |||||
+#if defined(JOB_CONTROL) | |||||
+ job_control == 0 && | |||||
+#endif | |||||
+ asynchronous == 0 && pipe_out == NO_PIPE && prev > 0) | |||||
{ | |||||
lstdin = move_to_high_fd (0, 1, -1); | |||||
if (lstdin > 0) |
@ -1,28 +0,0 @@ | |||||
Index: bash-4.4/configure | |||||
=================================================================== | |||||
--- bash-4.4.orig/configure | |||||
+++ bash-4.4/configure | |||||
@@ -5420,8 +5420,7 @@ if test $opt_readline = yes; then | |||||
# static version specified as -llibname to override the | |||||
# dynamic version | |||||
case "${host_os}" in | |||||
- darwin[89]*|darwin10*) READLINE_LIB='${READLINE_LIBRARY}' ;; | |||||
- *) READLINE_LIB=-lreadline ;; | |||||
+ *) READLINE_LIB='${READLINE_LIBRARY}' ;; | |||||
esac | |||||
fi | |||||
else | |||||
Index: bash-4.4/configure.ac | |||||
=================================================================== | |||||
--- bash-4.4.orig/configure.ac | |||||
+++ bash-4.4/configure.ac | |||||
@@ -573,8 +573,7 @@ if test $opt_readline = yes; then | |||||
# static version specified as -llibname to override the | |||||
# dynamic version | |||||
case "${host_os}" in | |||||
- darwin[[89]]*|darwin10*) READLINE_LIB='${READLINE_LIBRARY}' ;; | |||||
- *) READLINE_LIB=-lreadline ;; | |||||
+ *) READLINE_LIB='${READLINE_LIBRARY}' ;; | |||||
esac | |||||
fi | |||||
else |
@ -0,0 +1,31 @@ | |||||
Fix builint command jobs | |||||
Patch was taken from https://git.alpinelinux.org/cgit/aports/tree/main/bash/fix-jobs.patch | |||||
See also "Bash 4.4.12-r2 jobs hangs on arm (alpine 3.7)", https://bugs.alpinelinux.org/issues/8447 | |||||
diff --git a/jobs.c b/jobs.c | |||||
index cef3c79..bf99266 100644 | |||||
--- a/jobs.c | |||||
+++ b/jobs.c | |||||
@@ -4166,10 +4166,8 @@ initialize_job_control (force) | |||||
if (js.c_childmax < 0) | |||||
js.c_childmax = DEFAULT_CHILD_MAX; | |||||
-#if 0 | |||||
if (js.c_childmax > MAX_CHILD_MAX) | |||||
js.c_childmax = MAX_CHILD_MAX; | |||||
-#endif | |||||
return job_control; | |||||
} | |||||
@@ -4547,10 +4545,8 @@ mark_dead_jobs_as_notified (force) | |||||
if (js.c_childmax < 0) | |||||
js.c_childmax = DEFAULT_CHILD_MAX; | |||||
-#if 0 | |||||
if (js.c_childmax > MAX_CHILD_MAX) | |||||
js.c_childmax = MAX_CHILD_MAX; | |||||
-#endif | |||||
/* Don't do anything if the number of dead processes is less than CHILD_MAX | |||||
and we're not forcing a cleanup. */ |
@ -1,36 +0,0 @@ | |||||
Index: bash-4.4/lib/readline/history.c | |||||
=================================================================== | |||||
--- bash-4.4.orig/lib/readline/history.c | |||||
+++ bash-4.4/lib/readline/history.c | |||||
@@ -57,6 +57,8 @@ extern int errno; | |||||
/* How big to make the_history when we first allocate it. */ | |||||
#define DEFAULT_HISTORY_INITIAL_SIZE 502 | |||||
+#define MAX_HISTORY_INITIAL_SIZE 8192 | |||||
+ | |||||
/* The number of slots to increase the_history by. */ | |||||
#define DEFAULT_HISTORY_GROW_SIZE 50 | |||||
@@ -307,7 +309,9 @@ add_history (string) | |||||
if (history_size == 0) | |||||
{ | |||||
if (history_stifled && history_max_entries > 0) | |||||
- history_size = history_max_entries + 2; | |||||
+ history_size = (history_max_entries > MAX_HISTORY_INITIAL_SIZE) | |||||
+ ? MAX_HISTORY_INITIAL_SIZE | |||||
+ : history_max_entries + 2; | |||||
else | |||||
history_size = DEFAULT_HISTORY_INITIAL_SIZE; | |||||
the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *)); | |||||
Index: bash-4.4/patchlevel.h | |||||
=================================================================== | |||||
--- bash-4.4.orig/patchlevel.h | |||||
+++ bash-4.4/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 0 | |||||
+#define PATCHLEVEL 1 | |||||
#endif /* _PATCHLEVEL_H_ */ |
@ -1,46 +0,0 @@ | |||||
Index: bash-4.4/patchlevel.h | |||||
=================================================================== | |||||
--- bash-4.4.orig/patchlevel.h | |||||
+++ bash-4.4/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 1 | |||||
+#define PATCHLEVEL 2 | |||||
#endif /* _PATCHLEVEL_H_ */ | |||||
Index: bash-4.4/subst.c | |||||
=================================================================== | |||||
--- bash-4.4.orig/subst.c | |||||
+++ bash-4.4/subst.c | |||||
@@ -5931,6 +5931,7 @@ read_comsub (fd, quoted, rflag) | |||||
char *istring, buf[128], *bufp, *s; | |||||
int istring_index, istring_size, c, tflag, skip_ctlesc, skip_ctlnul; | |||||
ssize_t bufn; | |||||
+ int nullbyte; | |||||
istring = (char *)NULL; | |||||
istring_index = istring_size = bufn = tflag = 0; | |||||
@@ -5938,6 +5939,8 @@ read_comsub (fd, quoted, rflag) | |||||
for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++) | |||||
skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL; | |||||
+ nullbyte = 0; | |||||
+ | |||||
/* Read the output of the command through the pipe. This may need to be | |||||
changed to understand multibyte characters in the future. */ | |||||
while (1) | |||||
@@ -5956,7 +5959,11 @@ read_comsub (fd, quoted, rflag) | |||||
if (c == 0) | |||||
{ | |||||
#if 1 | |||||
- internal_warning ("%s", _("command substitution: ignored null byte in input")); | |||||
+ if (nullbyte == 0) | |||||
+ { | |||||
+ internal_warning ("%s", _("command substitution: ignored null byte in input")); | |||||
+ nullbyte = 1; | |||||
+ } | |||||
#endif | |||||
continue; | |||||
} |
@ -1,39 +0,0 @@ | |||||
Index: bash-4.4/lib/glob/sm_loop.c | |||||
=================================================================== | |||||
--- bash-4.4.orig/lib/glob/sm_loop.c | |||||
+++ bash-4.4/lib/glob/sm_loop.c | |||||
@@ -330,6 +330,12 @@ PARSE_COLLSYM (p, vp) | |||||
for (pc = 0; p[pc]; pc++) | |||||
if (p[pc] == L('.') && p[pc+1] == L(']')) | |||||
break; | |||||
+ if (p[pc] == 0) | |||||
+ { | |||||
+ if (vp) | |||||
+ *vp = INVALID; | |||||
+ return (p + pc); | |||||
+ } | |||||
val = COLLSYM (p, pc); | |||||
if (vp) | |||||
*vp = val; | |||||
@@ -483,6 +489,9 @@ BRACKMATCH (p, test, flags) | |||||
c = *p++; | |||||
c = FOLD (c); | |||||
+ if (c == L('\0')) | |||||
+ return ((test == L('[')) ? savep : (CHAR *)0); | |||||
+ | |||||
if ((flags & FNM_PATHNAME) && c == L('/')) | |||||
/* [/] can never match when matching a pathname. */ | |||||
return (CHAR *)0; | |||||
Index: bash-4.4/patchlevel.h | |||||
=================================================================== | |||||
--- bash-4.4.orig/patchlevel.h | |||||
+++ bash-4.4/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 2 | |||||
+#define PATCHLEVEL 3 | |||||
#endif /* _PATCHLEVEL_H_ */ |
@ -1,66 +0,0 @@ | |||||
Index: bash-4.4/jobs.c | |||||
=================================================================== | |||||
--- bash-4.4.orig/jobs.c | |||||
+++ bash-4.4/jobs.c | |||||
@@ -453,6 +453,21 @@ cleanup_the_pipeline () | |||||
discard_pipeline (disposer); | |||||
} | |||||
+void | |||||
+discard_last_procsub_child () | |||||
+{ | |||||
+ PROCESS *disposer; | |||||
+ sigset_t set, oset; | |||||
+ | |||||
+ BLOCK_CHILD (set, oset); | |||||
+ disposer = last_procsub_child; | |||||
+ last_procsub_child = (PROCESS *)NULL; | |||||
+ UNBLOCK_CHILD (oset); | |||||
+ | |||||
+ if (disposer) | |||||
+ discard_pipeline (disposer); | |||||
+} | |||||
+ | |||||
struct pipeline_saver * | |||||
alloc_pipeline_saver () | |||||
{ | |||||
Index: bash-4.4/jobs.h | |||||
=================================================================== | |||||
--- bash-4.4.orig/jobs.h | |||||
+++ bash-4.4/jobs.h | |||||
@@ -190,6 +190,7 @@ extern JOB **jobs; | |||||
extern void making_children __P((void)); | |||||
extern void stop_making_children __P((void)); | |||||
extern void cleanup_the_pipeline __P((void)); | |||||
+extern void discard_last_procsub_child __P((void)); | |||||
extern void save_pipeline __P((int)); | |||||
extern PROCESS *restore_pipeline __P((int)); | |||||
extern void start_pipeline __P((void)); | |||||
Index: bash-4.4/patchlevel.h | |||||
=================================================================== | |||||
--- bash-4.4.orig/patchlevel.h | |||||
+++ bash-4.4/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 3 | |||||
+#define PATCHLEVEL 4 | |||||
#endif /* _PATCHLEVEL_H_ */ | |||||
Index: bash-4.4/subst.c | |||||
=================================================================== | |||||
--- bash-4.4.orig/subst.c | |||||
+++ bash-4.4/subst.c | |||||
@@ -5808,10 +5808,7 @@ process_substitute (string, open_for_rea | |||||
{ | |||||
#if defined (JOB_CONTROL) | |||||
if (last_procsub_child) | |||||
- { | |||||
- discard_pipeline (last_procsub_child); | |||||
- last_procsub_child = (PROCESS *)NULL; | |||||
- } | |||||
+ discard_last_procsub_child (); | |||||
last_procsub_child = restore_pipeline (0); | |||||
#endif | |||||
@ -1,29 +0,0 @@ | |||||
Index: bash-4.4/builtins/evalstring.c | |||||
=================================================================== | |||||
--- bash-4.4.orig/builtins/evalstring.c | |||||
+++ bash-4.4/builtins/evalstring.c | |||||
@@ -104,12 +104,9 @@ should_suppress_fork (command) | |||||
running_trap == 0 && | |||||
*bash_input.location.string == '\0' && | |||||
command->type == cm_simple && | |||||
-#if 0 | |||||
signal_is_trapped (EXIT_TRAP) == 0 && | |||||
signal_is_trapped (ERROR_TRAP) == 0 && | |||||
-#else | |||||
any_signals_trapped () < 0 && | |||||
-#endif | |||||
command->redirects == 0 && command->value.Simple->redirects == 0 && | |||||
((command->flags & CMD_TIME_PIPELINE) == 0) && | |||||
((command->flags & CMD_INVERT_RETURN) == 0)); | |||||
Index: bash-4.4/patchlevel.h | |||||
=================================================================== | |||||
--- bash-4.4.orig/patchlevel.h | |||||
+++ bash-4.4/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 4 | |||||
+#define PATCHLEVEL 5 | |||||
#endif /* _PATCHLEVEL_H_ */ |
@ -1,37 +0,0 @@ | |||||
Index: bash-4.4/builtins/pushd.def | |||||
=================================================================== | |||||
--- bash-4.4.orig/builtins/pushd.def | |||||
+++ bash-4.4/builtins/pushd.def | |||||
@@ -365,7 +365,7 @@ popd_builtin (list) | |||||
break; | |||||
} | |||||
- if (which > directory_list_offset || (directory_list_offset == 0 && which == 0)) | |||||
+ if (which > directory_list_offset || (which < -directory_list_offset) || (directory_list_offset == 0 && which == 0)) | |||||
{ | |||||
pushd_error (directory_list_offset, which_word ? which_word : ""); | |||||
return (EXECUTION_FAILURE); | |||||
@@ -387,6 +387,11 @@ popd_builtin (list) | |||||
remove that directory from the list and shift the remainder | |||||
of the list into place. */ | |||||
i = (direction == '+') ? directory_list_offset - which : which; | |||||
+ if (i < 0 || i > directory_list_offset) | |||||
+ { | |||||
+ pushd_error (directory_list_offset, which_word ? which_word : ""); | |||||
+ return (EXECUTION_FAILURE); | |||||
+ } | |||||
free (pushd_directory_list[i]); | |||||
directory_list_offset--; | |||||
Index: bash-4.4/patchlevel.h | |||||
=================================================================== | |||||
--- bash-4.4.orig/patchlevel.h | |||||
+++ bash-4.4/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 5 | |||||
+#define PATCHLEVEL 6 | |||||
#endif /* _PATCHLEVEL_H_ */ |
@ -1,100 +0,0 @@ | |||||
Index: bash-4.4/bashline.c | |||||
=================================================================== | |||||
--- bash-4.4.orig/bashline.c | |||||
+++ bash-4.4/bashline.c | |||||
@@ -142,7 +142,7 @@ static int executable_completion __P((co | |||||
static rl_icppfunc_t *save_directory_hook __P((void)); | |||||
static void restore_directory_hook __P((rl_icppfunc_t)); | |||||
-static int directory_exists __P((const char *)); | |||||
+static int directory_exists __P((const char *, int)); | |||||
static void cleanup_expansion_error __P((void)); | |||||
static void maybe_make_readline_line __P((char *)); | |||||
@@ -3102,18 +3102,20 @@ restore_directory_hook (hookf) | |||||
rl_directory_rewrite_hook = hookf; | |||||
} | |||||
-/* Check whether not the (dequoted) version of DIRNAME, with any trailing slash | |||||
- removed, exists. */ | |||||
+/* Check whether not DIRNAME, with any trailing slash removed, exists. If | |||||
+ SHOULD_DEQUOTE is non-zero, we dequote the directory name first. */ | |||||
static int | |||||
-directory_exists (dirname) | |||||
+directory_exists (dirname, should_dequote) | |||||
const char *dirname; | |||||
+ int should_dequote; | |||||
{ | |||||
char *new_dirname; | |||||
int dirlen, r; | |||||
struct stat sb; | |||||
- /* First, dequote the directory name */ | |||||
- new_dirname = bash_dequote_filename ((char *)dirname, rl_completion_quote_character); | |||||
+ /* We save the string and chop the trailing slash because stat/lstat behave | |||||
+ inconsistently if one is present. */ | |||||
+ new_dirname = should_dequote ? bash_dequote_filename ((char *)dirname, rl_completion_quote_character) : savestring (dirname); | |||||
dirlen = STRLEN (new_dirname); | |||||
if (new_dirname[dirlen - 1] == '/') | |||||
new_dirname[dirlen - 1] = '\0'; | |||||
@@ -3145,7 +3147,7 @@ bash_filename_stat_hook (dirname) | |||||
else if (t = mbschr (local_dirname, '`')) /* XXX */ | |||||
should_expand_dirname = '`'; | |||||
- if (should_expand_dirname && directory_exists (local_dirname)) | |||||
+ if (should_expand_dirname && directory_exists (local_dirname, 0)) | |||||
should_expand_dirname = 0; | |||||
if (should_expand_dirname) | |||||
@@ -3155,7 +3157,7 @@ bash_filename_stat_hook (dirname) | |||||
have to worry about restoring this setting. */ | |||||
global_nounset = unbound_vars_is_error; | |||||
unbound_vars_is_error = 0; | |||||
- wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_COMPLETE); /* does the right thing */ | |||||
+ wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_NOPROCSUB|W_COMPLETE); /* does the right thing */ | |||||
unbound_vars_is_error = global_nounset; | |||||
if (wl) | |||||
{ | |||||
@@ -3244,13 +3246,13 @@ bash_directory_completion_hook (dirname) | |||||
should_expand_dirname = '`'; | |||||
} | |||||
- if (should_expand_dirname && directory_exists (local_dirname)) | |||||
+ if (should_expand_dirname && directory_exists (local_dirname, 1)) | |||||
should_expand_dirname = 0; | |||||
if (should_expand_dirname) | |||||
{ | |||||
new_dirname = savestring (local_dirname); | |||||
- wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_COMPLETE); /* does the right thing */ | |||||
+ wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_NOPROCSUB|W_COMPLETE); /* does the right thing */ | |||||
if (wl) | |||||
{ | |||||
*dirname = string_list (wl); | |||||
Index: bash-4.4/patchlevel.h | |||||
=================================================================== | |||||
--- bash-4.4.orig/patchlevel.h | |||||
+++ bash-4.4/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 6 | |||||
+#define PATCHLEVEL 7 | |||||
#endif /* _PATCHLEVEL_H_ */ | |||||
Index: bash-4.4/subst.c | |||||
=================================================================== | |||||
--- bash-4.4.orig/subst.c | |||||
+++ bash-4.4/subst.c | |||||
@@ -9458,6 +9458,10 @@ add_twochars: | |||||
tword->flags |= word->flags & (W_ASSIGNARG|W_ASSIGNRHS); /* affects $@ */ | |||||
if (word->flags & W_COMPLETE) | |||||
tword->flags |= W_COMPLETE; /* for command substitutions */ | |||||
+ if (word->flags & W_NOCOMSUB) | |||||
+ tword->flags |= W_NOCOMSUB; | |||||
+ if (word->flags & W_NOPROCSUB) | |||||
+ tword->flags |= W_NOPROCSUB; | |||||
temp = (char *)NULL; | |||||
@ -1,58 +0,0 @@ | |||||
Index: bash-4.4/expr.c | |||||
=================================================================== | |||||
--- bash-4.4.orig/expr.c | |||||
+++ bash-4.4/expr.c | |||||
@@ -578,24 +578,23 @@ expcond () | |||||
rval = cval = explor (); | |||||
if (curtok == QUES) /* found conditional expr */ | |||||
{ | |||||
- readtok (); | |||||
- if (curtok == 0 || curtok == COL) | |||||
- evalerror (_("expression expected")); | |||||
if (cval == 0) | |||||
{ | |||||
set_noeval = 1; | |||||
noeval++; | |||||
} | |||||
+ readtok (); | |||||
+ if (curtok == 0 || curtok == COL) | |||||
+ evalerror (_("expression expected")); | |||||
+ | |||||
val1 = EXP_HIGHEST (); | |||||
if (set_noeval) | |||||
noeval--; | |||||
if (curtok != COL) | |||||
evalerror (_("`:' expected for conditional expression")); | |||||
- readtok (); | |||||
- if (curtok == 0) | |||||
- evalerror (_("expression expected")); | |||||
+ | |||||
set_noeval = 0; | |||||
if (cval) | |||||
{ | |||||
@@ -603,7 +602,11 @@ expcond () | |||||
noeval++; | |||||
} | |||||
+ readtok (); | |||||
+ if (curtok == 0) | |||||
+ evalerror (_("expression expected")); | |||||
val2 = expcond (); | |||||
+ | |||||
if (set_noeval) | |||||
noeval--; | |||||
rval = cval ? val1 : val2; | |||||
Index: bash-4.4/patchlevel.h | |||||
=================================================================== | |||||
--- bash-4.4.orig/patchlevel.h | |||||
+++ bash-4.4/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 7 | |||||
+#define PATCHLEVEL 8 | |||||
#endif /* _PATCHLEVEL_H_ */ |
@ -1,67 +0,0 @@ | |||||
Index: bash-4.4/lib/readline/history.c | |||||
=================================================================== | |||||
--- bash-4.4.orig/lib/readline/history.c | |||||
+++ bash-4.4/lib/readline/history.c | |||||
@@ -279,6 +279,7 @@ add_history (string) | |||||
const char *string; | |||||
{ | |||||
HIST_ENTRY *temp; | |||||
+ int new_length; | |||||
if (history_stifled && (history_length == history_max_entries)) | |||||
{ | |||||
@@ -295,13 +296,9 @@ add_history (string) | |||||
/* Copy the rest of the entries, moving down one slot. Copy includes | |||||
trailing NULL. */ | |||||
-#if 0 | |||||
- for (i = 0; i < history_length; i++) | |||||
- the_history[i] = the_history[i + 1]; | |||||
-#else | |||||
memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *)); | |||||
-#endif | |||||
+ new_length = history_length; | |||||
history_base++; | |||||
} | |||||
else | |||||
@@ -315,7 +312,7 @@ add_history (string) | |||||
else | |||||
history_size = DEFAULT_HISTORY_INITIAL_SIZE; | |||||
the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *)); | |||||
- history_length = 1; | |||||
+ new_length = 1; | |||||
} | |||||
else | |||||
{ | |||||
@@ -325,14 +322,15 @@ add_history (string) | |||||
the_history = (HIST_ENTRY **) | |||||
xrealloc (the_history, history_size * sizeof (HIST_ENTRY *)); | |||||
} | |||||
- history_length++; | |||||
+ new_length = history_length + 1; | |||||
} | |||||
} | |||||
temp = alloc_history_entry ((char *)string, hist_inittime ()); | |||||
- the_history[history_length] = (HIST_ENTRY *)NULL; | |||||
- the_history[history_length - 1] = temp; | |||||
+ the_history[new_length] = (HIST_ENTRY *)NULL; | |||||
+ the_history[new_length - 1] = temp; | |||||
+ history_length = new_length; | |||||
} | |||||
/* Change the time stamp of the most recent history entry to STRING. */ | |||||
Index: bash-4.4/patchlevel.h | |||||
=================================================================== | |||||
--- bash-4.4.orig/patchlevel.h | |||||
+++ bash-4.4/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 8 | |||||
+#define PATCHLEVEL 9 | |||||
#endif /* _PATCHLEVEL_H_ */ |
@ -1,26 +0,0 @@ | |||||
Index: bash-4.4/builtins/read.def | |||||
=================================================================== | |||||
--- bash-4.4.orig/builtins/read.def | |||||
+++ bash-4.4/builtins/read.def | |||||
@@ -181,7 +181,8 @@ read_builtin (list) | |||||
WORD_LIST *list; | |||||
{ | |||||
register char *varname; | |||||
- int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2; | |||||
+ int size, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2; | |||||
+ volatile int i; | |||||
int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul; | |||||
int raw, edit, nchars, silent, have_timeout, ignore_delim, fd, lastsig, t_errno; | |||||
unsigned int tmsec, tmusec; | |||||
Index: bash-4.4/patchlevel.h | |||||
=================================================================== | |||||
--- bash-4.4.orig/patchlevel.h | |||||
+++ bash-4.4/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 9 | |||||
+#define PATCHLEVEL 10 | |||||
#endif /* _PATCHLEVEL_H_ */ |
@ -1,26 +0,0 @@ | |||||
Index: bash-4.4/patchlevel.h | |||||
=================================================================== | |||||
--- bash-4.4.orig/patchlevel.h | |||||
+++ bash-4.4/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 10 | |||||
+#define PATCHLEVEL 11 | |||||
#endif /* _PATCHLEVEL_H_ */ | |||||
Index: bash-4.4/sig.c | |||||
=================================================================== | |||||
--- bash-4.4.orig/sig.c | |||||
+++ bash-4.4/sig.c | |||||
@@ -585,7 +585,8 @@ termsig_handler (sig) | |||||
#if defined (JOB_CONTROL) | |||||
if (sig == SIGHUP && (interactive || (subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB)))) | |||||
hangup_all_jobs (); | |||||
- end_job_control (); | |||||
+ if ((subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB)) == 0) | |||||
+ end_job_control (); | |||||
#endif /* JOB_CONTROL */ | |||||
#if defined (PROCESS_SUBSTITUTION) |
@ -1,106 +0,0 @@ | |||||
Index: bash-4.4/patchlevel.h | |||||
=================================================================== | |||||
--- bash-4.4.orig/patchlevel.h | |||||
+++ bash-4.4/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 11 | |||||
+#define PATCHLEVEL 12 | |||||
#endif /* _PATCHLEVEL_H_ */ | |||||
Index: bash-4.4/subst.c | |||||
=================================================================== | |||||
--- bash-4.4.orig/subst.c | |||||
+++ bash-4.4/subst.c | |||||
@@ -2825,11 +2825,15 @@ list_string (string, separators, quoted) | |||||
/* Parse a single word from STRING, using SEPARATORS to separate fields. | |||||
ENDPTR is set to the first character after the word. This is used by | |||||
- the `read' builtin. This is never called with SEPARATORS != $IFS; | |||||
- it should be simplified. | |||||
+ the `read' builtin. | |||||
+ | |||||
+ This is never called with SEPARATORS != $IFS, and takes advantage of that. | |||||
XXX - this function is very similar to list_string; they should be | |||||
combined - XXX */ | |||||
+ | |||||
+#define islocalsep(c) (local_cmap[(unsigned char)(c)] != 0) | |||||
+ | |||||
char * | |||||
get_word_from_string (stringp, separators, endptr) | |||||
char **stringp, *separators, **endptr; | |||||
@@ -2837,6 +2841,7 @@ get_word_from_string (stringp, separator | |||||
register char *s; | |||||
char *current_word; | |||||
int sindex, sh_style_split, whitesep, xflags; | |||||
+ unsigned char local_cmap[UCHAR_MAX+1]; /* really only need single-byte chars here */ | |||||
size_t slen; | |||||
if (!stringp || !*stringp || !**stringp) | |||||
@@ -2846,20 +2851,23 @@ get_word_from_string (stringp, separator | |||||
separators[1] == '\t' && | |||||
separators[2] == '\n' && | |||||
separators[3] == '\0'; | |||||
- for (xflags = 0, s = ifs_value; s && *s; s++) | |||||
+ memset (local_cmap, '\0', sizeof (local_cmap)); | |||||
+ for (xflags = 0, s = separators; s && *s; s++) | |||||
{ | |||||
if (*s == CTLESC) xflags |= SX_NOCTLESC; | |||||
if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL; | |||||
+ local_cmap[(unsigned char)*s] = 1; /* local charmap of separators */ | |||||
} | |||||
s = *stringp; | |||||
slen = 0; | |||||
/* Remove sequences of whitespace at the beginning of STRING, as | |||||
- long as those characters appear in IFS. */ | |||||
- if (sh_style_split || !separators || !*separators) | |||||
+ long as those characters appear in SEPARATORS. This happens if | |||||
+ SEPARATORS == $' \t\n' or if IFS is unset. */ | |||||
+ if (sh_style_split || separators == 0) | |||||
{ | |||||
- for (; *s && spctabnl (*s) && isifs (*s); s++); | |||||
+ for (; *s && spctabnl (*s) && islocalsep (*s); s++); | |||||
/* If the string is nothing but whitespace, update it and return. */ | |||||
if (!*s) | |||||
@@ -2878,9 +2886,9 @@ get_word_from_string (stringp, separator | |||||
This obeys the field splitting rules in Posix.2. */ | |||||
sindex = 0; | |||||
- /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim | |||||
- unless multibyte chars are possible. */ | |||||
- slen = (MB_CUR_MAX > 1) ? STRLEN (s) : 1; | |||||
+ /* Don't need string length in ADVANCE_CHAR unless multibyte chars are | |||||
+ possible, but need it in string_extract_verbatim for bounds checking */ | |||||
+ slen = STRLEN (s); | |||||
current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags); | |||||
/* Set ENDPTR to the first character after the end of the word. */ | |||||
@@ -2899,19 +2907,19 @@ get_word_from_string (stringp, separator | |||||
/* Now skip sequences of space, tab, or newline characters if they are | |||||
in the list of separators. */ | |||||
- while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex])) | |||||
+ while (s[sindex] && spctabnl (s[sindex]) && islocalsep (s[sindex])) | |||||
sindex++; | |||||
/* If the first separator was IFS whitespace and the current character is | |||||
a non-whitespace IFS character, it should be part of the current field | |||||
delimiter, not a separate delimiter that would result in an empty field. | |||||
Look at POSIX.2, 3.6.5, (3)(b). */ | |||||
- if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex])) | |||||
+ if (s[sindex] && whitesep && islocalsep (s[sindex]) && !spctabnl (s[sindex])) | |||||
{ | |||||
sindex++; | |||||
/* An IFS character that is not IFS white space, along with any adjacent | |||||
IFS white space, shall delimit a field. */ | |||||
- while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex])) | |||||
+ while (s[sindex] && spctabnl (s[sindex]) && islocalsep(s[sindex])) | |||||
sindex++; | |||||
} | |||||