mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-01 17:39:56 +02:00
fix for invalid bracketed paste prefix when the final character is wrong; fixes for unlikely SIGINTs while readline is reading from the keyboard; android fix for generating $'...' strings in the presence of invalid multibyte characters
This commit is contained in:
+38
-4
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
+8
-4
@@ -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--]);
|
||||
|
||||
+9
-3
@@ -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;
|
||||
|
||||
+31
-36
@@ -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;
|
||||
}
|
||||
if (b == 0 && clen == 0)
|
||||
break;
|
||||
else
|
||||
#endif
|
||||
if (ISPRINT (c))
|
||||
{
|
||||
*r++ = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
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++ = TOCHAR ((c >> 6) & 07);
|
||||
*r++ = TOCHAR ((c >> 3) & 07);
|
||||
*r++ = TOCHAR (c & 07);
|
||||
continue;
|
||||
}
|
||||
|
||||
*r++ = '\\';
|
||||
*r++ = c;
|
||||
}
|
||||
|
||||
*r++ = '\'';
|
||||
|
||||
Reference in New Issue
Block a user