From 21c9990fbbf67790f42c836102f525f4f3c0d63e Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Mon, 17 Apr 2017 17:08:57 -0400 Subject: [PATCH] commit bash-20170414 snapshot --- CWRU/CWRU.chlog | 37 ++++++++++++++++++++++++++++++++++ Makefile.in | 22 ++++++++++++++++---- builtins/Makefile.in | 2 +- builtins/fc.def | 2 +- builtins/mapfile.def | 2 +- builtins/read.def | 24 +++++++++++----------- builtins/source.def | 2 +- eval.c | 9 +++++---- execute_cmd.c | 2 +- lib/sh/Makefile.in | 4 ++-- lib/tilde/Makefile.in | 2 +- parse.y | 47 +++++++++++++++++++++++++++++++++++-------- subst.c | 4 ++-- support/Makefile.in | 3 +-- tests/RUN-ONE-TEST | 2 +- tests/dollar.right | 2 +- 16 files changed, 124 insertions(+), 42 deletions(-) diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index ba347b30..68e9174a 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -13664,3 +13664,40 @@ execute_cmd.c - execute_intern_function: if the function name contains CTLESC, run it through dequote_escapes just in case it got CTLESC quoting CTLESC or CTLNUL from the parser + + 4/11 + ---- +eval.c + - reader_loop: make sure PS0 is expanded and displayed before + incrementing the command number + +parse.y + - prompt_history_number: function to make history number as reported + by \!, or posix mode !!, be the same index that the (possibly multi- + line) command will be stored with. The history library increments + history_offset as soon as a new line is entered, and it's up to the + history code to store the second and subsequent lines of a command + in the same history entry. If we are expanding PS0 or PS4, or + a ${var@P} expansion, we're already past the history entry no + matter what. Inspired by patch from Grisha Levit + + - decode_prompt_string: call prompt_history_number + - decode_prompt_string: if expanding PS4 or ${var@P}, make the + command number the same as reported by PS0/PS1/PS2 + + 4/12 + ---- +support/Makefile.in + - clean: remove man2html.o as part of this production instead of + waiting until `distclean'. Reported by chrlis + +subst.c + - string_list_pos_params: if we are expanding $* in a context where + IFS is null and expand_no_split_dollar_star is set (no word + splitting), use string_list_dollar_star to force the positional + parameters to be joined without first separating them into a list + and attempting to join them later. Fixes problem with constructs + like ${var=${*:1}}, pointed out by Grisha Levit + . This undoes change to @Q from 4/7, so + list_transform change reverted + diff --git a/Makefile.in b/Makefile.in index 8cd28832..3e52403b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# Makefile for bash-4.4, version 4.20 +# Makefile for bash-4.4, version 4.22 # # Copyright (C) 1996-2015 Free Software Foundation, Inc. @@ -77,6 +77,7 @@ AR = @AR@ ARFLAGS = @ARFLAGS@ RANLIB = @RANLIB@ SIZE = @SIZE@ +STRIP = strip INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -147,14 +148,17 @@ SYSTEM_FLAGS = -DPROGRAM='"$(Program)"' -DCONF_HOSTTYPE='"$(Machine)"' -DCONF_OS BASE_CCFLAGS = $(SYSTEM_FLAGS) $(LOCAL_DEFS) \ $(DEFS) $(LOCAL_CFLAGS) $(INCLUDES) -CCFLAGS = $(BASE_CCFLAGS) ${PROFILE_FLAGS} $(CPPFLAGS) $(CFLAGS) +CCFLAGS = $(ASAN_CFLAGS) $(BASE_CCFLAGS) ${PROFILE_FLAGS} $(CPPFLAGS) $(CFLAGS) CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) BASE_LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS) -LDFLAGS = ${BASE_LDFLAGS} ${PROFILE_FLAGS} ${STATIC_LD} +LDFLAGS = ${ASAN_LDFLAGS} ${BASE_LDFLAGS} ${PROFILE_FLAGS} ${STATIC_LD} LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ $(LOCAL_LDFLAGS) $(CFLAGS_FOR_BUILD) +ASAN_XCFLAGS = -fsanitize=address -fno-omit-frame-pointer +ASAN_XLDFLAGS = -fsanitize=address + INCLUDES = -I. @RL_INCLUDE@ -I$(srcdir) -I$(BASHINCDIR) -I$(LIBSRC) $(INTL_INC) # Maybe add: -Wextra @@ -590,13 +594,23 @@ bashbug: $(SDIR)/bashbug.sh config.h Makefile $(VERSPROG) @chmod a+rx bashbug strip: $(Program) .made - strip $(Program) + $(STRIP) $(Program) ls -l $(Program) -$(SIZE) $(Program) lint: ${MAKE} ${MFLAGS} CFLAGS='${GCC_LINT_FLAGS}' .made +asan: + ${MAKE} ${MFLAGS} ASAN_CFLAGS='${ASAN_XCFLAGS}' ASAN_LDFLAGS='${ASAN_XLDFLAGS}' .made + +# have to make this separate because making tests depend on $(PROGRAM) +asan-tests: asan $(TESTS_SUPPORT) + @-test -d tests || mkdir tests + @cp $(TESTS_SUPPORT) tests + @( cd $(srcdir)/tests && \ + PATH=$(BUILD_DIR)/tests:$$PATH THIS_SH=$(THIS_SH) $(SHELL) ${TESTSCRIPT} ) + version.h: $(SOURCES) config.h Makefile patchlevel.h $(SHELL) $(SUPPORT_SRC)mkversion.sh -b -S ${topdir} -s $(RELSTATUS) -d $(Version) -o newversion.h \ && mv newversion.h version.h diff --git a/builtins/Makefile.in b/builtins/Makefile.in index c6485ede..d86a69b5 100644 --- a/builtins/Makefile.in +++ b/builtins/Makefile.in @@ -94,7 +94,7 @@ INCLUDES = -I. -I.. @RL_INCLUDE@ -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib -I$ BASE_CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) \ ${INCLUDES} $(LOCAL_CFLAGS) -CCFLAGS = $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS) +CCFLAGS = ${ASAN_CFLAGS} $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS) CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) diff --git a/builtins/fc.def b/builtins/fc.def index 826fabe6..da0f0bcb 100644 --- a/builtins/fc.def +++ b/builtins/fc.def @@ -459,7 +459,7 @@ fc_builtin (list) /* Turn on the `v' flag while fc_execute_file runs so the commands will be echoed as they are read by the parser. */ begin_unwind_frame ("fc builtin"); - add_unwind_protect ((Function *)xfree, fn); + add_unwind_protect (xfree, fn); add_unwind_protect (unlink, fn); add_unwind_protect (set_verbose_flag, (char *)NULL); echo_input_at_read = 1; diff --git a/builtins/mapfile.def b/builtins/mapfile.def index d3bf56fc..0ac445bb 100644 --- a/builtins/mapfile.def +++ b/builtins/mapfile.def @@ -232,7 +232,7 @@ mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_n break; } - xfree (line); + free (line); if (unbuffered_read == 0) zsyncfd (fd); diff --git a/builtins/read.def b/builtins/read.def index f767a29c..e6db4393 100644 --- a/builtins/read.def +++ b/builtins/read.def @@ -541,7 +541,7 @@ read_builtin (list) { if (rlbuf && rlbuf[rlind] == '\0') { - xfree (rlbuf); + free (rlbuf); rlbuf = (char *)0; } if (rlbuf == 0) @@ -736,20 +736,20 @@ assign_vars: if (legal_identifier (arrayname) == 0) { sh_invalidid (arrayname); - xfree (input_string); + free (input_string); return (EXECUTION_FAILURE); } var = find_or_make_array_variable (arrayname, 1); if (var == 0) { - xfree (input_string); + free (input_string); return EXECUTION_FAILURE; /* readonly or noassign */ } if (assoc_p (var)) { builtin_error (_("%s: cannot convert associative to indexed array"), arrayname); - xfree (input_string); + free (input_string); return EXECUTION_FAILURE; /* existing associative array */ } else if (invisible_p (var)) @@ -766,7 +766,7 @@ assign_vars: assign_array_var_from_word_list (var, alist, 0); dispose_words (alist); } - xfree (input_string); + free (input_string); return (retval); } #endif /* ARRAY_VARS */ @@ -802,7 +802,7 @@ assign_vars: else VUNSETATTR (var, att_invisible); - xfree (input_string); + free (input_string); return (retval); } @@ -825,7 +825,7 @@ assign_vars: #endif { sh_invalidid (varname); - xfree (orig_input_string); + free (orig_input_string); return (EXECUTION_FAILURE); } @@ -843,7 +843,7 @@ assign_vars: { t1 = dequote_string (t); var = bind_read_variable (varname, t1); - xfree (t1); + free (t1); } else var = bind_read_variable (varname, t ? t : ""); @@ -857,7 +857,7 @@ assign_vars: FREE (t); if (var == 0) { - xfree (orig_input_string); + free (orig_input_string); return (EXECUTION_FAILURE); } @@ -873,7 +873,7 @@ assign_vars: #endif { sh_invalidid (list->word->word); - xfree (orig_input_string); + free (orig_input_string); return (EXECUTION_FAILURE); } @@ -904,7 +904,7 @@ assign_vars: { t = dequote_string (input_string); var = bind_read_variable (list->word->word, t); - xfree (t); + free (t); } else var = bind_read_variable (list->word->word, input_string ? input_string : ""); @@ -918,7 +918,7 @@ assign_vars: retval = EXECUTION_FAILURE; FREE (tofree); - xfree (orig_input_string); + free (orig_input_string); return (retval); } diff --git a/builtins/source.def b/builtins/source.def index 6abb337f..f5115eeb 100644 --- a/builtins/source.def +++ b/builtins/source.def @@ -166,7 +166,7 @@ source_builtin (list) } begin_unwind_frame ("source"); - add_unwind_protect ((Function *)xfree, filename); + add_unwind_protect (xfree, filename); if (list->next) { diff --git a/eval.c b/eval.c index 28a3bdc0..7992346a 100644 --- a/eval.c +++ b/eval.c @@ -148,10 +148,6 @@ reader_loop () else if (current_command = global_command) { global_command = (COMMAND *)NULL; - current_command_number++; - - executing = 1; - stdin_redir = 0; /* If the shell is interactive, expand and display $PS0 after reading a command (possibly a list or pipeline) and before executing it. */ @@ -168,6 +164,11 @@ reader_loop () free (ps0_string); } + current_command_number++; + + executing = 1; + stdin_redir = 0; + execute_command (current_command); exec_done: diff --git a/execute_cmd.c b/execute_cmd.c index 5822c87c..6a008684 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -4617,7 +4617,7 @@ execute_builtin (builtin, words, flags, subshell) if (error_trap) { set_error_trap (error_trap); - xfree (error_trap); + free (error_trap); } discard_unwind_frame ("eval_builtin"); } diff --git a/lib/sh/Makefile.in b/lib/sh/Makefile.in index 2ca921b3..9870dcd6 100644 --- a/lib/sh/Makefile.in +++ b/lib/sh/Makefile.in @@ -67,8 +67,8 @@ LOCAL_DEFS = @LOCAL_DEFS@ INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib -I$(BASHINCDIR) -I$(srcdir) $(INTL_INC) -CCFLAGS = ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) \ - $(CFLAGS) $(CPPFLAGS) +CCFLAGS = ${ASAN_CFLAGS} ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) \ + $(LOCAL_CFLAGS) $(CFLAGS) $(CPPFLAGS) GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \ -Wcast-align -Wstrict-prototypes -Wconversion \ diff --git a/lib/tilde/Makefile.in b/lib/tilde/Makefile.in index 7ca3b789..c21d3897 100644 --- a/lib/tilde/Makefile.in +++ b/lib/tilde/Makefile.in @@ -52,7 +52,7 @@ BASHINCDIR = ${topdir}/include INCLUDES = -I. -I../.. -I$(topdir) -I${BASHINCDIR} -I$(topdir)/lib -CCFLAGS = $(PROFILE_FLAGS) $(DEFS) $(LOCAL_DEFS) $(CPPFLAGS) \ +CCFLAGS = ${ASAN_CFLAGS} $(PROFILE_FLAGS) $(DEFS) $(LOCAL_DEFS) $(CPPFLAGS) \ ${INCLUDES} $(LOCAL_CFLAGS) $(CFLAGS) .c.o: diff --git a/parse.y b/parse.y index 5846ad32..fa25dca9 100644 --- a/parse.y +++ b/parse.y @@ -3564,7 +3564,7 @@ parse_matched_pair (qc, open, close, lenp, flags) { /* Translate $'...' here. */ ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen); - xfree (nestret); + free (nestret); /* If we're parsing a double-quoted brace expansion and we are not in a place where single quotes are treated specially, @@ -3594,7 +3594,7 @@ parse_matched_pair (qc, open, close, lenp, flags) { /* Locale expand $"..." here. */ ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen); - xfree (nestret); + free (nestret); nestret = sh_mkdoublequoted (ttrans, ttranslen, 0); free (ttrans); @@ -4190,7 +4190,7 @@ eof_error: { /* Translate $'...' here. */ ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen); - xfree (nestret); + free (nestret); if ((rflags & P_DQUOTE) == 0) { @@ -4209,7 +4209,7 @@ eof_error: { /* Locale expand $"..." here. */ ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen); - xfree (nestret); + free (nestret); nestret = sh_mkdoublequoted (ttrans, ttranslen, 0); free (ttrans); @@ -5497,6 +5497,31 @@ print_prompt () fflush (stderr); } +#if defined (HISTORY) + /* The history library increments the history offset as soon as it stores + the first line of a potentially multi-line command, so we compensate + here by returning one fewer when appropriate. */ +static int +prompt_history_number (pmt) + char *pmt; +{ + int ret; + + ret = history_number (); + if (ret == 1) + return ret; + + if (pmt == ps1_prompt) /* are we expanding $PS1? */ + return ret; + else if (pmt == ps2_prompt && command_oriented_history == 0) + return ret; /* not command oriented history */ + else if (pmt == ps2_prompt && command_oriented_history && current_command_first_line_saved) + return ret - 1; + else + return ret - 1; /* PS0, PS4, ${var@P}, PS2 other cases */ +} +#endif + /* Return a string which will be printed as a prompt. The string may contain special characters which are decoded as follows: @@ -5534,7 +5559,7 @@ decode_prompt_string (string) char *string; { WORD_LIST *list; - char *result, *t; + char *result, *t, *orig_string; struct dstack save_dstack; int last_exit_value, last_comsub_pid; #if defined (PROMPT_STRING_DECODE) @@ -5550,6 +5575,7 @@ decode_prompt_string (string) result = (char *)xmalloc (result_size = PROMPT_GROWTH); result[result_index = 0] = 0; temp = (char *)NULL; + orig_string = string; while (c = *string++) { @@ -5565,7 +5591,7 @@ decode_prompt_string (string) #if !defined (HISTORY) temp = savestring ("1"); #else /* HISTORY */ - temp = itos (history_number ()); + temp = itos (prompt_history_number (orig_string)); #endif /* HISTORY */ string--; /* add_string increments string again. */ goto add_string; @@ -5797,14 +5823,19 @@ decode_prompt_string (string) goto add_string; case '#': - temp = itos (current_command_number); + n = current_command_number; + /* If we have already incremented current_command_number (PS4, + ${var@P}), compensate */ + if (orig_string != ps0_prompt && orig_string != ps1_prompt && orig_string != ps2_prompt) + n--; + temp = itos (n); goto add_string; case '!': #if !defined (HISTORY) temp = savestring ("1"); #else /* HISTORY */ - temp = itos (history_number ()); + temp = itos (prompt_history_number (orig_string)); #endif /* HISTORY */ goto add_string; diff --git a/subst.c b/subst.c index ba957c27..12702654 100644 --- a/subst.c +++ b/subst.c @@ -2684,7 +2684,7 @@ string_list_pos_params (pchar, list, quoted) ret = string_list (tlist); } else if (pchar == '*' && quoted == 0 && ifs_is_null) /* XXX */ - ret = string_list_dollar_at (list, quoted, 0); /* Posix interp 888 */ + ret = expand_no_split_dollar_star ? string_list_dollar_star (list) : string_list_dollar_at (list, quoted, 0); /* Posix interp 888 */ else if (pchar == '*') { /* Even when unquoted, string_list_dollar_star does the right thing @@ -7306,7 +7306,7 @@ list_transform (xc, v, list, itype, quoted) qflags = quoted; /* If we are expanding in a context where word splitting will not be performed, treat as quoted. This changes how $* will be expanded. */ - if (xc != 'Q' && itype == '*' && expand_no_split_dollar_star && ifs_is_null) + if (itype == '*' && expand_no_split_dollar_star && ifs_is_null) qflags |= Q_DOUBLE_QUOTES; /* Posix interp 888 */ tword = string_list_pos_params (itype, l, qflags); diff --git a/support/Makefile.in b/support/Makefile.in index 9ed70215..f684a4d6 100644 --- a/support/Makefile.in +++ b/support/Makefile.in @@ -79,10 +79,9 @@ man2html$(EXEEXT): $(OBJ1) $(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) $(OBJ1) -o $@ ${LIBS_FOR_BUILD} clean: - $(RM) man2html$(EXEEXT) + $(RM) man2html$(EXEEXT) $(OBJ1) distclean maintainer-clean mostlyclean: clean - $(RM) $(OBJ1) $(RM) bash.pc man2html.o: man2html.c diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index 554f3d6e..58c375b7 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/dollar.right b/tests/dollar.right index 13c7c38d..37246ff4 100644 --- a/tests/dollar.right +++ b/tests/dollar.right @@ -559,4 +559,4 @@ argv[1] = <2> argv[2] = <> <12><12><12><12><12><12> <12><12><12><12><12><12> -<12><'1' '2'> +<12><'1''2'>