From: Chet Ramey Date: Tue, 5 Dec 2023 16:54:24 +0000 (-0500) Subject: readline fix for do-lowercase-version; fix for reading here-documents from aliases X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ba57a3e752a949da1ba1e5729ec5ae1a7ac06bca;p=thirdparty%2Fbash.git readline fix for do-lowercase-version; fix for reading here-documents from aliases --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index baf1677b8..c163e28a6 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -8109,3 +8109,35 @@ builtins/set.def doc/bashref.texi - update posix mode section with change to unset for interp 1009 + + 12/1 + ---- +lib/readline/readline.c + - _rl_subseq_result: add check before _rl_do_lowercase_version that + _rl_to_lower actually results in a different key sequence + Report and patch from Grisha Levit + +lib/readline/isearch.c + - _rl_isearch_dispatch: if the function bound to a key and the function + bound to the result of _rl_to_lower for that key are both + rl_do_lowercase_version, just insert the key into the search string + + 12/5 + ---- +parse.y,parser.h + - heredoc_string: new variable to indicate whether or not we're reading + a here-document from an alias (a pushed string). Set in + gather_here_documents individually for each call to + make_here_document. + +parse.y + - read_a_line: if heredoc_string is non-zero, use shell_getc instead + of yy_getc to get the right alias processing + - shell_getc: if heredoc_string is non-zero, don't add a space to the + end of the alias -- it can mess up the here-document delimiter if + the next character is a newline + Report and sample patch from gldrk + +parse.y,make_cmd.c + - read_a_line,make_here_document: if we're using shell_getc to read + the body of a here-document, let it manage line_number diff --git a/MANIFEST b/MANIFEST index c6c4817cd..81ef50989 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1246,6 +1246,7 @@ tests/heredoc6.sub f tests/heredoc7.sub f tests/heredoc8.sub f tests/heredoc9.sub f +tests/heredoc10.sub f tests/herestr.tests f tests/herestr.right f tests/herestr1.sub f diff --git a/lib/readline/isearch.c b/lib/readline/isearch.c index 07e76f116..9ddf9ce33 100644 --- a/lib/readline/isearch.c +++ b/lib/readline/isearch.c @@ -430,7 +430,11 @@ add_character: { f = cxt->keymap[c].function; if (f == rl_do_lowercase_version) - f = cxt->keymap[_rl_to_lower (c)].function; + { + f = cxt->keymap[_rl_to_lower (c)].function; + if (f == rl_do_lowercase_version) + f = rl_insert; + } } if (f == rl_reverse_search_history) diff --git a/lib/readline/readline.c b/lib/readline/readline.c index 608c65ec3..dbe57ef6d 100644 --- a/lib/readline/readline.c +++ b/lib/readline/readline.c @@ -1124,7 +1124,11 @@ _rl_subseq_result (int r, Keymap map, int key, int got_subseq) type = m[ANYOTHERKEY].type; func = m[ANYOTHERKEY].function; if (type == ISFUNC && func == rl_do_lowercase_version) - r = _rl_dispatch (_rl_to_lower ((unsigned char)key), map); + { + int newkey = _rl_to_lower ((unsigned char)key); + /* check that there is actually a lowercase version to avoid infinite recursion */ + r = (newkey != key) ? _rl_dispatch (newkey, map) : 1; + } else if (type == ISFUNC) { /* If we shadowed a function, whatever it is, we somehow need a diff --git a/make_cmd.c b/make_cmd.c index db4f37599..3830a3b22 100644 --- a/make_cmd.c +++ b/make_cmd.c @@ -573,7 +573,11 @@ make_here_document (REDIRECT *temp, int lineno) here_doc_first_line = 0; line = full_line; - line_number++; + + /* if read_secondary_line uses shell_getc, that handles incrementing + line_number where necessary. */ + if (heredoc_string == 0) + line_number++; /* If set -v is in effect, echo the line read. read_secondary_line/ read_a_line leaves the newline at the end, so don't print another. */ diff --git a/parse.y b/parse.y index 4170d144b..e1e64f5c2 100644 --- a/parse.y +++ b/parse.y @@ -295,6 +295,9 @@ int parser_state; static REDIRECT *redir_stack[HEREDOC_MAX]; int need_here_doc; +/* Are we reading a here-document from a string? (alias) */ +int heredoc_string; + /* Where shell input comes from. History expansion is performed on each line when the shell is interactive. */ static char *shell_input_line = (char *)NULL; @@ -2143,7 +2146,8 @@ read_a_line (int remove_quoted_newline) /* Allow immediate exit if interrupted during input. */ QUIT; - c = yy_getc (); + /* If we're reading the here-document from an alias, use shell_getc */ + c = heredoc_string ? shell_getc (0) : yy_getc (); /* Ignore null bytes in input. */ if (c == 0) @@ -2155,7 +2159,13 @@ read_a_line (int remove_quoted_newline) if (interactive && bash_input.type == st_stream) clearerr (stdin); if (indx == 0) - return ((char *)NULL); + { + /* if we use shell_getc, that increments line_number on eof */ + if (heredoc_string) + line_number--; + + return ((char *)NULL); + } c = '\n'; } @@ -2177,10 +2187,12 @@ read_a_line (int remove_quoted_newline) else if (c == '\\' && remove_quoted_newline) { QUIT; - peekc = yy_getc (); + /* If we're reading the here-document from an alias, use shell_getc */ + peekc = heredoc_string ? shell_getc (0) : yy_getc (); if (peekc == '\n') { - line_number++; + if (heredoc_string == 0) + line_number++; continue; /* Make the unquoted \ pair disappear. */ } else if (peekc == EOF) @@ -2200,7 +2212,11 @@ read_a_line (int remove_quoted_newline) } else { - yy_ungetc (peekc); + if (heredoc_string) + shell_ungetc (peekc); + else + yy_ungetc (peekc); + pass_next = 1; line_buffer[indx++] = c; /* Preserve the backslash. */ } @@ -2691,12 +2707,13 @@ next_alias_char: return the space that will delimit the token and postpone the pop_string. This set of conditions duplicates what used to be in mk_alexpansion () below, with the addition that we don't add a space if we're currently - reading a quoted string or in a shell comment. */ + reading a quoted string or in a shell comment or here-document. */ #ifndef OLD_ALIAS_HACK if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE && pushed_string_list->flags != PSH_DPAREN && (parser_state & PST_COMMENT) == 0 && (parser_state & PST_ENDALIAS) == 0 && /* only once */ + heredoc_string == 0 && shell_input_line_index > 0 && shellblank (shell_input_line[shell_input_line_index-1]) == 0 && shell_input_line[shell_input_line_index-1] != '\n' && @@ -3027,6 +3044,7 @@ gather_here_documents (void) while (need_here_doc > 0) { parser_state |= PST_HEREDOC; + heredoc_string = expanding_alias () && (shell_input_line_index < shell_input_line_len); make_here_document (redir_stack[r++], line_number); parser_state &= ~PST_HEREDOC; need_here_doc--; diff --git a/parser.h b/parser.h index 752dd7d73..14cd41493 100644 --- a/parser.h +++ b/parser.h @@ -103,6 +103,7 @@ extern int shell_eof_token; extern int current_token; extern int parser_state; extern int need_here_doc; +extern int heredoc_string; extern int ignoreeof; extern int eof_encountered; diff --git a/po/pt_BR.gmo b/po/pt_BR.gmo index 4c968346d..4aecfc354 100644 Binary files a/po/pt_BR.gmo and b/po/pt_BR.gmo differ diff --git a/po/pt_BR.po b/po/pt_BR.po index eaae6b58d..0c5b20e7e 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: bash 5.2-rc1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-01-11 14:50-0500\n" -"PO-Revision-Date: 2023-01-12 14:27-0300\n" +"PO-Revision-Date: 2023-12-04 14:27-0300\n" "Last-Translator: Rafael Fontenelle \n" "Language-Team: Brazilian Portuguese \n" "Language: pt_BR\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1)\n" -"X-Generator: Gtranslator 42.0\n" +"X-Generator: Gtranslator 45.2\n" "X-Bugs: Report translation errors to the Language-Team address.\n" #: arrayfunc.c:66 diff --git a/tests/heredoc.right b/tests/heredoc.right index d5a4a7d75..a50493061 100644 --- a/tests/heredoc.right +++ b/tests/heredoc.right @@ -153,8 +153,14 @@ HERE echo 3 4; done } +hello +world +hello +world +here-document +here-document comsub here-string -./heredoc.tests: line 181: warning: here-document at line 178 delimited by end-of-file (wanted `') +./heredoc.tests: line 184: warning: here-document at line 181 delimited by end-of-file (wanted `') hi there '' diff --git a/tests/heredoc.tests b/tests/heredoc.tests index 2f94d1d72..d6431b8a7 100644 --- a/tests/heredoc.tests +++ b/tests/heredoc.tests @@ -168,6 +168,9 @@ ${THIS_SH} ./heredoc8.sub # various tests for printing here-documents in function bodies ${THIS_SH} ./heredoc9.sub +# test various combinations of here-documents and aliases +${THIS_SH} ./heredoc10.sub + echo $( cat <<< "comsub here-string" ) diff --git a/tests/heredoc10.sub b/tests/heredoc10.sub new file mode 100644 index 000000000..aa310e173 --- /dev/null +++ b/tests/heredoc10.sub @@ -0,0 +1,45 @@ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# test various forms of reading here-documents from an alias +shopt -s expand_aliases + +# single alias definition contains entire here-document +alias 'foo=cat <$TMPFILE + +echo expect outside +var=temp . $TMPFILE +echo $var + +set -o posix +echo expect assignment +var=temp . $TMPFILE +echo $var + +rm -f $TMPFILE +unset -v var diff --git a/tests/varenv12.sub b/tests/varenv12.sub index 92b3692f5..441a02f03 100644 --- a/tests/varenv12.sub +++ b/tests/varenv12.sub @@ -134,6 +134,19 @@ echo -n 'outside 3.0: ' ; echo "var=${var-}" unset -v var unset -f func1 +# operations inside a function on temporary variables do not propagate +func1() +{ + export var + echo -n 'inside func1: ' ; echo "var=${var-}" +} +var=outside +var=func func1 +echo -n 'outside 3.5: ' ; echo "var=${var-}" + +unset -v var +unset -f func1 + func2() { local var=local