]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
fix off by one error when dequoting completed filenames; initial cut at readline...
authorChet Ramey <chet.ramey@case.edu>
Wed, 13 Dec 2023 15:52:43 +0000 (10:52 -0500)
committerChet Ramey <chet.ramey@case.edu>
Wed, 13 Dec 2023 15:52:43 +0000 (10:52 -0500)
CWRU/CWRU.chlog
Makefile.in
bashline.c
lib/readline/rlconf.h
lib/readline/terminal.c
print_cmd.c
tests/heredoc.right
tests/heredoc10.sub
tests/type.right
tests/type4.sub

index c163e28a60da20a13229e162e8d331e25417d0ac..e1039c83705ec6b35bb2b86ba1c8fa92fbdff8a6 100644 (file)
@@ -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 <ota@prosa.dk>, fix from Grisha Levit <grishalevit@gmail.com>
+
+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 <nuclear@mutantstargoat.com> 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 <ackbeat@gmail.com>
index a257fa8d7c3b10d811bee1cf01885cbc0dd15d9b..d6fdd70b2938ecd94a11933e088c833fb3511940 100644 (file)
@@ -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)
 
index 774f813fa8f9fb4962250d261a0449e856cf0d81..8ba34a8162c1db7ab755af9f979955b0734d20e9 100644 (file)
@@ -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;
index b6d6a2f12841ac5e3a6d096f6c321e56b61919ad..e0fd735b5b3c16ba2931762665a0e0cb185942d4 100644 (file)
@@ -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_ */
index 67adc7b5f9caa97d8b3af28fc88ca9e5e41fb61e..7003d2a97d99cef0f10335bafd97ce6692643637 100644 (file)
@@ -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)
index 2bf271f453e14e9711e948e4b2064d8565d52513..2b33f197053136bd78f7b877997fa8a306a997b2 100644 (file)
@@ -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;
index a504930616134dd6cea7c9ff038ff54b0e6038ab..a3ef0336fb8c8ee30bf4a6a2c6bb8c5fd896823c 100644 (file)
@@ -157,6 +157,8 @@ hello
 world
 hello
 world
+here-doc line 1
+here-doc line 2
 here-document
 here-document
 comsub here-string
index aa310e173507df2588526fa57cb5a17ee6285bdc..d5d3864bc57aee68b548d639736d33b26185000a 100644 (file)
 shopt -s expand_aliases
 
 # single alias definition contains entire here-document
-alias 'foo=cat <<EOF
+alias 'heredoc=cat <<EOF
 hello
 world
 EOF'
-foo
+heredoc
 
 # here-document body continues after alias definition
-alias 'foo=cat <<EOF
+alias 'headplus=cat <<EOF
 hello'
-foo
+headplus
 world
 EOF
 
+unalias heredoc headplus
+
+alias head='cat <<END'
+
+head
+here-doc line 1
+here-doc line 2
+END
+
 # here-document delimiter in one alias, body in another
-shopt -s expand_aliases
-alias c='cat <<\END' d='c
+alias head='cat <<\END' body='head
 here-document
 END'
-d
+body
 
 # make sure delimiter is recognized whether the alias ends with a newline or not
 shopt -s expand_aliases
-alias c='cat <<\END' d='c
+alias head='cat <<\END' body='head
 here-document
 END
 '
-d
+body
+
+unalias head body
index 817757a4b11efecc38e4e39d4395921749b0f3d3..957bc97d1ad3d14b91708d9d5af9cf028fc35870 100644 (file)
@@ -134,6 +134,11 @@ EOF
  );
     echo "coprocs created"
 }
+mkcoprocs is a function
+mkcoprocs () 
+{ 
+    coproc cat -u - & read -u ${COPROC[0]} msg
+}
 cat is /bin/cat
 cat is aliased to `echo cat'
 /bin/cat
index 937f9980cc6c249b685fe6d46e8bc6dab8aec9fd..cff16ac3c982c4125347a25e6bad0e77348f91eb 100644 (file)
@@ -54,3 +54,13 @@ echo "coprocs created"
 }
 
 type mkcoprocs
+
+unset -f mkcoprocs
+
+# make sure that simple commands are printed without the coproc name
+mkcoprocs ()
+{
+       coproc cat -u - &
+       read -u ${COPROC[0]} msg
+}
+type mkcoprocs