fix readline expand prompt issue; fixes for readline fuzzing issues

This commit is contained in:
Chet Ramey
2021-10-28 14:39:34 -04:00
parent c813e24652
commit 1984960023
13 changed files with 116 additions and 11 deletions
+33
View File
@@ -2334,3 +2334,36 @@ builtins/shopt.def
doc/{bash.1,bashref.texi}
- patsub_replacement: document new shopt option
10/26
-----
lib/readline/display.c
- expand_prompt: group runs of invisible characters at the right edge
of the screen with the previous physical characters when setting
local_prompt_newlines, since that's how update_line() expects to
get it. Fix from sparrowhawk996@gmail.com.
lib/readline/macro.c
- rl_end_kbd_macro: make sure current_macro_index is > 0 after
subtracting the key sequence length, clamp it to 0 before writing
the ending NULL. From a fuzzing report by
Tillmann Osswald <tosswald@ernw.de>
lib/readline/isearch.c
- _rl_isearch_dispatch: in the bracketed paste case, don't assume the
pasted text is null-terminated, so use memcpy instead of strcpy for
the length of the pasted text, then make sure the search string is
null-terminated. From a fuzzing report by
Tillmann Osswald <tosswald@ernw.de>
lib/readline/text.c
- rl_transpose_words: make sure to preserve the value of rl_end from
the beginning to the end of the function. From a fuzzing report by
Tillmann Osswald <tosswald@ernw.de>
lib/readline/vi_mode.c
- rl_vi_delete_to,rl_vi_change_to,rl_vi_yank_to: if we are redoing a
command (_rl_vi_redoing == 1), save the old _rl_vimvcxt, allocate a
new one, and restore the old one before returning. Prevents some
pointer aliasing problems. From a fuzzing report by
Tillmann Osswald <tosswald@ernw.de>
+15 -2
View File
@@ -356,7 +356,7 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
{
char *r, *ret, *p, *igstart, *nprompt, *ms;
int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
int mlen, newlines, newlines_guess, bound;
int mlen, newlines, newlines_guess, bound, can_add_invis;
int mb_cur_max;
/* We only expand the mode string for the last line of a multiline prompt
@@ -372,6 +372,7 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
else
nprompt = pmt;
can_add_invis = 0;
mb_cur_max = MB_CUR_MAX;
if (_rl_screenwidth == 0)
@@ -434,6 +435,11 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
else if (ignoring && *p == RL_PROMPT_END_IGNORE)
{
ignoring = 0;
/* If we have a run of invisible characters, adjust local_prompt_newlines
to add them, since update_line expects them to be counted before
wrapping the line. */
if (can_add_invis)
local_prompt_newlines[newlines] = r - ret;
if (p != (igstart + 1))
last = r - ret - 1;
continue;
@@ -498,10 +504,17 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
new = r - ret;
local_prompt_newlines[++newlines] = new;
}
/* What if a physical character of width >= 2 is split? There is
code that wraps before the physical screen width if the character
width would exceed it, but it needs to be checked against this
code and local_prompt_newlines[]. */
if (ignoring == 0)
can_add_invis = (physchars == bound);
}
}
if (rl < _rl_screenwidth)
if (rl <= _rl_screenwidth)
invfl = ninvis;
*r = '\0';
+4 -1
View File
@@ -273,6 +273,8 @@ _rl_isearch_fini (_rl_search_cxt *cxt)
last_isearch_string = cxt->search_string;
last_isearch_string_len = cxt->search_string_index;
cxt->search_string = 0;
cxt->search_string_size = 0;
cxt->search_string_index = 0;
if (cxt->last_found_line < cxt->save_line)
rl_get_previous_history (cxt->save_line - cxt->last_found_line, 0);
@@ -687,8 +689,9 @@ opcode_dispatch:
cxt->search_string_size += pastelen + 2;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
strcpy (cxt->search_string + cxt->search_string_index, paste);
memcpy (cxt->search_string + cxt->search_string_index, paste, pastelen);
cxt->search_string_index += pastelen;
cxt->search_string[cxt->search_string_index] = '\0';
free (paste);
break;
+2
View File
@@ -276,6 +276,8 @@ rl_end_kbd_macro (int count, int ignore)
}
current_macro_index -= rl_key_sequence_length;
if (current_macro_index < 0)
current_macro_index = 0;
current_macro[current_macro_index] = '\0';
RL_UNSETSTATE(RL_STATE_MACRODEF);
+6 -1
View File
@@ -96,6 +96,7 @@ rl_insert_text (const char *string)
for (i = rl_end; i >= rl_point; i--)
rl_line_buffer[i + l] = rl_line_buffer[i];
strncpy (rl_line_buffer + rl_point, string, l);
/* Remember how to undo this if we aren't undoing something. */
@@ -1539,7 +1540,10 @@ rl_transpose_words (int count, int key)
{
char *word1, *word2;
int w1_beg, w1_end, w2_beg, w2_end;
int orig_point = rl_point;
int orig_point, orig_end;
orig_point = rl_point;
orig_end = rl_end;
if (!count)
return 0;
@@ -1583,6 +1587,7 @@ rl_transpose_words (int count, int key)
/* This is exactly correct since the text before this point has not
changed in length. */
rl_point = w2_end;
rl_end = orig_end; /* just make sure */
/* I think that does it. */
rl_end_undo_group ();
+27 -6
View File
@@ -1372,8 +1372,15 @@ int
rl_vi_delete_to (int count, int key)
{
int c, r;
_rl_vimotion_cxt *savecxt;
if (_rl_vimvcxt)
savecxt = 0;
if (_rl_vi_redoing)
{
savecxt = _rl_vimvcxt;
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_DELETE, key);
}
else if (_rl_vimvcxt)
_rl_mvcxt_init (_rl_vimvcxt, VIM_DELETE, key);
else
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_DELETE, key);
@@ -1416,7 +1423,7 @@ rl_vi_delete_to (int count, int key)
}
_rl_mvcxt_dispose (_rl_vimvcxt);
_rl_vimvcxt = 0;
_rl_vimvcxt = savecxt;
return r;
}
@@ -1464,8 +1471,15 @@ int
rl_vi_change_to (int count, int key)
{
int c, r;
_rl_vimotion_cxt *savecxt;
if (_rl_vimvcxt)
savecxt = 0;
if (_rl_vi_redoing)
{
savecxt = _rl_vimvcxt;
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_CHANGE, key);
}
else if (_rl_vimvcxt)
_rl_mvcxt_init (_rl_vimvcxt, VIM_CHANGE, key);
else
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_CHANGE, key);
@@ -1507,7 +1521,7 @@ rl_vi_change_to (int count, int key)
}
_rl_mvcxt_dispose (_rl_vimvcxt);
_rl_vimvcxt = 0;
_rl_vimvcxt = savecxt;
return r;
}
@@ -1536,8 +1550,15 @@ int
rl_vi_yank_to (int count, int key)
{
int c, r;
_rl_vimotion_cxt *savecxt;
if (_rl_vimvcxt)
savecxt = 0;
if (_rl_vi_redoing)
{
savecxt = _rl_vimvcxt;
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_YANK, key);
}
else if (_rl_vimvcxt)
_rl_mvcxt_init (_rl_vimvcxt, VIM_YANK, key);
else
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_YANK, key);
@@ -1579,7 +1600,7 @@ rl_vi_yank_to (int count, int key)
}
_rl_mvcxt_dispose (_rl_vimvcxt);
_rl_vimvcxt = 0;
_rl_vimvcxt = savecxt;
return r;
}
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/bash/bash-current
BUILD_DIR=/usr/local/build/chet/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
Executable → Regular
View File
+10
View File
@@ -749,6 +749,16 @@ abc defg
abc defg
& defg
& defg
abcdefg
abcdefg
&defg
&defg
\abcdefg
&defg
&defg
\&defg
\&defg
\\&defg
argv[1] = </>
argv[1] = </>
+18
View File
@@ -27,6 +27,8 @@ echo "${string/abc/"$notthere"}"
echo ${string//?/\$\'&\' }
shopt -s patsub_replacement
echo ${string//?/\& }
echo "${string//?/\& }"
echo ${string//?/"& "}
@@ -43,3 +45,19 @@ echo ${string/abc/\& }
echo "${string/abc/\& }"
echo ${string/abc/"\& "}
echo ${string/abc/\\& }
rep='\\&'
echo "${string/abc/&}"
echo ${string/abc/\&}
echo "${string/abc/\\&}"
echo "${string/abc/"\\&"}"
echo ${string/abc/"$rep"}
shopt -u patsub_replacement
echo "${string/abc/&}"
echo ${string/abc/\&}
echo "${string/abc/\\&}"
echo "${string/abc/"\\&"}"
echo ${string/abc/"$rep"}
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
View File