From: Chet Ramey Date: Wed, 13 Dec 2023 15:52:43 +0000 (-0500) Subject: fix off by one error when dequoting completed filenames; initial cut at readline... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9d51df7546eab80ea6baa4a83b2ae2178e8020c5;p=thirdparty%2Fbash.git fix off by one error when dequoting completed filenames; initial cut at readline identifying ANSI terminals; print coproc commands without coproc name if the coproc is a simple command --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index c163e28a6..e1039c837 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -8141,3 +8141,34 @@ parse.y 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 + + 12/8 + ---- +bashline.c + - bash_dequote_filename: fix an off-by-one error that didn't remove a + closing single quote in a filename if it was backslash-escaped. + Report by Ole Tange , fix from Grisha Levit + +lib/readline/terminal.c + - _rl_check_ansi_terminal: check whether or not rl_terminal_name + appears to be an ANSI/ECMA-48 terminal. Check some common terminal + types and then check whether some common terminal capabilities + (ce, nd, ho, up) begin with CSI (ESC-[) and then have a correct + subsequent character + - _rl_term_isansi: new variable, holds readline's idea about whether + the value of rl_terminal_name is an ANSI/ECMA-48 terminal. Initialized + to RL_ANSI_TERM_DEFAULT; set to the result of _rl_check_ansi_terminal + if initialized to 0 and on a `non-dumb' terminal + From an idea by John Tsiombikas in 11/2023 + +lib/readline/rlconf.h + - RL_ANSI_TERM_DEFAULT: define to 1 (yes) or 0 (no) to tell readline + whether or not to assume it's running on an ANSI/ECMA-48 terminal. + The default is 1 (yes) + + 12/11 + ----- +print_cmd.c + - make_command_string_internal: when printing a coproc, print the + coproc name only if the coproc command is not a simple command. + Report from Albert Akchurin diff --git a/Makefile.in b/Makefile.in index a257fa8d7..d6fdd70b2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -180,7 +180,8 @@ GCC_LINT_FLAGS = -O -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wno-parentheses -Wmissing-braces -Wuninitialized \ -Wmissing-declarations -Winline \ -Wmissing-prototypes -Wredundant-decls \ - -Wformat-security -pedantic + -Wformat-security -pedantic \ + -Werror=incompatible-pointer-types GCC_LINT_CFLAGS = $(BASE_CCFLAGS) $(CPPFLAGS) $(GCC_LINT_FLAGS) diff --git a/bashline.c b/bashline.c index 774f813fa..8ba34a816 100644 --- a/bashline.c +++ b/bashline.c @@ -4077,15 +4077,13 @@ bash_dequote_filename (char *text, int quote_char) ret = (char *)xmalloc (l + 1); for (quoted = quote_char, p = text, r = ret; p && *p; p++) { - /* Allow backslash-escaped characters to pass through unscathed. */ - if (*p == '\\') + /* Allow backslash-escaped characters to pass through unscathed. Backslashes + aren't special in single quotes. */ + if (quoted != '\'' && *p == '\\') { - /* Backslashes are preserved within single quotes. */ - if (quoted == '\'') - *r++ = *p; /* Backslashes are preserved within double quotes unless the character is one that is defined to be escaped */ - else if (quoted == '"' && ((sh_syntaxtab[(unsigned char)p[1]] & CBSDQUOTE) == 0)) + if (quoted == '"' && ((sh_syntaxtab[(unsigned char)p[1]] & CBSDQUOTE) == 0)) *r++ = *p; *r++ = *++p; diff --git a/lib/readline/rlconf.h b/lib/readline/rlconf.h index b6d6a2f12..e0fd735b5 100644 --- a/lib/readline/rlconf.h +++ b/lib/readline/rlconf.h @@ -76,4 +76,9 @@ #define RL_VI_CMD_MODESTR_DEFAULT "(cmd)" #define RL_VI_CMD_MODESTR_DEFLEN 5 +/* Do you want readline to assume it's running in an ANSI-compatible terminal + by default? If set to 0, readline tries to check and verify whether or not + it is. */ +#define RL_ANSI_TERM_DEFAULT 1 /* for now */ + #endif /* _RLCONF_H_ */ diff --git a/lib/readline/terminal.c b/lib/readline/terminal.c index 67adc7b5f..7003d2a97 100644 --- a/lib/readline/terminal.c +++ b/lib/readline/terminal.c @@ -1,6 +1,6 @@ /* terminal.c -- controlling the terminal with termcap. */ -/* Copyright (C) 1996-2022 Free Software Foundation, Inc. +/* Copyright (C) 1996-2023 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. @@ -113,6 +113,7 @@ char PC, *BC, *UP; char *_rl_term_clreol; char *_rl_term_clrpag; char *_rl_term_clrscroll; +char *_rl_term_ho; char *_rl_term_cr; char *_rl_term_backspace; char *_rl_term_goto; @@ -220,6 +221,9 @@ int _rl_enable_keypad; /* Non-zero means the user wants to enable a meta key. */ int _rl_enable_meta = 1; +/* Non-zero means this is an ANSI-compatible terminal; assume it is. */ +int _rl_term_isansi = RL_ANSI_TERM_DEFAULT; + #if defined (__EMX__) static void _emx_get_screensize (int *swp, int *shp) @@ -433,6 +437,7 @@ static const struct _tc_string tc_strings[] = { "cr", &_rl_term_cr }, { "dc", &_rl_term_dc }, { "ei", &_rl_term_ei }, + { "ho", &_rl_term_ho }, { "ic", &_rl_term_ic }, { "im", &_rl_term_im }, { "kD", &_rl_term_kD }, /* delete */ @@ -476,6 +481,63 @@ get_term_capabilities (char **bp) tcap_initialized = 1; } +struct _term_name { + const char * const name; + size_t len; +}; + +/* Non-exhaustive list of ANSI/ECMA terminals. */ +static const struct _term_name ansiterms[] = +{ + { "xterm", 5 }, + { "rxvt", 4 }, + { "eterm", 5 }, + { "screen", 6 }, + { "tmux", 4 }, + { "vt100", 5 }, + { "vt102", 5 }, + { "vt220", 5 }, + { "vt320", 5 }, + { "ansi", 4 }, + { "scoansi", 7 }, + { "cygwin", 6 }, + { "linux", 5 }, + { "konsole", 7 }, + { "bvterm", 6 }, + { 0, 0 } +}; + +static inline int +iscsi (const char *s) +{ + return ((s[0] == ESC && s[1] == '[') ? 2 + : ((unsigned char)s[0] == 0x9b) ? 1 : 0); +} + +static int +_rl_check_ansi_terminal (const char *terminal_name) +{ + int i; + size_t len; + + for (i = 0; ansiterms[i].name; i++) + if (STREQN (terminal_name, ansiterms[i].name, ansiterms[i].len)) + return 1; + + if (_rl_term_clreol == 0 || _rl_term_forward_char == 0 || + _rl_term_ho == 0 || _rl_term_up == 0) + return 0; + + /* check some common capabilities */ + if (((len = iscsi (_rl_term_clreol)) && _rl_term_clreol[len] == 'K') && /* ce */ + ((len = iscsi (_rl_term_forward_char)) && _rl_term_forward_char[len] == 'C') && /* nd */ + ((len = iscsi (_rl_term_ho)) && _rl_term_ho[len] == 'H') && /* ho */ + ((len = iscsi (_rl_term_up)) && _rl_term_up[len] == 'A')) /* up */ + return 1; + + return 0; +} + int _rl_init_terminal_io (const char *terminal_name) { @@ -490,7 +552,10 @@ _rl_init_terminal_io (const char *terminal_name) if (term == 0) term = "dumb"; - dumbterm = STREQ (term, "dumb"); + _rl_term_isansi = RL_ANSI_TERM_DEFAULT; + dumbterm = STREQ (term, "dumb") || STREQ (term, "vt52") || STREQ (term, "adm3a"); + if (dumbterm) + _rl_term_isansi = 0; reset_region_colors = 1; @@ -502,6 +567,7 @@ _rl_init_terminal_io (const char *terminal_name) _rl_terminal_can_insert = term_has_meta = _rl_term_autowrap = 0; _rl_term_cr = "\r"; _rl_term_backspace = (char *)NULL; + _rl_term_ho = (char *)NULL; _rl_term_goto = _rl_term_pc = _rl_term_ip = (char *)NULL; _rl_term_ks = _rl_term_ke =_rl_term_vs = _rl_term_ve = (char *)NULL; _rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL; @@ -564,6 +630,7 @@ _rl_init_terminal_io (const char *terminal_name) /* Everything below here is used by the redisplay code (tputs). */ _rl_screenchars = _rl_screenwidth * _rl_screenheight; _rl_term_cr = "\r"; + _rl_term_ho = (char *)NULL; _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL; _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL; _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL; @@ -576,6 +643,8 @@ _rl_init_terminal_io (const char *terminal_name) _rl_term_so = _rl_term_se = (char *)NULL; _rl_terminal_can_insert = term_has_meta = 0; + _rl_term_isansi = 0; /* not an ANSI terminal */ + /* Assume generic unknown terminal can't handle the enable/disable escape sequences */ _rl_term_BD = _rl_term_BE = _rl_term_PE = _rl_term_PS = (char *)NULL; @@ -637,9 +706,13 @@ _rl_init_terminal_io (const char *terminal_name) bind_termcap_arrow_keys (vi_insertion_keymap); #endif /* VI_MODE */ + if (dumbterm == 0 && _rl_term_isansi == 0) + _rl_term_isansi = _rl_check_ansi_terminal (terminal_name); + /* There's no way to determine whether or not a given terminal supports - bracketed paste mode, so we assume a terminal named "dumb" does not. */ - if (dumbterm) + bracketed paste mode, so we assume a non-ANSI terminal (as best as we + can determine) does not. */ + if (_rl_term_isansi == 0) _rl_enable_bracketed_paste = _rl_enable_active_region = 0; if (reset_region_colors) diff --git a/print_cmd.c b/print_cmd.c index 2bf271f45..2b33f1970 100644 --- a/print_cmd.c +++ b/print_cmd.c @@ -355,7 +355,9 @@ make_command_string_internal (COMMAND *command) break; case cm_coproc: - cprintf ("coproc %s ", command->value.Coproc->name); + cprintf ("coproc "); + if (command->value.Coproc->command->type != cm_simple) + cprintf ("%s ", command->value.Coproc->name); skip_this_indent++; make_command_string_internal (command->value.Coproc->command); break; diff --git a/tests/heredoc.right b/tests/heredoc.right index a50493061..a3ef0336f 100644 --- a/tests/heredoc.right +++ b/tests/heredoc.right @@ -157,6 +157,8 @@ hello world hello world +here-doc line 1 +here-doc line 2 here-document here-document comsub here-string diff --git a/tests/heredoc10.sub b/tests/heredoc10.sub index aa310e173..d5d3864bc 100644 --- a/tests/heredoc10.sub +++ b/tests/heredoc10.sub @@ -16,30 +16,40 @@ shopt -s expand_aliases # single alias definition contains entire here-document -alias 'foo=cat <