From: Chet Ramey Date: Thu, 1 Aug 2019 20:00:56 +0000 (-0400) Subject: commit bash-20190731 snapshot X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1679cff94f916917472abe3d3a42c0c52d87238b;p=thirdparty%2Fbash.git commit bash-20190731 snapshot --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index f8cbc518b..5fc3f13da 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -6390,3 +6390,61 @@ lib/glob/sm_loop.c builtins/colon.def - add the right includes so colon_builtin and false_builtin can take a WORD_LIST * argument like the prototype says they do + + 7/29 + ---- +lib/readline/kill.c + - _rl_read_bracketed_paste_prefix: read the character prefix that + indicates a pasted string in bracketed paste mode. If we don't + read a valid bracketed paste prefix, push the other characters + back onto the input stack with _rl_unget_char + - _rl_bracketed_read_key: handle reading pasted input when bracketed + paste mode is enabled, including reading multibyte characters; push + anything beyond a single byte back onto the input stack where it + can be read by _rl_read_mbstring or subsequent input + - _rl_bracketed_read_mbstring: handle reading pasted input in bracketed + paste mode, using _rl_bracketed_read_key to get the pasted text, + then call _rl_read_mbstring to get the rest of any multibyte char + + +lib/readline/vi_mode.c + - _rl_vi_callback_getchar: call _rl_bracketed_read_mbstring to handle + bracketed paste mode input. Fixes issue with vi-change-char reported + by + - rl_vi_domove_getchar: just call _rl_bracketed_read_key and return + the result -- we're not interested in multibyte-character input here + yet + - rl_vi_replace: bind BRACK_PASTE_PREF key sequence if bracketed paste + mode has been enabled + - _rl_overstrike_bracketed_paste: key binding function for the bracketed + paste prefix key sequence in overwrite mode; reads the pasted text + and uses rl_vi_overstrike to add each character in overwrite mode. + Fixes issue reported by + + 7/31 + ---- +lib/readline/input.c + - _rl_read_mbchar: the first time through the loop (mb_len == 0), call + _rl_bracketed_read_key to process any bracketed paste characters + +lib/readline/text.c + - _rl_char_search: use _rl_bracketed_read_key in the non-multibyte + character case + +lib/readline/misc.c + - _rl_arg_dispatch: use _rl_bracketed_read_key in place of rl_read_key + +subst.c + - list_string: if string_extract_verbatim returns something, just make + a WORD_DESC * and add current_word directly to it, noting that we + don't want to free current_word (free_word = 0) + - string_extract_verbatim: if the separator string is the empty + string, don't bother with the loop -- just savestring the string, + update *sindex, and return the copy + - read_comsub: make the string we use to save the output from the pipe + 512 bytes instead of 128 (same size as the buffer used to read from + the pipe); fewer calls to xrealloc in the worst case + - parameter_brace_expand_length: optimize the common case (non-dynamic + scalar variable without `set -u' in effect) and just call MB_STRLEN + on the variable value in that case. From a report from + Alkis Georgopoulos diff --git a/aclocal.m4 b/aclocal.m4 index ff8469297..c42dbf3b6 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -10,7 +10,7 @@ AC_DEFUN(BASH_C_LONG_LONG, ac_cv_c_long_long=yes else AC_TRY_RUN([ -#include "bashansi.h" +#include int main() { @@ -34,7 +34,7 @@ AC_DEFUN(BASH_C_LONG_DOUBLE, ac_cv_c_long_double=yes else AC_TRY_RUN([ -#include "bashansi.h" +#include int main() { @@ -138,7 +138,7 @@ typedef int (*_bashfunc)(const char *, ...); #else typedef int (*_bashfunc)(); #endif -#include "bashansi.h" +#include main() { _bashfunc pf; @@ -196,7 +196,7 @@ AC_CACHE_VAL(bash_cv_under_sys_siglist, #ifdef HAVE_UNISTD_H #include #endif -#include "bashansi.h" +#include #ifndef UNDER_SYS_SIGLIST_DECLARED extern char *_sys_siglist[]; #endif @@ -224,7 +224,7 @@ AC_CACHE_VAL(bash_cv_sys_siglist, #ifdef HAVE_UNISTD_H #include #endif -#include "bashansi.h" +#include #if !HAVE_DECL_SYS_SIGLIST extern char *sys_siglist[]; #endif @@ -280,7 +280,7 @@ AC_CACHE_VAL(bash_cv_dup2_broken, [AC_TRY_RUN([ #include #include -#include "bashansi.h" +#include main() { int fd1, fd2, fl; @@ -343,7 +343,7 @@ AC_CACHE_VAL(bash_cv_opendir_not_robust, # include # endif #endif /* HAVE_DIRENT_H */ -#include "bashansi.h" +#include main() { DIR *dir; @@ -523,7 +523,7 @@ AC_TRY_RUN([ #include #include #include -#include "bashansi.h" +#include main() { #ifdef HAVE_QUAD_T @@ -593,7 +593,7 @@ AC_CACHE_VAL(bash_cv_getenv_redef, #ifdef HAVE_UNISTD_H # include #endif -#include "bashansi.h" +#include #ifndef __STDC__ # ifndef const # define const @@ -797,7 +797,7 @@ AC_CACHE_VAL(bash_cv_func_sigsetjmp, #include #include #include -#include "bashansi.h" +#include main() { @@ -893,7 +893,7 @@ AC_CACHE_VAL(bash_cv_printf_a_format, [AC_TRY_RUN([ #include #include -#include "bashansi.h" +#include int main() @@ -1254,7 +1254,7 @@ AC_CACHE_VAL(bash_cv_pgrp_pipe, #ifdef HAVE_UNISTD_H # include #endif -#include "bashansi.h" +#include main() { # ifdef GETPGRP_VOID @@ -1319,7 +1319,7 @@ AC_CACHE_VAL(bash_cv_must_reinstall_sighandlers, #ifdef HAVE_UNISTD_H #include #endif -#include "bashansi.h" +#include typedef RETSIGTYPE sigfunc(); @@ -1433,7 +1433,7 @@ AC_CACHE_VAL(bash_cv_sys_named_pipes, #ifdef HAVE_UNISTD_H #include #endif -#include "bashansi.h" +#include /* Add more tests in here as appropriate. */ main() @@ -1667,7 +1667,7 @@ AC_CACHE_VAL(bash_cv_unusable_rtsigs, [AC_TRY_RUN([ #include #include -#include "bashansi.h" +#include #ifndef NSIG # define NSIG 64 @@ -1851,7 +1851,7 @@ AC_CACHE_VAL(ac_cv_rl_version, [AC_TRY_RUN([ #include #include -#include "bashansi.h" +#include extern int rl_gnu_readline_p; @@ -2056,7 +2056,7 @@ AC_DEFUN([BASH_FUNC_SNPRINTF], AC_CACHE_CHECK([for standard-conformant snprintf], [bash_cv_func_snprintf], [AC_TRY_RUN([ #include -#include "bashansi.h" +#include main() { diff --git a/configure b/configure index 9f8dadf7d..930cba073 100755 --- a/configure +++ b/configure @@ -5392,7 +5392,7 @@ else #include #include -#include "bashansi.h" +#include extern int rl_gnu_readline_p; @@ -16916,7 +16916,7 @@ else #include #include -#include "bashansi.h" +#include main() { int fd1, fd2, fl; @@ -16968,7 +16968,7 @@ else #ifdef HAVE_UNISTD_H # include #endif -#include "bashansi.h" +#include main() { # ifdef GETPGRP_VOID @@ -17182,7 +17182,7 @@ else #ifdef HAVE_UNISTD_H #include #endif -#include "bashansi.h" +#include #if !HAVE_DECL_SYS_SIGLIST extern char *sys_siglist[]; #endif @@ -17264,7 +17264,7 @@ else #ifdef HAVE_UNISTD_H #include #endif -#include "bashansi.h" +#include #ifndef UNDER_SYS_SIGLIST_DECLARED extern char *_sys_siglist[]; #endif @@ -17672,7 +17672,7 @@ else #include #include #include -#include "bashansi.h" +#include main() { #ifdef HAVE_QUAD_T @@ -18586,7 +18586,7 @@ else # include # endif #endif /* HAVE_DIRENT_H */ -#include "bashansi.h" +#include main() { DIR *dir; @@ -18700,7 +18700,7 @@ else #ifdef HAVE_UNISTD_H # include #endif -#include "bashansi.h" +#include #ifndef __STDC__ # ifndef const # define const @@ -18822,7 +18822,7 @@ else #include #include #include -#include "bashansi.h" +#include main() { @@ -18962,7 +18962,7 @@ else /* end confdefs.h. */ #include -#include "bashansi.h" +#include main() { @@ -19202,7 +19202,7 @@ else #include #include -#include "bashansi.h" +#include int main() @@ -19315,7 +19315,7 @@ else #ifdef HAVE_UNISTD_H #include #endif -#include "bashansi.h" +#include typedef RETSIGTYPE sigfunc(); @@ -19467,7 +19467,7 @@ else #ifdef HAVE_UNISTD_H #include #endif -#include "bashansi.h" +#include /* Add more tests in here as appropriate. */ main() @@ -19778,7 +19778,7 @@ else #include #include -#include "bashansi.h" +#include #ifndef NSIG # define NSIG 64 diff --git a/lib/readline/input.c b/lib/readline/input.c index a55733057..0090e97b8 100644 --- a/lib/readline/input.c +++ b/lib/readline/input.c @@ -635,9 +635,7 @@ _rl_read_mbchar (char *mbchar, int size) mb_len = 0; while (mb_len < size) { - RL_SETSTATE(RL_STATE_MOREINPUT); - c = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); + c = (mb_len == 0) ? _rl_bracketed_read_key () : rl_read_key (); if (c < 0) break; diff --git a/lib/readline/isearch.c b/lib/readline/isearch.c index d6c590417..951fce575 100644 --- a/lib/readline/isearch.c +++ b/lib/readline/isearch.c @@ -297,6 +297,7 @@ _rl_isearch_fini (_rl_search_cxt *cxt) rl_clear_message (); } +/* XXX - we could use _rl_bracketed_read_mbstring () here. */ int _rl_search_getchar (_rl_search_cxt *cxt) { diff --git a/lib/readline/kill.c b/lib/readline/kill.c index cf8ca9324..6a2e0c6a5 100644 --- a/lib/readline/kill.c +++ b/lib/readline/kill.c @@ -1,6 +1,6 @@ /* kill.c -- kill ring management. */ -/* Copyright (C) 1994-2017 Free Software Foundation, Inc. +/* Copyright (C) 1994-2019 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -668,8 +668,7 @@ rl_yank_last_arg (int count, int key) /* Having read the special escape sequence denoting the beginning of a `bracketed paste' sequence, read the rest of the pasted input until the - closing sequence and insert the pasted text as a single unit without - interpretation. */ + closing sequence and return the pasted text. */ char * _rl_bracketed_text (size_t *lenp) { @@ -715,6 +714,10 @@ _rl_bracketed_text (size_t *lenp) return (buf); } +/* Having read the special escape sequence denoting the beginning of a + `bracketed paste' sequence, read the rest of the pasted input until the + closing sequence and insert the pasted text as a single unit without + interpretation. */ int rl_bracketed_paste_begin (int count, int key) { @@ -729,6 +732,96 @@ rl_bracketed_paste_begin (int count, int key) return (retval); } +int +_rl_read_bracketed_paste_prefix (int c) +{ + char pbuf[BRACK_PASTE_SLEN+1], *pbpref; + int key, ind, j; + + pbpref = BRACK_PASTE_PREF; /* XXX - debugging */ + if (c != pbpref[0]) + return (0); + pbuf[ind = 0] = c; + while (ind < BRACK_PASTE_SLEN-1 && + (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) && + _rl_pushed_input_available () == 0 && + _rl_input_queued (0)) + { + key = rl_read_key (); /* XXX - for now */ + if (key < 0) + break; + pbuf[++ind] = key; + if (pbuf[ind] != pbpref[ind]) + break; + } + + if (ind < BRACK_PASTE_SLEN-1) /* read incomplete sequence */ + { + while (ind >= 0) + _rl_unget_char (pbuf[ind--]); + return (key < 0 ? key : 0); + } + return (key < 0 ? key : 1); +} + +/* Get a character from wherever we read input, handling input in bracketed + paste mode. If we don't have or use bracketed paste mode, this can be + used in place of rl_read_key(). */ +int +_rl_bracketed_read_key () +{ + int c, r; + char *pbuf; + size_t pblen; + + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (c < 0) + return -1; + + /* read pasted data with bracketed-paste mode enabled. */ + if (_rl_enable_bracketed_paste && c == ESC && (r = _rl_read_bracketed_paste_prefix (c)) == 1) + { + pbuf = _rl_bracketed_text (&pblen); + if (pblen == 0) + { + xfree (pbuf); + return 0; /* XXX */ + } + c = (unsigned char)pbuf[0]; + if (pblen > 1) + { + while (--pblen > 0) + _rl_unget_char ((unsigned char)pbuf[pblen]); + } + xfree (pbuf); + } + + return c; +} + +/* Get a character from wherever we read input, handling input in bracketed + paste mode. If we don't have or use bracketed paste mode, this can be + used in place of rl_read_key(). */ +int +_rl_bracketed_read_mbstring (char *mb, int mlen) +{ + int c, r; + + c = _rl_bracketed_read_key (); + if (c < 0) + return -1; + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + c = _rl_read_mbstring (c, mb, mlen); +#endif + + return c; +} + /* A special paste command for Windows users. */ #if defined (_WIN32) #include diff --git a/lib/readline/misc.c b/lib/readline/misc.c index b49d61ac2..e6b42ebf2 100644 --- a/lib/readline/misc.c +++ b/lib/readline/misc.c @@ -138,9 +138,7 @@ _rl_arg_dispatch (_rl_arg_cxt cxt, int c) } else { - RL_SETSTATE(RL_STATE_MOREINPUT); - key = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); + key = _rl_bracketed_read_key (); rl_restore_prompt (); rl_clear_message (); RL_UNSETSTATE(RL_STATE_NUMERICARG); diff --git a/lib/readline/rlprivate.h b/lib/readline/rlprivate.h index 38e1dc79b..76631d7ab 100644 --- a/lib/readline/rlprivate.h +++ b/lib/readline/rlprivate.h @@ -309,7 +309,10 @@ extern int _rl_search_getchar PARAMS((_rl_search_cxt *)); #define BRACK_PASTE_INIT "\033[?2004h" #define BRACK_PASTE_FINI "\033[?2004l\r" +extern int _rl_read_bracketed_paste_prefix PARAMS((int)); extern char *_rl_bracketed_text PARAMS((size_t *)); +extern int _rl_bracketed_read_key PARAMS((void)); +extern int _rl_bracketed_read_mbstring PARAMS((char *, int)); /* macro.c */ extern void _rl_with_macro_input PARAMS((char *)); diff --git a/lib/readline/text.c b/lib/readline/text.c index 43aa4d97d..ff6ab6884 100644 --- a/lib/readline/text.c +++ b/lib/readline/text.c @@ -1,6 +1,6 @@ /* text.c -- text handling commands for readline. */ -/* Copyright (C) 1987-2017 Free Software Foundation, Inc. +/* Copyright (C) 1987-2019 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -1722,10 +1722,7 @@ _rl_char_search (int count, int fdir, int bdir) { int c; - RL_SETSTATE(RL_STATE_MOREINPUT); - c = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); - + c = _rl_bracketed_read_key (); if (c < 0) return 1; diff --git a/lib/readline/vi_mode.c b/lib/readline/vi_mode.c index 836371c95..dd4c3e8c4 100644 --- a/lib/readline/vi_mode.c +++ b/lib/readline/vi_mode.c @@ -1,7 +1,7 @@ /* vi_mode.c -- A vi emulation mode for Bash. Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */ -/* Copyright (C) 1987-2018 Free Software Foundation, Inc. +/* Copyright (C) 1987-2019 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -1316,13 +1316,7 @@ rl_domove_read_callback (_rl_vimotion_cxt *m) static int rl_vi_domove_getchar (_rl_vimotion_cxt *m) { - int c; - - RL_SETSTATE(RL_STATE_MOREINPUT); - c = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); - - return c; + return (_rl_bracketed_read_key ()); } #if defined (READLINE_CALLBACKS) @@ -2000,21 +1994,7 @@ _rl_vi_change_char (int count, int c, char *mb) static int _rl_vi_callback_getchar (char *mb, int mlen) { - int c; - - RL_SETSTATE(RL_STATE_MOREINPUT); - c = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); - - if (c < 0) - return -1; - -#if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - c = _rl_read_mbstring (c, mb, mlen); -#endif - - return c; + return (_rl_bracketed_read_mbstring (mb, mlen)); } #if defined (READLINE_CALLBACKS) @@ -2137,6 +2117,34 @@ rl_vi_overstrike_delete (int count, int key) return (0); } +/* Read bracketed paste mode pasted text and insert it in overwrite mode */ +static int +rl_vi_overstrike_bracketed_paste (int count, int key) +{ + int r; + char *pbuf; + size_t pblen; + + pbuf = _rl_bracketed_text (&pblen); + if (pblen == 0) + { + xfree (pbuf); + return 0; + } + r = pblen; + while (--r >= 0) + _rl_unget_char ((unsigned char)pbuf[r]); + xfree (pbuf); + + while (_rl_pushed_input_available ()) + { + key = rl_read_key (); + r = rl_vi_overstrike (1, key); + } + + return r; +} + int rl_vi_replace (int count, int key) { @@ -2179,6 +2187,9 @@ rl_vi_replace (int count, int key) _rl_vi_last_key_before_insert = key; _rl_keymap = vi_replace_map; + if (_rl_enable_bracketed_paste) + rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_vi_overstrike_bracketed_paste); + return (0); } diff --git a/subst.c b/subst.c index 9bfff905a..6660fa18b 100644 --- a/subst.c +++ b/subst.c @@ -1155,6 +1155,18 @@ string_extract_verbatim (string, slen, sindex, charlist, flags) return temp; } + /* This can never be called with charlist == NULL. If *charlist == NULL, + we can skip the loop and just return a copy of the string, updating + *sindex */ + if (*charlist == 0) + { + temp = string + *sindex; + c = (*sindex == 0) ? slen : STRLEN (temp); + temp = savestring (temp); + *sindex += c; + return temp; + } + i = *sindex; #if defined (HANDLE_MULTIBYTE) wcharlist = 0; @@ -2352,7 +2364,7 @@ split_at_delims (string, slen, delims, sentinel, flags, nwp, cwp) token = substring (string, ts, te); - ret = add_string_to_list (token, ret); + ret = add_string_to_list (token, ret); /* XXX */ free (token); nw++; @@ -2778,7 +2790,7 @@ list_string (string, separators, quoted) WORD_LIST *result; WORD_DESC *t; char *current_word, *s; - int sindex, sh_style_split, whitesep, xflags; + int sindex, sh_style_split, whitesep, xflags, free_word; size_t slen; if (!string || !*string) @@ -2800,7 +2812,14 @@ list_string (string, separators, quoted) STRING is quoted or if there are no separator characters. We use the Posix definition of whitespace as a member of the space character class in the current locale. */ +#if 0 if (!quoted || !separators || !*separators) +#else + /* issep() requires that separators be non-null, and always returns 0 if + separator is the empty string, so don't bother if we get an empty string + for separators. We already returned NULL above if STRING is empty. */ + if (!quoted && separators && *separators) +#endif { for (s = string; *s && issep (*s) && ifs_whitespace (*s); s++); @@ -2824,6 +2843,8 @@ list_string (string, separators, quoted) if (current_word == 0) break; + free_word = 1; /* If non-zero, we free current_word */ + /* If we have a quoted empty string, add a quoted null argument. We want to preserve the quoted null character iff this is a quoted empty string; otherwise the quoted null characters are removed @@ -2840,7 +2861,15 @@ list_string (string, separators, quoted) /* If we have something, then add it regardless. However, perform quoted null character removal on the current word. */ remove_quoted_nulls (current_word); - result = add_string_to_list (current_word, result); + + /* We don't want to set the word flags based on the string contents + here -- that's mostly for the parser -- so we just allocate a + WORD_DESC *, assign current_word (noting that we don't want to + free it), and skip all of make_word. */ + t = alloc_word_desc (); + t->word = current_word; + result = make_word_list (t, result); + free_word = 0; result->word->flags &= ~W_HASQUOTEDNULL; /* just to be sure */ if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) result->word->flags |= W_QUOTED; @@ -2860,7 +2889,8 @@ list_string (string, separators, quoted) result = make_word_list (t, result); } - free (current_word); + if (free_word) + free (current_word); /* Note whether or not the separator is IFS whitespace, used later. */ whitesep = string[sindex] && ifs_whitesep (string[sindex]); @@ -6119,7 +6149,7 @@ read_comsub (fd, quoted, flags, rflag) } /* Add the character to ISTRING, possibly after resizing it. */ - RESIZE_MALLOCED_BUFFER (istring, istring_index, mb_cur_max+1, istring_size, DEFAULT_ARRAY_SIZE); + RESIZE_MALLOCED_BUFFER (istring, istring_index, mb_cur_max+1, istring_size, 512); /* This is essentially quote_string inline */ if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */) @@ -7191,9 +7221,9 @@ parameter_brace_expand_length (name) char *t, *newname; intmax_t number, arg_index; WORD_LIST *list; -#if defined (ARRAY_VARS) SHELL_VAR *var; -#endif + + var = (SHELL_VAR *)NULL; if (name[1] == '\0') /* ${#} */ number = number_of_args (); @@ -7254,6 +7284,15 @@ parameter_brace_expand_length (name) number = MB_STRLEN (t); } #endif + /* Fast path for the common case of taking the length of a non-dynamic + scalar variable value. */ + else if ((var || (var = find_variable (name + 1))) && + invisible_p (var) == 0 && + array_p (var) == 0 && assoc_p (var) == 0 && + var->dynamic_value == 0) + number = value_cell (var) ? MB_STRLEN (value_cell (var)) : 0; + else if (var == 0 && unbound_vars_is_error == 0) + number = 0; else /* ${#PS1} */ { newname = savestring (name);