On Mon, Mar 20, 2023 at 4:59 PM Chet Ramey <chet.ra...@case.edu> wrote: > Thanks, it's an easy fix to preserve the newline here.
FWIW even with the latest fixes, this kind of nesting in a history entry still triggers ASAN: bash --norc -in <<<$'${_+$(\n \cP\en ' ERROR: AddressSanitizer: heap-buffer-overflow READ of size 1 at 0x000105c0c2cf thread T0 #0 bash_add_history bashhist.c:898 #1 maybe_add_history bashhist.c:759 #2 pre_process_line bashhist.c:628 #3 shell_getc parse.y:2501 #4 read_token parse.y:3425 #5 yylex parse.y:2915 #6 yyparse y.tab.c:1869 #7 parse_comsub parse.y:4306 #8 parse_matched_pair parse.y:3973 #9 read_token_word parse.y:5172 #10 read_token parse.y:3621 #11 yylex parse.y:2915 #12 yyparse y.tab.c:1869 #13 parse_command eval.c:345 #14 read_command eval.c:389 #15 reader_loop eval.c:139 #16 main shell.c:821 Avoided by: diff --git a/bashhist.c b/bashhist.c index 21c77058..b48306c2 100644 --- a/bashhist.c +++ b/bashhist.c @@ -895,7 +895,7 @@ bash_add_history (char *line) newline, since that is what happens when the line is parsed. */ curlen = strlen (current->line); - if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' && + if (curlen && dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' && (curlen < 2 || current->line[curlen - 2] != '\\')) { current->line[curlen - 1] = '\0'; ---- bash --norc -in <<<$'${_+$(\n\e.' ERROR: AddressSanitizer: heap-buffer-overflow READ of size 1 at 0x00010870c517 thread T0 #0 history_tokenize_word histexpand.c:1561 #1 history_tokenize_internal histexpand.c:1660 #2 history_tokenize histexpand.c:1693 #3 history_arg_extract histexpand.c:1435 #4 rl_yank_nth_arg_internal kill.c:628 #5 rl_yank_last_arg kill.c:698 #6 _rl_dispatch_subseq readline.c:922 Avoided by: diff --git a/lib/readline/histexpand.c b/lib/readline/histexpand.c index d21240bf..8a147e40 100644 --- a/lib/readline/histexpand.c +++ b/lib/readline/histexpand.c @@ -1603,6 +1603,8 @@ get_word: delimopen = '('; delimiter = ')'; nestdelim = 1; + if (string[i] == 0) + break; continue; }