mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-02 18:00:49 +02:00
fix readline expand prompt issue; fixes for readline fuzzing issues
This commit is contained in:
@@ -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
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -749,6 +749,16 @@ abc defg
|
||||
abc defg
|
||||
& defg
|
||||
& defg
|
||||
abcdefg
|
||||
abcdefg
|
||||
&defg
|
||||
&defg
|
||||
\abcdefg
|
||||
&defg
|
||||
&defg
|
||||
\&defg
|
||||
\&defg
|
||||
\\&defg
|
||||
argv[1] = </>
|
||||
argv[1] = </>
|
||||
|
||||
|
||||
@@ -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
Executable → Regular
Executable → Regular
Reference in New Issue
Block a user