diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 7f87832d..1c564e2f 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -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 + +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 + +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 + +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 diff --git a/lib/readline/display.c b/lib/readline/display.c index 5d34b49d..e38bfce7 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -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'; diff --git a/lib/readline/isearch.c b/lib/readline/isearch.c index 33f67d3d..df23f15a 100644 --- a/lib/readline/isearch.c +++ b/lib/readline/isearch.c @@ -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; diff --git a/lib/readline/macro.c b/lib/readline/macro.c index 92cc55c3..231a24bc 100644 --- a/lib/readline/macro.c +++ b/lib/readline/macro.c @@ -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); diff --git a/lib/readline/text.c b/lib/readline/text.c index b16bc9bf..91c3f330 100644 --- a/lib/readline/text.c +++ b/lib/readline/text.c @@ -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 (); diff --git a/lib/readline/vi_mode.c b/lib/readline/vi_mode.c index c3b555d1..3a033bab 100644 --- a/lib/readline/vi_mode.c +++ b/lib/readline/vi_mode.c @@ -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; } diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index c8bef8dd..0b063810 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -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 diff --git a/tests/exec1.sub b/tests/exec1.sub old mode 100755 new mode 100644 diff --git a/tests/new-exp.right b/tests/new-exp.right index 2d243fe4..cb1faa8b 100644 --- a/tests/new-exp.right +++ b/tests/new-exp.right @@ -749,6 +749,16 @@ abc defg abc defg & defg & defg +abcdefg +abcdefg +&defg +&defg +\abcdefg +&defg +&defg +\&defg +\&defg +\\&defg argv[1] = argv[1] = diff --git a/tests/new-exp16.sub b/tests/new-exp16.sub index f871f708..34ad8a7b 100644 --- a/tests/new-exp16.sub +++ b/tests/new-exp16.sub @@ -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"} diff --git a/tests/trap1.sub b/tests/trap1.sub old mode 100755 new mode 100644 diff --git a/tests/trap2.sub b/tests/trap2.sub old mode 100755 new mode 100644 diff --git a/tests/trap2a.sub b/tests/trap2a.sub old mode 100755 new mode 100644