asan fuzzing fixes; fix incomplete multibyte chars in history expansion; new nosort GLOBSORT value

This commit is contained in:
Chet Ramey
2023-05-01 09:59:55 -04:00
parent 7aae19bfe4
commit 23935dbe85
9 changed files with 95 additions and 41 deletions
+30 -1
View File
@@ -6040,7 +6040,8 @@ builtins/complete.def
variable in which to store the completions.
- compgen_builtin: if the -V option is supplied, store the possible
completions into VARNAME instead of printing them on stdout. From a
patch from Grisha Levit <grishalevit@gmail.com>
patch from Grisha Levit <grishalevit@gmail.com>, idea originally
from konsolebox <konsolebox@gmail.com> back in 2/2022
doc/bash.1,lib/readline/doc/rluser.texi
- compgen: document new -V option
@@ -6150,6 +6151,7 @@ lib/readline/display.c
- _rl_move_cursor_relative: when checking to see whether data is within
the invisible line, make sure to stay within the invisible line
line break boundaries
From a report by minipython <599192367@qq.com>
lib/readline/search.c
- dispose_saved_search_line: new function, either unsave the saved
@@ -6163,3 +6165,30 @@ lib/readline/search.c
- noninc_dosearch,rl_history_search_internal: call dispose_saved_search_line
before calling make_history_line_current
lib/readline/misc.c
- _rl_start_using_history: free the undo list associated with
_rl_saved_line_for_history, if one exists. Have to watch out for
this causing pointer aliasing problems, maybe add a call to
_hs_search_history_data()
4/28
----
pathexp.c
- sh_globsort: a sort specifier of `nosort' disables sorting completely
doc/bash.1,doc/bashref.texi
- GLOBSORT: document `nosort' sort specifier
bashline.c
- attempt_shell_completion: attempt completion with the empty command
for a null command word on a line with only whitespace following any
optional assignment statements
- attempt_shell_completion: make sure that the start of the command
word is not after rl_point before calling the programmable completion
for the initial word.
From a report by Grisha Levit <grishalevit@gmail.com>
lib/readline/histexpand.c
- history_expand: don't read past the end of the string if it ends with
an incomplete multibyte character
From a report by Grisha Levit <grishalevit@gmail.com>
+11 -2
View File
@@ -1695,10 +1695,12 @@ attempt_shell_completion (const char *text, int start, int end)
end == index of where word to be completed ends
if (s == start) we are doing command word completion for sure
if (e1 == end) we are at the end of the command name and completing it */
if (start == 0 && end == 0 && e != 0 && text[0] == '\0') /* beginning of non-empty line */
if (start == 0 && end == 0 && e != 0 && e1 < rl_end && text[0] == '\0') /* beginning of non-empty line */
foundcs = 0;
else if (start == end && start == s1 && e != 0 && e1 > end) /* beginning of command name, leading whitespace */
foundcs = 0;
else if (start == 0 && start == end && start < s1 && e != 0 && e1 > end && text[0] == '\0' && have_progcomps) /* no command name, leading whitespace only */
prog_complete_matches = programmable_completions (EMPTYCMD, text, s, e, &foundcs);
else if (e == 0 && e == s && text[0] == '\0' && have_progcomps) /* beginning of empty line */
prog_complete_matches = programmable_completions (EMPTYCMD, text, s, e, &foundcs);
else if (start == end && text[0] == '\0' && s1 > start && whitespace (rl_line_buffer[start]))
@@ -1742,7 +1744,14 @@ attempt_shell_completion (const char *text, int start, int end)
/* If we have defined a compspec for the initial (command) word, call
it and process the results like any other programmable completion. */
if (in_command_position && have_progcomps && foundcs == 0 && iw_compspec)
prog_complete_matches = programmable_completions (INITIALWORD, text, s, e, &foundcs);
{
/* Do some sanity checking on S and E. Room for more here. */
if (s > rl_point)
s = rl_point;
if (e > rl_end)
e = rl_end;
prog_complete_matches = programmable_completions (INITIALWORD, text, s, e, &foundcs);
}
FREE (n);
/* XXX - if we found a COMPSPEC for the command, just return whatever
+3 -1
View File
@@ -2267,8 +2267,10 @@ and
.IR blocks ,
which sort the files on name, file size, modification time, access time,
inode change time, and number of blocks, respectively.
For example, a value of \fB\-mtime\fP sorts the results in descending
For example, a value of \fI\-mtime\fP sorts the results in descending
order by modification time (newest first).
A sort specifier of \fInosort\fP disables sorting completely; the results
are returned in the order they are read from the file system,.
If the sort specifier is missing, it defaults to \fIname\fP,
so a value of \fI+\fP is equivalent to the null string,
and a value of \fI-\fP sorts by name in descending order.
+3
View File
@@ -6494,6 +6494,9 @@ inode change time, and number of blocks, respectively.
For example, a value of @code{-mtime} sorts the results in descending
order by modification time (newest first).
A sort specifier of @samp{nosort} disables sorting completely; the results
are returned in the order they are read from the file system,.
If the sort specifier is missing, it defaults to @var{name},
so a value of @samp{+} is equivalent to the null string,
and a value of @samp{-} sorts by name in descending order.
+1 -1
View File
@@ -1121,7 +1121,7 @@ history_expand (const char *hstring, char **output)
c = tchar;
memset (mb, 0, sizeof (mb));
for (k = 0; k < MB_LEN_MAX; k++)
for (k = 0; k < MB_LEN_MAX && i < l; k++)
{
mb[k] = (char)c;
memset (&ps, 0, sizeof (mbstate_t));
+4
View File
@@ -307,6 +307,10 @@ void
_rl_start_using_history (void)
{
using_history ();
#if 1
if (_rl_saved_line_for_history && _rl_saved_line_for_history->data)
_rl_free_undo_list ((UNDO_LIST *)_rl_saved_line_for_history->data);
#endif
_rl_free_saved_history_line ();
_rl_history_search_pos = -99; /* some random invalid history position */
}
+3 -1
View File
@@ -983,6 +983,9 @@ rl_insert (int count, int c)
break;
}
/* If we didn't insert n and there are pending bytes, we need to insert
them if _rl_insert_char didn't do that on its own. */
if (n != (unsigned short)-2) /* -2 = sentinel value for having inserted N */
{
/* setting rl_pending_input inhibits setting rl_last_func so we do it
@@ -992,7 +995,6 @@ rl_insert (int count, int c)
rl_executing_keyseq[rl_key_sequence_length = 0] = '\0';
r = rl_execute_next (n);
}
return r;
}
+31 -27
View File
@@ -647,15 +647,16 @@ setup_ignore_patterns (struct ignorevar *ivp)
/* Functions to handle sorting glob results in different ways depending on
the value of the GLOBSORT variable. */
static int glob_sorttype = STAT_NONE;
static int glob_sorttype = SORT_NONE;
static STRING_INT_ALIST sorttypes[] = {
{ "name", STAT_NAME },
{ "size", STAT_SIZE },
{ "mtime", STAT_MTIME },
{ "atime", STAT_ATIME },
{ "ctime", STAT_CTIME },
{ "blocks", STAT_BLOCKS },
{ "name", SORT_NAME },
{ "size", SORT_SIZE },
{ "mtime", SORT_MTIME },
{ "atime", SORT_ATIME },
{ "ctime", SORT_CTIME },
{ "blocks", SORT_BLOCKS },
{ "nosort", SORT_NOSORT },
{ (char *)NULL, -1 }
};
@@ -682,7 +683,7 @@ glob_findtype (char *t)
int type;
type = find_string_in_alist (t, sorttypes, 0);
return (type == -1 ? STAT_NONE : type);
return (type == -1 ? SORT_NONE : type);
}
void
@@ -691,7 +692,7 @@ setup_globsort (const char *varname)
char *val;
int r, t;
glob_sorttype = STAT_NONE;
glob_sorttype = SORT_NONE;
val = get_string_value (varname);
if (val == 0 || *val == 0)
return;
@@ -703,7 +704,7 @@ setup_globsort (const char *varname)
val++; /* allow leading `+' but ignore it */
else if (*val == '-')
{
r = STAT_REVERSE; /* leading `-' reverses sort order */
r = SORT_REVERSE; /* leading `-' reverses sort order */
val++;
}
@@ -711,25 +712,25 @@ setup_globsort (const char *varname)
{
/* A bare `+' means the default sort by name in ascending order; a bare
`-' means to sort by name in descending order. */
glob_sorttype = STAT_NAME | r;
glob_sorttype = SORT_NAME | r;
return;
}
t = glob_findtype (val);
/* any other value is equivalent to the historical behavior */
glob_sorttype = (t == STAT_NONE) ? t : t | r;
glob_sorttype = (t == SORT_NONE) ? t : t | r;
}
static int
globsort_namecmp (char **s1, char **s2)
{
return ((glob_sorttype < STAT_REVERSE) ? strvec_posixcmp (s1, s2) : strvec_posixcmp (s2, s1));
return ((glob_sorttype < SORT_REVERSE) ? strvec_posixcmp (s1, s2) : strvec_posixcmp (s2, s1));
}
static int
globsort_sizecmp (struct globsort_t *g1, struct globsort_t *g2)
{
return ((glob_sorttype < STAT_REVERSE) ? g1->st.size - g2->st.size : g2->st.size - g1->st.size);
return ((glob_sorttype < SORT_REVERSE) ? g1->st.size - g2->st.size : g2->st.size - g1->st.size);
}
static int
@@ -738,13 +739,13 @@ globsort_timecmp (struct globsort_t *g1, struct globsort_t *g2)
int t;
struct timespec t1, t2;
t = (glob_sorttype < STAT_REVERSE) ? glob_sorttype : glob_sorttype - STAT_REVERSE;
if (t == STAT_MTIME)
t = (glob_sorttype < SORT_REVERSE) ? glob_sorttype : glob_sorttype - SORT_REVERSE;
if (t == SORT_MTIME)
{
t1 = g1->st.mtime;
t2 = g2->st.mtime;
}
else if (t == STAT_ATIME)
else if (t == SORT_ATIME)
{
t1 = g1->st.atime;
t2 = g2->st.atime;
@@ -755,13 +756,13 @@ globsort_timecmp (struct globsort_t *g1, struct globsort_t *g2)
t2 = g2->st.ctime;
}
return ((glob_sorttype < STAT_REVERSE) ? timespec_cmp (t1, t2) : timespec_cmp (t2, t1));
return ((glob_sorttype < SORT_REVERSE) ? timespec_cmp (t1, t2) : timespec_cmp (t2, t1));
}
static int
globsort_blockscmp (struct globsort_t *g1, struct globsort_t *g2)
{
return ((glob_sorttype < STAT_REVERSE) ? g1->st.blocks - g2->st.blocks : g2->st.blocks - g1->st.blocks);
return ((glob_sorttype < SORT_REVERSE) ? g1->st.blocks - g2->st.blocks : g2->st.blocks - g1->st.blocks);
}
static struct globsort_t *
@@ -803,19 +804,19 @@ globsort_sortarray (struct globsort_t *garray, size_t len)
int t;
QSFUNC *sortfunc;
t = (glob_sorttype < STAT_REVERSE) ? glob_sorttype : glob_sorttype - STAT_REVERSE;
t = (glob_sorttype < SORT_REVERSE) ? glob_sorttype : glob_sorttype - SORT_REVERSE;
switch (t)
{
case STAT_SIZE:
case SORT_SIZE:
sortfunc = (QSFUNC *)globsort_sizecmp;
break;
case STAT_ATIME:
case STAT_MTIME:
case STAT_CTIME:
case SORT_ATIME:
case SORT_MTIME:
case SORT_CTIME:
sortfunc = (QSFUNC *)globsort_timecmp;
break;
case STAT_BLOCKS:
case SORT_BLOCKS:
sortfunc = (QSFUNC *)globsort_blockscmp;
break;
default:
@@ -832,9 +833,12 @@ sh_sortglob (char **results)
size_t rlen;
struct globsort_t *garray;
if (glob_sorttype == STAT_NONE || glob_sorttype == STAT_NAME)
if (glob_sorttype == SORT_NOSORT || glob_sorttype == (SORT_NOSORT|SORT_REVERSE))
return;
if (glob_sorttype == SORT_NONE || glob_sorttype == SORT_NAME)
globsort_sortbyname (results); /* posix sort */
else if (glob_sorttype == (STAT_NAME|STAT_REVERSE))
else if (glob_sorttype == (SORT_NAME|SORT_REVERSE))
globsort_sortbyname (results); /* posix sort reverse order */
else
{
+9 -8
View File
@@ -105,15 +105,16 @@ extern int should_ignore_glob_matches (void);
extern void ignore_glob_matches (char **);
/* Definitions for glob sorting */
#define STAT_NONE 0
#define STAT_NAME 1
#define STAT_SIZE 2
#define STAT_MTIME 3
#define STAT_ATIME 4
#define STAT_CTIME 5
#define STAT_BLOCKS 6
#define SORT_NONE 0
#define SORT_NAME 1
#define SORT_SIZE 2
#define SORT_MTIME 3
#define SORT_ATIME 4
#define SORT_CTIME 5
#define SORT_BLOCKS 6
#define SORT_NOSORT 7
#define STAT_REVERSE 128
#define SORT_REVERSE 128
extern void setup_globsort (const char *);