| [ba0a8be] | 1 | Submitted By: William Harrington (kb0iic at cross-lfs dot org)
|
|---|
| 2 | Date: 05-03-2017
|
|---|
| 3 | Initial Package Version: 4.4
|
|---|
| 4 | Origin: Upstream
|
|---|
| 5 | Upstream Status: Applied
|
|---|
| 6 | Description: Contains all upstream patches up to 4.4-012
|
|---|
| 7 |
|
|---|
| 8 | diff -Naur bash-4.4.orig/bashline.c bash-4.4/bashline.c
|
|---|
| 9 | --- bash-4.4.orig/bashline.c 2016-08-06 01:44:05.000000000 +0000
|
|---|
| 10 | +++ bash-4.4/bashline.c 2017-04-13 23:33:07.549107403 +0000
|
|---|
| 11 | @@ -142,7 +142,7 @@
|
|---|
| 12 | static rl_icppfunc_t *save_directory_hook __P((void));
|
|---|
| 13 | static void restore_directory_hook __P((rl_icppfunc_t));
|
|---|
| 14 |
|
|---|
| 15 | -static int directory_exists __P((const char *));
|
|---|
| 16 | +static int directory_exists __P((const char *, int));
|
|---|
| 17 |
|
|---|
| 18 | static void cleanup_expansion_error __P((void));
|
|---|
| 19 | static void maybe_make_readline_line __P((char *));
|
|---|
| 20 | @@ -3102,18 +3102,20 @@
|
|---|
| 21 | rl_directory_rewrite_hook = hookf;
|
|---|
| 22 | }
|
|---|
| 23 |
|
|---|
| 24 | -/* Check whether not the (dequoted) version of DIRNAME, with any trailing slash
|
|---|
| 25 | - removed, exists. */
|
|---|
| 26 | +/* Check whether not DIRNAME, with any trailing slash removed, exists. If
|
|---|
| 27 | + SHOULD_DEQUOTE is non-zero, we dequote the directory name first. */
|
|---|
| 28 | static int
|
|---|
| 29 | -directory_exists (dirname)
|
|---|
| 30 | +directory_exists (dirname, should_dequote)
|
|---|
| 31 | const char *dirname;
|
|---|
| 32 | + int should_dequote;
|
|---|
| 33 | {
|
|---|
| 34 | char *new_dirname;
|
|---|
| 35 | int dirlen, r;
|
|---|
| 36 | struct stat sb;
|
|---|
| 37 |
|
|---|
| 38 | - /* First, dequote the directory name */
|
|---|
| 39 | - new_dirname = bash_dequote_filename ((char *)dirname, rl_completion_quote_character);
|
|---|
| 40 | + /* We save the string and chop the trailing slash because stat/lstat behave
|
|---|
| 41 | + inconsistently if one is present. */
|
|---|
| 42 | + new_dirname = should_dequote ? bash_dequote_filename ((char *)dirname, rl_completion_quote_character) : savestring (dirname);
|
|---|
| 43 | dirlen = STRLEN (new_dirname);
|
|---|
| 44 | if (new_dirname[dirlen - 1] == '/')
|
|---|
| 45 | new_dirname[dirlen - 1] = '\0';
|
|---|
| 46 | @@ -3145,7 +3147,7 @@
|
|---|
| 47 | else if (t = mbschr (local_dirname, '`')) /* XXX */
|
|---|
| 48 | should_expand_dirname = '`';
|
|---|
| 49 |
|
|---|
| 50 | - if (should_expand_dirname && directory_exists (local_dirname))
|
|---|
| 51 | + if (should_expand_dirname && directory_exists (local_dirname, 0))
|
|---|
| 52 | should_expand_dirname = 0;
|
|---|
| 53 |
|
|---|
| 54 | if (should_expand_dirname)
|
|---|
| 55 | @@ -3155,7 +3157,7 @@
|
|---|
| 56 | have to worry about restoring this setting. */
|
|---|
| 57 | global_nounset = unbound_vars_is_error;
|
|---|
| 58 | unbound_vars_is_error = 0;
|
|---|
| 59 | - wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_COMPLETE); /* does the right thing */
|
|---|
| 60 | + wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_NOPROCSUB|W_COMPLETE); /* does the right thing */
|
|---|
| 61 | unbound_vars_is_error = global_nounset;
|
|---|
| 62 | if (wl)
|
|---|
| 63 | {
|
|---|
| 64 | @@ -3244,13 +3246,13 @@
|
|---|
| 65 | should_expand_dirname = '`';
|
|---|
| 66 | }
|
|---|
| 67 |
|
|---|
| 68 | - if (should_expand_dirname && directory_exists (local_dirname))
|
|---|
| 69 | + if (should_expand_dirname && directory_exists (local_dirname, 1))
|
|---|
| 70 | should_expand_dirname = 0;
|
|---|
| 71 |
|
|---|
| 72 | if (should_expand_dirname)
|
|---|
| 73 | {
|
|---|
| 74 | new_dirname = savestring (local_dirname);
|
|---|
| 75 | - wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_COMPLETE); /* does the right thing */
|
|---|
| 76 | + wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_NOPROCSUB|W_COMPLETE); /* does the right thing */
|
|---|
| 77 | if (wl)
|
|---|
| 78 | {
|
|---|
| 79 | *dirname = string_list (wl);
|
|---|
| 80 | diff -Naur bash-4.4.orig/builtins/evalstring.c bash-4.4/builtins/evalstring.c
|
|---|
| 81 | --- bash-4.4.orig/builtins/evalstring.c 2016-08-11 18:18:51.000000000 +0000
|
|---|
| 82 | +++ bash-4.4/builtins/evalstring.c 2017-04-13 23:33:07.545107350 +0000
|
|---|
| 83 | @@ -104,12 +104,9 @@
|
|---|
| 84 | running_trap == 0 &&
|
|---|
| 85 | *bash_input.location.string == '\0' &&
|
|---|
| 86 | command->type == cm_simple &&
|
|---|
| 87 | -#if 0
|
|---|
| 88 | signal_is_trapped (EXIT_TRAP) == 0 &&
|
|---|
| 89 | signal_is_trapped (ERROR_TRAP) == 0 &&
|
|---|
| 90 | -#else
|
|---|
| 91 | any_signals_trapped () < 0 &&
|
|---|
| 92 | -#endif
|
|---|
| 93 | command->redirects == 0 && command->value.Simple->redirects == 0 &&
|
|---|
| 94 | ((command->flags & CMD_TIME_PIPELINE) == 0) &&
|
|---|
| 95 | ((command->flags & CMD_INVERT_RETURN) == 0));
|
|---|
| 96 | diff -Naur bash-4.4.orig/builtins/pushd.def bash-4.4/builtins/pushd.def
|
|---|
| 97 | --- bash-4.4.orig/builtins/pushd.def 2016-01-25 18:31:49.000000000 +0000
|
|---|
| 98 | +++ bash-4.4/builtins/pushd.def 2017-04-13 23:33:07.546107363 +0000
|
|---|
| 99 | @@ -365,7 +365,7 @@
|
|---|
| 100 | break;
|
|---|
| 101 | }
|
|---|
| 102 |
|
|---|
| 103 | - if (which > directory_list_offset || (directory_list_offset == 0 && which == 0))
|
|---|
| 104 | + if (which > directory_list_offset || (which < -directory_list_offset) || (directory_list_offset == 0 && which == 0))
|
|---|
| 105 | {
|
|---|
| 106 | pushd_error (directory_list_offset, which_word ? which_word : "");
|
|---|
| 107 | return (EXECUTION_FAILURE);
|
|---|
| 108 | @@ -387,6 +387,11 @@
|
|---|
| 109 | remove that directory from the list and shift the remainder
|
|---|
| 110 | of the list into place. */
|
|---|
| 111 | i = (direction == '+') ? directory_list_offset - which : which;
|
|---|
| 112 | + if (i < 0 || i > directory_list_offset)
|
|---|
| 113 | + {
|
|---|
| 114 | + pushd_error (directory_list_offset, which_word ? which_word : "");
|
|---|
| 115 | + return (EXECUTION_FAILURE);
|
|---|
| 116 | + }
|
|---|
| 117 | free (pushd_directory_list[i]);
|
|---|
| 118 | directory_list_offset--;
|
|---|
| 119 |
|
|---|
| 120 | diff -Naur bash-4.4.orig/builtins/read.def bash-4.4/builtins/read.def
|
|---|
| 121 | --- bash-4.4.orig/builtins/read.def 2016-05-16 18:24:56.000000000 +0000
|
|---|
| 122 | +++ bash-4.4/builtins/read.def 2017-04-13 23:33:07.609108202 +0000
|
|---|
| 123 | @@ -181,7 +181,8 @@
|
|---|
| 124 | WORD_LIST *list;
|
|---|
| 125 | {
|
|---|
| 126 | register char *varname;
|
|---|
| 127 | - int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
|
|---|
| 128 | + int size, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
|
|---|
| 129 | + volatile int i;
|
|---|
| 130 | int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
|
|---|
| 131 | int raw, edit, nchars, silent, have_timeout, ignore_delim, fd, lastsig, t_errno;
|
|---|
| 132 | unsigned int tmsec, tmusec;
|
|---|
| 133 | diff -Naur bash-4.4.orig/expr.c bash-4.4/expr.c
|
|---|
| 134 | --- bash-4.4.orig/expr.c 2015-10-11 18:46:36.000000000 +0000
|
|---|
| 135 | +++ bash-4.4/expr.c 2017-04-13 23:33:07.552107443 +0000
|
|---|
| 136 | @@ -578,24 +578,23 @@
|
|---|
| 137 | rval = cval = explor ();
|
|---|
| 138 | if (curtok == QUES) /* found conditional expr */
|
|---|
| 139 | {
|
|---|
| 140 | - readtok ();
|
|---|
| 141 | - if (curtok == 0 || curtok == COL)
|
|---|
| 142 | - evalerror (_("expression expected"));
|
|---|
| 143 | if (cval == 0)
|
|---|
| 144 | {
|
|---|
| 145 | set_noeval = 1;
|
|---|
| 146 | noeval++;
|
|---|
| 147 | }
|
|---|
| 148 |
|
|---|
| 149 | + readtok ();
|
|---|
| 150 | + if (curtok == 0 || curtok == COL)
|
|---|
| 151 | + evalerror (_("expression expected"));
|
|---|
| 152 | +
|
|---|
| 153 | val1 = EXP_HIGHEST ();
|
|---|
| 154 |
|
|---|
| 155 | if (set_noeval)
|
|---|
| 156 | noeval--;
|
|---|
| 157 | if (curtok != COL)
|
|---|
| 158 | evalerror (_("`:' expected for conditional expression"));
|
|---|
| 159 | - readtok ();
|
|---|
| 160 | - if (curtok == 0)
|
|---|
| 161 | - evalerror (_("expression expected"));
|
|---|
| 162 | +
|
|---|
| 163 | set_noeval = 0;
|
|---|
| 164 | if (cval)
|
|---|
| 165 | {
|
|---|
| 166 | @@ -603,7 +602,11 @@
|
|---|
| 167 | noeval++;
|
|---|
| 168 | }
|
|---|
| 169 |
|
|---|
| 170 | + readtok ();
|
|---|
| 171 | + if (curtok == 0)
|
|---|
| 172 | + evalerror (_("expression expected"));
|
|---|
| 173 | val2 = expcond ();
|
|---|
| 174 | +
|
|---|
| 175 | if (set_noeval)
|
|---|
| 176 | noeval--;
|
|---|
| 177 | rval = cval ? val1 : val2;
|
|---|
| 178 | diff -Naur bash-4.4.orig/jobs.c bash-4.4/jobs.c
|
|---|
| 179 | --- bash-4.4.orig/jobs.c 2016-08-23 20:38:44.000000000 +0000
|
|---|
| 180 | +++ bash-4.4/jobs.c 2017-04-13 23:33:07.542107310 +0000
|
|---|
| 181 | @@ -453,6 +453,21 @@
|
|---|
| 182 | discard_pipeline (disposer);
|
|---|
| 183 | }
|
|---|
| 184 |
|
|---|
| 185 | +void
|
|---|
| 186 | +discard_last_procsub_child ()
|
|---|
| 187 | +{
|
|---|
| 188 | + PROCESS *disposer;
|
|---|
| 189 | + sigset_t set, oset;
|
|---|
| 190 | +
|
|---|
| 191 | + BLOCK_CHILD (set, oset);
|
|---|
| 192 | + disposer = last_procsub_child;
|
|---|
| 193 | + last_procsub_child = (PROCESS *)NULL;
|
|---|
| 194 | + UNBLOCK_CHILD (oset);
|
|---|
| 195 | +
|
|---|
| 196 | + if (disposer)
|
|---|
| 197 | + discard_pipeline (disposer);
|
|---|
| 198 | +}
|
|---|
| 199 | +
|
|---|
| 200 | struct pipeline_saver *
|
|---|
| 201 | alloc_pipeline_saver ()
|
|---|
| 202 | {
|
|---|
| 203 | diff -Naur bash-4.4.orig/jobs.h bash-4.4/jobs.h
|
|---|
| 204 | --- bash-4.4.orig/jobs.h 2016-04-27 14:35:51.000000000 +0000
|
|---|
| 205 | +++ bash-4.4/jobs.h 2017-04-13 23:33:07.542107310 +0000
|
|---|
| 206 | @@ -190,6 +190,7 @@
|
|---|
| 207 | extern void making_children __P((void));
|
|---|
| 208 | extern void stop_making_children __P((void));
|
|---|
| 209 | extern void cleanup_the_pipeline __P((void));
|
|---|
| 210 | +extern void discard_last_procsub_child __P((void));
|
|---|
| 211 | extern void save_pipeline __P((int));
|
|---|
| 212 | extern PROCESS *restore_pipeline __P((int));
|
|---|
| 213 | extern void start_pipeline __P((void));
|
|---|
| 214 | diff -Naur bash-4.4.orig/lib/glob/sm_loop.c bash-4.4/lib/glob/sm_loop.c
|
|---|
| 215 | --- bash-4.4.orig/lib/glob/sm_loop.c 2016-04-10 15:23:21.000000000 +0000
|
|---|
| 216 | +++ bash-4.4/lib/glob/sm_loop.c 2017-04-13 23:33:07.540107283 +0000
|
|---|
| 217 | @@ -330,6 +330,12 @@
|
|---|
| 218 | for (pc = 0; p[pc]; pc++)
|
|---|
| 219 | if (p[pc] == L('.') && p[pc+1] == L(']'))
|
|---|
| 220 | break;
|
|---|
| 221 | + if (p[pc] == 0)
|
|---|
| 222 | + {
|
|---|
| 223 | + if (vp)
|
|---|
| 224 | + *vp = INVALID;
|
|---|
| 225 | + return (p + pc);
|
|---|
| 226 | + }
|
|---|
| 227 | val = COLLSYM (p, pc);
|
|---|
| 228 | if (vp)
|
|---|
| 229 | *vp = val;
|
|---|
| 230 | @@ -483,6 +489,9 @@
|
|---|
| 231 | c = *p++;
|
|---|
| 232 | c = FOLD (c);
|
|---|
| 233 |
|
|---|
| 234 | + if (c == L('\0'))
|
|---|
| 235 | + return ((test == L('[')) ? savep : (CHAR *)0);
|
|---|
| 236 | +
|
|---|
| 237 | if ((flags & FNM_PATHNAME) && c == L('/'))
|
|---|
| 238 | /* [/] can never match when matching a pathname. */
|
|---|
| 239 | return (CHAR *)0;
|
|---|
| 240 | diff -Naur bash-4.4.orig/lib/readline/history.c bash-4.4/lib/readline/history.c
|
|---|
| 241 | --- bash-4.4.orig/lib/readline/history.c 2015-12-28 18:50:31.000000000 +0000
|
|---|
| 242 | +++ bash-4.4/lib/readline/history.c 2017-04-13 23:33:07.607108175 +0000
|
|---|
| 243 | @@ -57,6 +57,8 @@
|
|---|
| 244 | /* How big to make the_history when we first allocate it. */
|
|---|
| 245 | #define DEFAULT_HISTORY_INITIAL_SIZE 502
|
|---|
| 246 |
|
|---|
| 247 | +#define MAX_HISTORY_INITIAL_SIZE 8192
|
|---|
| 248 | +
|
|---|
| 249 | /* The number of slots to increase the_history by. */
|
|---|
| 250 | #define DEFAULT_HISTORY_GROW_SIZE 50
|
|---|
| 251 |
|
|---|
| 252 | @@ -277,6 +279,7 @@
|
|---|
| 253 | const char *string;
|
|---|
| 254 | {
|
|---|
| 255 | HIST_ENTRY *temp;
|
|---|
| 256 | + int new_length;
|
|---|
| 257 |
|
|---|
| 258 | if (history_stifled && (history_length == history_max_entries))
|
|---|
| 259 | {
|
|---|
| 260 | @@ -293,13 +296,9 @@
|
|---|
| 261 |
|
|---|
| 262 | /* Copy the rest of the entries, moving down one slot. Copy includes
|
|---|
| 263 | trailing NULL. */
|
|---|
| 264 | -#if 0
|
|---|
| 265 | - for (i = 0; i < history_length; i++)
|
|---|
| 266 | - the_history[i] = the_history[i + 1];
|
|---|
| 267 | -#else
|
|---|
| 268 | memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *));
|
|---|
| 269 | -#endif
|
|---|
| 270 |
|
|---|
| 271 | + new_length = history_length;
|
|---|
| 272 | history_base++;
|
|---|
| 273 | }
|
|---|
| 274 | else
|
|---|
| 275 | @@ -307,11 +306,13 @@
|
|---|
| 276 | if (history_size == 0)
|
|---|
| 277 | {
|
|---|
| 278 | if (history_stifled && history_max_entries > 0)
|
|---|
| 279 | - history_size = history_max_entries + 2;
|
|---|
| 280 | + history_size = (history_max_entries > MAX_HISTORY_INITIAL_SIZE)
|
|---|
| 281 | + ? MAX_HISTORY_INITIAL_SIZE
|
|---|
| 282 | + : history_max_entries + 2;
|
|---|
| 283 | else
|
|---|
| 284 | history_size = DEFAULT_HISTORY_INITIAL_SIZE;
|
|---|
| 285 | the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
|
|---|
| 286 | - history_length = 1;
|
|---|
| 287 | + new_length = 1;
|
|---|
| 288 | }
|
|---|
| 289 | else
|
|---|
| 290 | {
|
|---|
| 291 | @@ -321,14 +322,15 @@
|
|---|
| 292 | the_history = (HIST_ENTRY **)
|
|---|
| 293 | xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
|
|---|
| 294 | }
|
|---|
| 295 | - history_length++;
|
|---|
| 296 | + new_length = history_length + 1;
|
|---|
| 297 | }
|
|---|
| 298 | }
|
|---|
| 299 |
|
|---|
| 300 | temp = alloc_history_entry ((char *)string, hist_inittime ());
|
|---|
| 301 |
|
|---|
| 302 | - the_history[history_length] = (HIST_ENTRY *)NULL;
|
|---|
| 303 | - the_history[history_length - 1] = temp;
|
|---|
| 304 | + the_history[new_length] = (HIST_ENTRY *)NULL;
|
|---|
| 305 | + the_history[new_length - 1] = temp;
|
|---|
| 306 | + history_length = new_length;
|
|---|
| 307 | }
|
|---|
| 308 |
|
|---|
| 309 | /* Change the time stamp of the most recent history entry to STRING. */
|
|---|
| 310 | diff -Naur bash-4.4.orig/patchlevel.h bash-4.4/patchlevel.h
|
|---|
| 311 | --- bash-4.4.orig/patchlevel.h 2016-06-22 18:51:03.000000000 +0000
|
|---|
| 312 | +++ bash-4.4/patchlevel.h 2017-04-13 23:33:07.612108242 +0000
|
|---|
| 313 | @@ -25,6 +25,6 @@
|
|---|
| 314 | regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
|---|
| 315 | looks for to find the patch level (for the sccs version string). */
|
|---|
| 316 |
|
|---|
| 317 | -#define PATCHLEVEL 0
|
|---|
| 318 | +#define PATCHLEVEL 12
|
|---|
| 319 |
|
|---|
| 320 | #endif /* _PATCHLEVEL_H_ */
|
|---|
| 321 | diff -Naur bash-4.4.orig/sig.c bash-4.4/sig.c
|
|---|
| 322 | --- bash-4.4.orig/sig.c 2016-02-11 20:02:45.000000000 +0000
|
|---|
| 323 | +++ bash-4.4/sig.c 2017-04-13 23:33:07.609108202 +0000
|
|---|
| 324 | @@ -585,7 +585,8 @@
|
|---|
| 325 | #if defined (JOB_CONTROL)
|
|---|
| 326 | if (sig == SIGHUP && (interactive || (subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB))))
|
|---|
| 327 | hangup_all_jobs ();
|
|---|
| 328 | - end_job_control ();
|
|---|
| 329 | + if ((subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB)) == 0)
|
|---|
| 330 | + end_job_control ();
|
|---|
| 331 | #endif /* JOB_CONTROL */
|
|---|
| 332 |
|
|---|
| 333 | #if defined (PROCESS_SUBSTITUTION)
|
|---|
| 334 | diff -Naur bash-4.4.orig/subst.c bash-4.4/subst.c
|
|---|
| 335 | --- bash-4.4.orig/subst.c 2016-08-30 20:46:38.000000000 +0000
|
|---|
| 336 | +++ bash-4.4/subst.c 2017-04-13 23:33:07.612108242 +0000
|
|---|
| 337 | @@ -2825,11 +2825,15 @@
|
|---|
| 338 |
|
|---|
| 339 | /* Parse a single word from STRING, using SEPARATORS to separate fields.
|
|---|
| 340 | ENDPTR is set to the first character after the word. This is used by
|
|---|
| 341 | - the `read' builtin. This is never called with SEPARATORS != $IFS;
|
|---|
| 342 | - it should be simplified.
|
|---|
| 343 | + the `read' builtin.
|
|---|
| 344 | +
|
|---|
| 345 | + This is never called with SEPARATORS != $IFS, and takes advantage of that.
|
|---|
| 346 |
|
|---|
| 347 | XXX - this function is very similar to list_string; they should be
|
|---|
| 348 | combined - XXX */
|
|---|
| 349 | +
|
|---|
| 350 | +#define islocalsep(c) (local_cmap[(unsigned char)(c)] != 0)
|
|---|
| 351 | +
|
|---|
| 352 | char *
|
|---|
| 353 | get_word_from_string (stringp, separators, endptr)
|
|---|
| 354 | char **stringp, *separators, **endptr;
|
|---|
| 355 | @@ -2837,6 +2841,7 @@
|
|---|
| 356 | register char *s;
|
|---|
| 357 | char *current_word;
|
|---|
| 358 | int sindex, sh_style_split, whitesep, xflags;
|
|---|
| 359 | + unsigned char local_cmap[UCHAR_MAX+1]; /* really only need single-byte chars here */
|
|---|
| 360 | size_t slen;
|
|---|
| 361 |
|
|---|
| 362 | if (!stringp || !*stringp || !**stringp)
|
|---|
| 363 | @@ -2846,20 +2851,23 @@
|
|---|
| 364 | separators[1] == '\t' &&
|
|---|
| 365 | separators[2] == '\n' &&
|
|---|
| 366 | separators[3] == '\0';
|
|---|
| 367 | - for (xflags = 0, s = ifs_value; s && *s; s++)
|
|---|
| 368 | + memset (local_cmap, '\0', sizeof (local_cmap));
|
|---|
| 369 | + for (xflags = 0, s = separators; s && *s; s++)
|
|---|
| 370 | {
|
|---|
| 371 | if (*s == CTLESC) xflags |= SX_NOCTLESC;
|
|---|
| 372 | if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
|
|---|
| 373 | + local_cmap[(unsigned char)*s] = 1; /* local charmap of separators */
|
|---|
| 374 | }
|
|---|
| 375 |
|
|---|
| 376 | s = *stringp;
|
|---|
| 377 | slen = 0;
|
|---|
| 378 |
|
|---|
| 379 | /* Remove sequences of whitespace at the beginning of STRING, as
|
|---|
| 380 | - long as those characters appear in IFS. */
|
|---|
| 381 | - if (sh_style_split || !separators || !*separators)
|
|---|
| 382 | + long as those characters appear in SEPARATORS. This happens if
|
|---|
| 383 | + SEPARATORS == $' \t\n' or if IFS is unset. */
|
|---|
| 384 | + if (sh_style_split || separators == 0)
|
|---|
| 385 | {
|
|---|
| 386 | - for (; *s && spctabnl (*s) && isifs (*s); s++);
|
|---|
| 387 | + for (; *s && spctabnl (*s) && islocalsep (*s); s++);
|
|---|
| 388 |
|
|---|
| 389 | /* If the string is nothing but whitespace, update it and return. */
|
|---|
| 390 | if (!*s)
|
|---|
| 391 | @@ -2878,9 +2886,9 @@
|
|---|
| 392 |
|
|---|
| 393 | This obeys the field splitting rules in Posix.2. */
|
|---|
| 394 | sindex = 0;
|
|---|
| 395 | - /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
|
|---|
| 396 | - unless multibyte chars are possible. */
|
|---|
| 397 | - slen = (MB_CUR_MAX > 1) ? STRLEN (s) : 1;
|
|---|
| 398 | + /* Don't need string length in ADVANCE_CHAR unless multibyte chars are
|
|---|
| 399 | + possible, but need it in string_extract_verbatim for bounds checking */
|
|---|
| 400 | + slen = STRLEN (s);
|
|---|
| 401 | current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags);
|
|---|
| 402 |
|
|---|
| 403 | /* Set ENDPTR to the first character after the end of the word. */
|
|---|
| 404 | @@ -2899,19 +2907,19 @@
|
|---|
| 405 |
|
|---|
| 406 | /* Now skip sequences of space, tab, or newline characters if they are
|
|---|
| 407 | in the list of separators. */
|
|---|
| 408 | - while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
|
|---|
| 409 | + while (s[sindex] && spctabnl (s[sindex]) && islocalsep (s[sindex]))
|
|---|
| 410 | sindex++;
|
|---|
| 411 |
|
|---|
| 412 | /* If the first separator was IFS whitespace and the current character is
|
|---|
| 413 | a non-whitespace IFS character, it should be part of the current field
|
|---|
| 414 | delimiter, not a separate delimiter that would result in an empty field.
|
|---|
| 415 | Look at POSIX.2, 3.6.5, (3)(b). */
|
|---|
| 416 | - if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
|
|---|
| 417 | + if (s[sindex] && whitesep && islocalsep (s[sindex]) && !spctabnl (s[sindex]))
|
|---|
| 418 | {
|
|---|
| 419 | sindex++;
|
|---|
| 420 | /* An IFS character that is not IFS white space, along with any adjacent
|
|---|
| 421 | IFS white space, shall delimit a field. */
|
|---|
| 422 | - while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
|
|---|
| 423 | + while (s[sindex] && spctabnl (s[sindex]) && islocalsep(s[sindex]))
|
|---|
| 424 | sindex++;
|
|---|
| 425 | }
|
|---|
| 426 |
|
|---|
| 427 | @@ -5808,10 +5816,7 @@
|
|---|
| 428 | {
|
|---|
| 429 | #if defined (JOB_CONTROL)
|
|---|
| 430 | if (last_procsub_child)
|
|---|
| 431 | - {
|
|---|
| 432 | - discard_pipeline (last_procsub_child);
|
|---|
| 433 | - last_procsub_child = (PROCESS *)NULL;
|
|---|
| 434 | - }
|
|---|
| 435 | + discard_last_procsub_child ();
|
|---|
| 436 | last_procsub_child = restore_pipeline (0);
|
|---|
| 437 | #endif
|
|---|
| 438 |
|
|---|
| 439 | @@ -5931,6 +5936,7 @@
|
|---|
| 440 | char *istring, buf[128], *bufp, *s;
|
|---|
| 441 | int istring_index, istring_size, c, tflag, skip_ctlesc, skip_ctlnul;
|
|---|
| 442 | ssize_t bufn;
|
|---|
| 443 | + int nullbyte;
|
|---|
| 444 |
|
|---|
| 445 | istring = (char *)NULL;
|
|---|
| 446 | istring_index = istring_size = bufn = tflag = 0;
|
|---|
| 447 | @@ -5938,6 +5944,8 @@
|
|---|
| 448 | for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
|
|---|
| 449 | skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
|
|---|
| 450 |
|
|---|
| 451 | + nullbyte = 0;
|
|---|
| 452 | +
|
|---|
| 453 | /* Read the output of the command through the pipe. This may need to be
|
|---|
| 454 | changed to understand multibyte characters in the future. */
|
|---|
| 455 | while (1)
|
|---|
| 456 | @@ -5956,7 +5964,11 @@
|
|---|
| 457 | if (c == 0)
|
|---|
| 458 | {
|
|---|
| 459 | #if 1
|
|---|
| 460 | - internal_warning ("%s", _("command substitution: ignored null byte in input"));
|
|---|
| 461 | + if (nullbyte == 0)
|
|---|
| 462 | + {
|
|---|
| 463 | + internal_warning ("%s", _("command substitution: ignored null byte in input"));
|
|---|
| 464 | + nullbyte = 1;
|
|---|
| 465 | + }
|
|---|
| 466 | #endif
|
|---|
| 467 | continue;
|
|---|
| 468 | }
|
|---|
| 469 | @@ -9454,6 +9466,10 @@
|
|---|
| 470 | tword->flags |= word->flags & (W_ASSIGNARG|W_ASSIGNRHS); /* affects $@ */
|
|---|
| 471 | if (word->flags & W_COMPLETE)
|
|---|
| 472 | tword->flags |= W_COMPLETE; /* for command substitutions */
|
|---|
| 473 | + if (word->flags & W_NOCOMSUB)
|
|---|
| 474 | + tword->flags |= W_NOCOMSUB;
|
|---|
| 475 | + if (word->flags & W_NOPROCSUB)
|
|---|
| 476 | + tword->flags |= W_NOPROCSUB;
|
|---|
| 477 |
|
|---|
| 478 | temp = (char *)NULL;
|
|---|
| 479 |
|
|---|