mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-05 11:20:50 +02:00
minor readline fixes for isearch, insert-char,quoted-insert, and do-lowercase-version; fix buffer overflow with printf %b; work around issues with isblank in UTF-8 locales on macOS; fixes for the enable builtin
This commit is contained in:
@@ -6442,3 +6442,55 @@ eval.c
|
||||
back to 0 if we should not exit. This can occur when EOF delimits
|
||||
a simple command (simple_command_terminator)
|
||||
From a report by Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
5/27
|
||||
----
|
||||
lib/readline/mbutil.c
|
||||
- _rl_get_char_len: if SRC is "", make sure to return 0
|
||||
|
||||
lib/readline/isearch.c
|
||||
- _rl_isearch_callback: if _rl_search_getchar returns EOF, return 1
|
||||
to abort search; if it returns with RL_STATE_ISEARCH unset, return
|
||||
1 (handling a signal can turn it off via _rl_isearch_cleanup)
|
||||
|
||||
5/29
|
||||
----
|
||||
lib/readline/text.c
|
||||
- _rl_insert_char, rl_quoted_insert: minor fixes from Grisha Levit
|
||||
|
||||
builtins/printf.def
|
||||
- bexpand: use the same calculation for the size of the return buffer
|
||||
as ansicstr().
|
||||
From a report by Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
locale.c
|
||||
- locale_setblanks: work around problem with macOS where isblank(x)
|
||||
incorrectly returns true for characters 0x80-0xff in a UTF-8 locale
|
||||
From a report by Grisha Levit <grishalevit@gmail.com>
|
||||
- set_default_locale_vars,set_locale_vars,reset_locale_vars: make sure
|
||||
we call locale_setblanks after setting/resetting locale_utf8locale,
|
||||
since we use that in locale_setblanks
|
||||
|
||||
lib/sh/smatch.c
|
||||
- charseqcmp,is_cclass,FOLD: make sure we don't treat chars >= 0x80
|
||||
as valid in a UTF-8 locale, since they are multibyte characters.
|
||||
From a report by Grisha Levit <grishalevit@gmail.com> with a full
|
||||
explanation in http://www.openradar.me/FB9973780
|
||||
|
||||
5/30
|
||||
----
|
||||
builtins/enable.def
|
||||
- enable_builtin: don't call dlopen with a null pathname, it will
|
||||
succeed. Report from Wiley Young <wyeth2485@gmail.com>
|
||||
|
||||
lib/readline/readline.c
|
||||
- _rl_dispatch_subseq: if a user binds do-lowercase-version to something
|
||||
that isn't an uppercase character, flag an error rather than recurse.
|
||||
From a report by Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
5/31
|
||||
----
|
||||
builtins/enable.def
|
||||
- enable_builtin: don't try to load a builtin that's not found if
|
||||
the -n flag is supplied.
|
||||
From a report from Emanuele Torre <torreemanuele6@gmail.com>
|
||||
|
||||
+7
-4
@@ -215,20 +215,23 @@ enable_builtin (WORD_LIST *list)
|
||||
{
|
||||
while (list)
|
||||
{
|
||||
opt = enable_shell_command (list->word->word, flags & NFLAG);
|
||||
char *command;
|
||||
|
||||
command = list->word->word;
|
||||
opt = enable_shell_command (command, flags & NFLAG);
|
||||
next = list->next;
|
||||
|
||||
#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
|
||||
/* If we try to enable a non-existent builtin, and we have dynamic
|
||||
loading, try the equivalent of `enable -f name name'. */
|
||||
if (opt == EX_NOTFOUND)
|
||||
if (*command && (flags & NFLAG) == 0 && opt == EX_NOTFOUND)
|
||||
{
|
||||
int dflags, r;
|
||||
|
||||
dflags = ENABLED|SILENT|((flags & SFLAG) ? SPECIAL : 0);
|
||||
|
||||
list->next = 0;
|
||||
r = dyn_load_builtin (list, dflags, list->word->word);
|
||||
r = dyn_load_builtin (list, dflags, command);
|
||||
list->next = next;
|
||||
if (r == EXECUTION_SUCCESS)
|
||||
opt = r;
|
||||
@@ -240,7 +243,7 @@ enable_builtin (WORD_LIST *list)
|
||||
|
||||
if (opt == EX_NOTFOUND)
|
||||
{
|
||||
sh_notbuiltin (list->word->word);
|
||||
sh_notbuiltin (command);
|
||||
result = EXECUTION_FAILURE;
|
||||
}
|
||||
else if (opt != EXECUTION_SUCCESS)
|
||||
|
||||
@@ -1152,7 +1152,16 @@ bexpand (char *string, int len, int *sawc, int *lenp)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
/* same logic as lib/sh/strtrans.c:ansicstr() */
|
||||
temp = 4*len + 4;
|
||||
if (temp < 12)
|
||||
temp = 12; /* ensure enough for eventual u32cesc */
|
||||
ret = (char *)xmalloc (temp);
|
||||
#else
|
||||
ret = (char *)xmalloc (len + 1);
|
||||
#endif
|
||||
temp = 0;
|
||||
for (r = ret, s = string; s && *s; )
|
||||
{
|
||||
c = *s++;
|
||||
|
||||
@@ -55,6 +55,9 @@ extern int locale_utf8locale; /* XXX */
|
||||
#define UTF8_MBFIRSTCHAR(c) (((c) & 0xc0) == 0xc0)
|
||||
#define UTF8_MBCHAR(c) (((c) & 0xc0) == 0x80)
|
||||
|
||||
/* Is an eight-bit quantity a valid character in the current locale? */
|
||||
#define VALID_SINGLEBYTE_CHAR(c) (locale_utf8locale == 0 || ((c) & 0x80) == 0)
|
||||
|
||||
#else /* !HANDLE_MULTIBYTE */
|
||||
|
||||
#undef MB_LEN_MAX
|
||||
@@ -83,6 +86,8 @@ extern int locale_utf8locale; /* XXX */
|
||||
#define UTF8_SINGLEBYTE(c) (1)
|
||||
#define UTF8_MBFIRSTCHAR(c) (0)
|
||||
|
||||
#defined VALID_SINGLEBYTE_CHAR(c) (1)
|
||||
|
||||
#endif /* !HANDLE_MULTIBYTE */
|
||||
|
||||
/* Declare and initialize a multibyte state. Call must be terminated
|
||||
|
||||
+11
-3
@@ -141,6 +141,10 @@ rangecmp (int c1, int c2, int forcecoll)
|
||||
static int
|
||||
collseqcmp (int c, int equiv)
|
||||
{
|
||||
/* Make sure characters >= 0x80 are compared as bytes in a UTF-8 locale. */
|
||||
if (locale_utf8locale && (UTF8_SINGLEBYTE (c) == 0 || UTF8_SINGLEBYTE (equiv) == 0))
|
||||
return (c == equiv);
|
||||
|
||||
if (charcmp (c, equiv, 1) == 0)
|
||||
return 1;
|
||||
|
||||
@@ -281,6 +285,9 @@ is_cclass (int c, const char *name)
|
||||
enum char_class char_class;
|
||||
int result;
|
||||
|
||||
if (locale_utf8locale && UTF8_SINGLEBYTE (c) == 0)
|
||||
return -1;
|
||||
|
||||
char_class = is_valid_cclass (name);
|
||||
if (char_class == CC_NO_CLASS)
|
||||
return -1;
|
||||
@@ -291,9 +298,10 @@ is_cclass (int c, const char *name)
|
||||
|
||||
/* Now include `sm_loop.c' for single-byte characters. */
|
||||
/* The result of FOLD is an `unsigned char' */
|
||||
# define FOLD(c) ((flags & FNM_CASEFOLD) \
|
||||
? TOLOWER ((unsigned char)c) \
|
||||
: ((unsigned char)c))
|
||||
# define FOLD(c) \
|
||||
(((flags & FNM_CASEFOLD) && (locale_utf8locale == 0 || UTF8_SINGLEBYTE (c))) \
|
||||
? TOLOWER ((unsigned char)c) \
|
||||
: ((unsigned char)c))
|
||||
|
||||
#if !defined (__CYGWIN__)
|
||||
# define ISDIRSEP(c) ((c) == '/')
|
||||
|
||||
@@ -919,6 +919,13 @@ _rl_isearch_callback (_rl_search_cxt *cxt)
|
||||
int c, r;
|
||||
|
||||
c = _rl_search_getchar (cxt);
|
||||
|
||||
if (c < 0) /* EOF */
|
||||
return 1;
|
||||
|
||||
if (RL_ISSTATE (RL_STATE_ISEARCH) == 0) /* signal could turn it off */
|
||||
return 1;
|
||||
|
||||
/* We might want to handle EOF here */
|
||||
r = _rl_isearch_dispatch (cxt, cxt->lastc);
|
||||
|
||||
|
||||
@@ -361,8 +361,8 @@ _rl_get_char_len (const char *src, mbstate_t *ps)
|
||||
int mb_cur_max;
|
||||
|
||||
/* Look at no more than MB_CUR_MAX characters */
|
||||
l = (size_t)strlen (src);
|
||||
if (_rl_utf8locale && l > 0 && UTF8_SINGLEBYTE(*src))
|
||||
l = strlen (src);
|
||||
if (_rl_utf8locale && l >= 0 && UTF8_SINGLEBYTE(*src))
|
||||
tmp = (*src != 0) ? 1 : 0;
|
||||
else
|
||||
{
|
||||
|
||||
+11
-2
@@ -905,8 +905,17 @@ _rl_dispatch_subseq (register int key, Keymap map, int got_subseq)
|
||||
{
|
||||
/* Special case rl_do_lowercase_version (). */
|
||||
if (func == rl_do_lowercase_version)
|
||||
/* Should we do anything special if key == ANYOTHERKEY? */
|
||||
return (_rl_dispatch (_rl_to_lower ((unsigned char)key), map));
|
||||
{
|
||||
/* Should we do anything special if key == ANYOTHERKEY? */
|
||||
newkey = _rl_to_lower ((unsigned char)key);
|
||||
if (newkey != key)
|
||||
return (_rl_dispatch (newkey, map));
|
||||
else
|
||||
{
|
||||
rl_ding (); /* gentle failure */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
rl_executing_keymap = map;
|
||||
rl_executing_key = key;
|
||||
|
||||
@@ -853,7 +853,11 @@ _rl_insert_char (int count, int c)
|
||||
rl_insert_text (string);
|
||||
xfree (string);
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
return (pending_bytes_length != 0);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (count > TEXT_COUNT_MAX)
|
||||
@@ -1112,6 +1116,8 @@ rl_quoted_insert (int count, int key)
|
||||
r = _rl_insert_next (1);
|
||||
while (r == 0 && ++count < 0);
|
||||
}
|
||||
else
|
||||
r = _rl_insert_next (count);
|
||||
|
||||
if (r == 1)
|
||||
_rl_insert_char (0, 0); /* insert partial multibyte character */
|
||||
|
||||
@@ -112,9 +112,9 @@ set_default_locale_vars (void)
|
||||
if (val == 0 && lc_all && *lc_all)
|
||||
{
|
||||
setlocale (LC_CTYPE, lc_all);
|
||||
locale_setblanks ();
|
||||
locale_mb_cur_max = MB_CUR_MAX;
|
||||
locale_utf8locale = locale_isutf8 (lc_all);
|
||||
locale_setblanks ();
|
||||
|
||||
# if defined (HANDLE_MULTIBYTE)
|
||||
locale_shiftstates = mblen ((char *)NULL, 0);
|
||||
@@ -219,11 +219,11 @@ set_locale_var (const char *var, const char *value)
|
||||
else
|
||||
internal_warning(_("setlocale: LC_ALL: cannot change locale (%s): %s"), lc_all, strerror (errno));
|
||||
}
|
||||
locale_setblanks ();
|
||||
locale_mb_cur_max = MB_CUR_MAX;
|
||||
/* if LC_ALL == "", reset_locale_vars has already called this */
|
||||
if (*lc_all && x)
|
||||
locale_utf8locale = locale_isutf8 (lc_all);
|
||||
locale_setblanks ();
|
||||
# if defined (HANDLE_MULTIBYTE)
|
||||
locale_shiftstates = mblen ((char *)NULL, 0);
|
||||
# else
|
||||
@@ -243,11 +243,11 @@ set_locale_var (const char *var, const char *value)
|
||||
if (lc_all == 0 || *lc_all == '\0')
|
||||
{
|
||||
x = setlocale (LC_CTYPE, get_locale_var ("LC_CTYPE"));
|
||||
locale_setblanks ();
|
||||
locale_mb_cur_max = MB_CUR_MAX;
|
||||
/* if setlocale() returns NULL, the locale is not changed */
|
||||
if (x)
|
||||
locale_utf8locale = locale_isutf8 (x);
|
||||
locale_setblanks ();
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
locale_shiftstates = mblen ((char *)NULL, 0);
|
||||
#else
|
||||
@@ -396,10 +396,10 @@ reset_locale_vars (void)
|
||||
retval = 0;
|
||||
# endif
|
||||
|
||||
locale_setblanks ();
|
||||
locale_mb_cur_max = MB_CUR_MAX;
|
||||
if (x)
|
||||
locale_utf8locale = locale_isutf8 (x);
|
||||
locale_setblanks ();
|
||||
# if defined (HANDLE_MULTIBYTE)
|
||||
locale_shiftstates = mblen ((char *)NULL, 0);
|
||||
# else
|
||||
@@ -575,6 +575,12 @@ locale_expand (const char *string, int start, int end, int lineno, size_t *lenp)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Is character C in the [:blank:] class in the current locale? Work around
|
||||
systems like macOS that treat some characters 0x80-0xff as blanks even in
|
||||
a UTF-8 locale where they are multibyte characters. */
|
||||
#define locale_isblank(c) \
|
||||
((locale_utf8locale == 0 || ((c) & 0x80) == 0) && isblank ((unsigned char)(c)))
|
||||
|
||||
/* Set every character in the <blank> character class to be a shell break
|
||||
character for the lexical analyzer when the locale changes. */
|
||||
static void
|
||||
@@ -584,7 +590,7 @@ locale_setblanks (void)
|
||||
|
||||
for (x = 0; x < sh_syntabsiz; x++)
|
||||
{
|
||||
if (isblank ((unsigned char)x))
|
||||
if (locale_isblank (x))
|
||||
sh_syntaxtab[x] |= CSHBRK|CBLANK;
|
||||
else if (member (x, shell_break_chars))
|
||||
{
|
||||
|
||||
@@ -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-05-01 16:11-0700\n"
|
||||
"PO-Revision-Date: 2023-05-23 19:54-0700\n"
|
||||
"Last-Translator: Božidar Putanec <bozidarp@yahoo.com>\n"
|
||||
"Language-Team: Croatian <lokalizacija@linux.hr>\n"
|
||||
"Language: hr\n"
|
||||
@@ -4064,7 +4064,7 @@ msgstr ""
|
||||
"\n"
|
||||
" Opcije:\n"
|
||||
" -f navedena IMENA se odnose samo na funkcije\n"
|
||||
" -n ukloni izvezeni atribut iz svakog IMENA \n"
|
||||
" -n ukloni izvezeni atribut iz svakog IMENA\n"
|
||||
" -p izlista popis svih izvezenih varijabli i funkcija\n"
|
||||
"\n"
|
||||
" Argument „--“ spriječi daljnje procesiranje opcija.\n"
|
||||
|
||||
Reference in New Issue
Block a user