]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
fix for invalid bracketed paste prefix when the final character is wrong; fixes for...
authorChet Ramey <chet.ramey@case.edu>
Thu, 18 Sep 2025 21:35:34 +0000 (17:35 -0400)
committerChet Ramey <chet.ramey@case.edu>
Thu, 18 Sep 2025 21:35:34 +0000 (17:35 -0400)
CWRU/CWRU.chlog
builtins/declare.def
lib/readline/input.c
lib/readline/kill.c
lib/readline/text.c
lib/sh/strtrans.c

index 6c73a4fc719ecfb04ece20cd155de1af7f748c40..8d453e0c08a9727b07eada3cf61ed3e12c32ae0e 100644 (file)
@@ -11723,10 +11723,11 @@ lib/readline/macro.c
           reading input from a bound macro.
          Suggested by Grisha Levit <grishalevit@gmail.com>
 
-lib/readline/readline.c,lib/readline/text.c
-       - _rl_dispatch_subseq,_rl_insert_next,_rl_char_search: if we're
-         defining a keyboard macro, don't insert the expanded value of a
-         macro that is bound to a key sequence added to the keyboard macro
+lib/readline/readline.c,lib/readline/text.c,lib/readline/kill.c
+       - _rl_dispatch_subseq,_rl_insert_next,_rl_char_search,
+         _rl_bracketed_text: if we're defining a keyboard macro, don't
+         insert the expanded value of a macro that is bound to a key
+         sequence added to the keyboard macro
          Report and patch from Grisha Levit <grishalevit@gmail.com>
 
                                   9/12
@@ -11734,3 +11735,36 @@ lib/readline/readline.c,lib/readline/text.c
 builtins/mkbuiltins.c
        - some minor code cleanups
          Patch from Martin D Kealey <martin@kurahaupo.gen.nz>
+
+                                  9/15
+                                  ----
+lib/readline/kill.c
+       - _rl_read_bracketed_paste_prefix: if we read the bracketed paste
+         prefix except for the last character (key != BRACK_PASTE_LAST),
+         return 0, since we didn't read a valid prefix
+         Report from Grisha Levit <grishalevit@gmail.com>
+       - _rl_bracketed_text: if _rl_read_key returns < 0, abort trying
+         to read the string
+
+lib/readline/text.c
+       - _rl_readstr_init: set _rl_rscxt after we finish initializing cxt,
+         before the call to rl_message
+         Report from Grisha Levit <grishalevit@gmail.com>
+       - _rl_readstr_getchar: if _rl_read_mbstring returns and _rl_caught_signal
+         is != 0, treat this as a failure and return -1 after handling the
+         signal
+       - _rl_read_command_name: if _rl_readstr_getchar returns -1, but
+         _rl_rscxt is NULL, assume this was the result of a signal and call
+         _rl_abort_internal accordingly
+         Report from Grisha Levit <grishalevit@gmail.com>
+
+lib/readline/input.c
+       - rl_getc: skip trying to read a character if we have a signal pending
+         when we enter this function in all cases, not just callback mode.
+         Suggestion from Grisha Levit <grishalevit@gmail.com>
+
+lib/sh/strtrans.c
+       - ansic_quote: handle the undefined state of the internal state
+         pointer when encountering an invalid wide character by using our
+         own mbstate_t and reinitializing it on EILSEQ.
+         Report and patch from Grisha Levit <grishalevit@gmail.com>
index a8284daac191edc329f6ae7539fa329f1e2271d3..b8c6f96631f53b30f35bee52c360cfd62aa8415f 100644 (file)
@@ -44,11 +44,15 @@ Options which set attributes:
   -A   to make NAMEs associative arrays (if supported)
 #endif
   -i   to make NAMEs have the `integer' attribute
+#ifdef CASEMOD_ATTRS
   -l   to convert the value of each NAME to lower case on assignment
+#endif
   -n   make NAME a reference to the variable named by its value
   -r   to make NAMEs readonly
   -t   to make NAMEs have the `trace' attribute
+#ifdef CASEMOD_ATTRS
   -u   to convert the value of each NAME to upper case on assignment
+#endif
   -x   to make NAMEs export
 
 Using `+' instead of `-' turns off the given attribute, except for a,
index aecc6fc743c49b5164e4717df09dd43381af1cd4..b2072122bc3c1d1b6d875537bee1310592ef0351 100644 (file)
@@ -859,16 +859,14 @@ rl_getc (FILE *stream)
 
       RL_CHECK_SIGNALS ();
 
-#if defined (READLINE_CALLBACKS)
-      /* Do signal handling post-processing here, but just in callback mode
-        for right now because the signal cleanup can change some of the
+      /* Do signal handling post-processing here, not just in callback mode
+        now, because the signal cleanup can change some of the readline and
         callback state, and we need to either let the application have a
         chance to react or abort some current operation that gets cleaned
-        up by rl_callback_sigcleanup(). If not, we'll just run through the
-        loop again. */
-      if (osig != 0 && (ostate & RL_STATE_CALLBACK))   /* XXX - when not in callback mode also? */
+        up by rl_callback_sigcleanup() or another signal cleanup function.
+        If not, we'll just run through the loop again. */
+      if (osig != 0)
        goto postproc_signal;
-#endif
 
       /* We know at this point that _rl_caught_signal == 0 */
 
index ca92ea1345b4b81967cf98846e111951a9a7b5b2..9d3bdb48e7128e689f4584e9a176426d5517b6a1 100644 (file)
@@ -1,6 +1,6 @@
 /* kill.c -- kill ring management. */
 
-/* Copyright (C) 1994-2024 Free Software Foundation, Inc.
+/* Copyright (C) 1994-2025 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.      
@@ -718,7 +718,7 @@ _rl_bracketed_text (size_t *lenp)
   RL_SETSTATE (RL_STATE_MOREINPUT);
   while ((c = rl_read_key ()) >= 0)
     {
-      if (RL_ISSTATE (RL_STATE_MACRODEF))
+      if (RL_ISSTATE (RL_STATE_MACRODEF) && RL_ISSTATE (RL_STATE_MACROINPUT) == 0)
        _rl_add_macro_char (c);
 
       if (c == '\r')           /* XXX */
@@ -736,7 +736,11 @@ _rl_bracketed_text (size_t *lenp)
        }
     }
   RL_UNSETSTATE (RL_STATE_MOREINPUT);
-
+  if (c < 0)           /* read error */
+    {
+      free (buf);
+      _rl_abort_internal ();
+    }
   if (len == cap)
     buf = xrealloc (buf, cap + 1);
   buf[len] = '\0';
@@ -790,7 +794,7 @@ _rl_read_bracketed_paste_prefix (int c)
         break;
     }
 
-  if (ind < BRACK_PASTE_SLEN-1)                /* read incomplete sequence */
+  if (ind < BRACK_PASTE_SLEN-1 || key != BRACK_PASTE_LAST)     /* read incomplete sequence */
     {
       while (ind >= 0)
        _rl_unget_char (pbuf[ind--]);
index e3ae28e1a25c9db5928e85d7dd98a317fac01c26..9b00a6f154607ce2767450cdba2a4bca323e143a 100644 (file)
@@ -39,6 +39,7 @@
 #  include <locale.h>
 #endif
 
+#include <signal.h>
 #include <stdio.h>
 
 /* System-specific feature definitions and include files. */
@@ -2029,11 +2030,11 @@ _rl_readstr_init (int pchar, int flags)
 
   RL_SETSTATE (RL_STATE_READSTR);
   cxt->flags |= READSTR_FREEPMT;
+  _rl_rscxt = cxt;  
+
   rl_message ("%s", p);
   xfree (p);
 
-  _rl_rscxt = cxt;  
-
   return cxt;
 }
 
@@ -2081,7 +2082,7 @@ _rl_readstr_getchar (_rl_readstr_cxt *cxt)
   RL_SETSTATE(RL_STATE_MOREINPUT);
   c = cxt->lastc = rl_read_key ();
   RL_UNSETSTATE(RL_STATE_MOREINPUT);
-                 
+
 #if defined (HANDLE_MULTIBYTE)
   /* This ends up with C (and LASTC) being set to the last byte of the
      multibyte character.  In most cases c == lastc == mb[0] */
@@ -2089,6 +2090,9 @@ _rl_readstr_getchar (_rl_readstr_cxt *cxt)
     c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX);
 #endif
 
+  if (_rl_caught_signal == SIGINT)     /* XXX maybe more signals here */
+    c = -1;
+
   RL_CHECK_SIGNALS ();
   return c;
 }
@@ -2331,6 +2335,8 @@ _rl_read_command_name ()
 
       if (c < 0)
        {
+         if (_rl_rscxt == 0)           /* signal */
+           _rl_abort_internal ();
          _rl_readstr_restore (cxt);
          _rl_readstr_cleanup (cxt, r);
          return NULL;
index af75dcfa820dec170474c8a4b059687456bab672..5a5e9244835c50aa7bb214a7ef334b094faccb26 100644 (file)
@@ -227,30 +227,24 @@ ansic_quote (const char *str, int flags, int *rlen)
 {
   char *r, *ret;
   const char  *s;
-  size_t l, rsize;
   unsigned char c;
+#if defined (HANDLE_MULTIBYTE)
   size_t clen;
   int b;
-#if defined (HANDLE_MULTIBYTE)
   wchar_t wc;
+  DECLARE_MBSTATE;
 #endif
 
   if (str == 0 || *str == 0)
     return ((char *)0);
 
-  l = strlen (str);
-  rsize = 4 * l + 4;
-  r = ret = (char *)xmalloc (rsize);
+  r = ret = (char *)xmalloc (4 * strlen (str) + 4);
 
   *r++ = '$';
   *r++ = '\'';
 
   for (s = str; c = *s; s++)
     {
-      b = 1;           /* 1 == add backslash; 0 == no backslash */
-      l = 1;
-      clen = 1;
-
       switch (c)
        {
        case ESC: c = 'E'; break;
@@ -266,37 +260,38 @@ ansic_quote (const char *str, int flags, int *rlen)
          break;
        default:
 #if defined (HANDLE_MULTIBYTE)
-         b = is_basic (c);
-         /* XXX - clen comparison to 0 is dicey */
-         if ((b == 0 && ((clen = mbrtowc (&wc, s, MB_CUR_MAX, 0)) < 0 || MB_INVALIDCH (clen) || iswprint (wc) == 0)) ||
-             (b == 1 && ISPRINT (c) == 0))
-#else
-         if (ISPRINT (c) == 0)
-#endif
+         if (is_basic (c) == 0)
            {
-             *r++ = '\\';
-             *r++ = TOCHAR ((c >> 6) & 07);
-             *r++ = TOCHAR ((c >> 3) & 07);
-             *r++ = TOCHAR (c & 07);
-             continue;
+             clen = mbrtowc (&wc, s, MB_CUR_MAX, &state);
+             if (clen == 0)
+               break;
+             if (MB_INVALIDCH (clen))
+               INITIALIZE_MBSTATE;
+             else if (iswprint (wc))
+               {
+                 for (b = 0; b < (int)clen; b++)
+                   *r++ = (unsigned char)s[b];
+                 s += clen - 1;        /* -1 because of the increment above */
+                 continue;
+               }
            }
-         l = 0;
-         break;
+         else
+#endif
+           if (ISPRINT (c))
+             {
+               *r++ = c;
+               continue;
+             }
+
+           *r++ = '\\';
+           *r++ = TOCHAR ((c >> 6) & 07);
+           *r++ = TOCHAR ((c >> 3) & 07);
+           *r++ = TOCHAR (c & 07);
+           continue;
        }
-      if (b == 0 && clen == 0)
-       break;
 
-      if (l)
-       *r++ = '\\';
-
-      if (clen == 1)
-       *r++ = c;
-      else
-       {
-         for (b = 0; b < (int)clen; b++)
-           *r++ = (unsigned char)s[b];
-         s += clen - 1;        /* -1 because of the increment above */
-       }
+      *r++ = '\\';
+      *r++ = c;
     }
 
   *r++ = '\'';