From: Chet Ramey Date: Wed, 7 Dec 2011 14:30:34 +0000 (-0500) Subject: commit bash-20081016 snapshot X-Git-Tag: bash-4.3-alpha~262 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f2f9854dfd1a35d3b2b10d5b59b96e951a45c3fe;p=thirdparty%2Fbash.git commit bash-20081016 snapshot --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index c374509c3..db9c71e80 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -7033,3 +7033,26 @@ builtins/evalstring.c - don't short-circuit execution in parse_and_execute if we want to run an exit trap. Fixes bug reported by Steffen Kiess + + 10/18 + ----- +parse.y + - fix error production to only call YYACCEPT if the shell is currently + interactive and not in parse_and_execute (so parser errors in + things like eval will correctly set $?). Fixes bug reported by + marco-oweber@gmx.de + +execute_cmd.c + - make sure variable name errors in execute_for_command and non- + identifier function names in execute_intern_function set the + return status to EX_BADUSAGE (2), not EX_USAGE (258) + +parser.h + - new parser state, PST_REPARSE + +parse.y + - turn PST_REPARSE on in parse_string_to_word_list + - in parse_matched_pair, if parsing a single-quoted string and + PST_REPARSE is set, don't requote CTLESC or CTLNUL. Fixes bug with + compound array assignment using $'\x7f' reported by Antonio Macchi + diff --git a/CWRU/CWRU.chlog~ b/CWRU/CWRU.chlog~ index 9a02993e7..3e8628cdd 100644 --- a/CWRU/CWRU.chlog~ +++ b/CWRU/CWRU.chlog~ @@ -7026,3 +7026,29 @@ execute_cmd.c - fix errexit logic to not cause the shell to exit when a command in a pipeline fails. Fixes bug reported by Marcin Owsiany + + 10/14 + ----- +builtins/evalstring.c + - don't short-circuit execution in parse_and_execute if we want to + run an exit trap. Fixes bug reported by Steffen Kiess + + + 10/18 + ----- +parse.y + - fix error production to only call YYACCEPT if the shell is currently + interactive and not in parse_and_execute (so parser errors in + things like eval will correctly set $?). Fixes bug reported by + marco-oweber@gmx.de + +execute_cmd.c + - make sure variable name errors in execute_for_command and non- + identifier function names in execute_intern_function set the + return status to EX_BADUSAGE (2), not EX_USAGE (258) + +parser.h + - new parser state, PST_REPARSE + +parse.y + - turn PST_REPARSE on in parse_string_to_word_list diff --git a/MANIFEST b/MANIFEST index a08cc8226..0d2173f33 100644 --- a/MANIFEST +++ b/MANIFEST @@ -743,6 +743,7 @@ tests/array5.sub f tests/array6.sub f tests/array7.sub f tests/array8.sub f +tests/array9.sub f tests/array-at-star f tests/array2.right f tests/assoc.tests f diff --git a/MANIFEST~ b/MANIFEST~ index c957858c0..a08cc8226 100644 --- a/MANIFEST~ +++ b/MANIFEST~ @@ -616,6 +616,7 @@ examples/loadables/uname.c f examples/loadables/sync.c f examples/loadables/mkdir.c f examples/loadables/ln.c f +examples/loadables/mypid.c f examples/loadables/unlink.c f examples/loadables/perl/Makefile.in f examples/loadables/perl/README f @@ -696,6 +697,7 @@ examples/scripts/shprompt f examples/scripts/spin.bash f examples/scripts/timeout f examples/scripts/timeout2 f +examples/scripts/timeout3 f examples/scripts/vtree2 f examples/scripts/vtree3 f examples/scripts/vtree3a f diff --git a/execute_cmd.c b/execute_cmd.c index 71dbfccf6..b42271a79 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -2172,7 +2172,7 @@ execute_for_command (for_command) { if (posixly_correct && interactive_shell == 0) { - last_command_exit_value = EX_USAGE; + last_command_exit_value = EX_BADUSAGE; jump_to_top_level (ERREXIT); } return (EXECUTION_FAILURE); @@ -4698,7 +4698,7 @@ execute_intern_function (name, function) { if (posixly_correct && interactive_shell == 0) { - last_command_exit_value = EX_USAGE; + last_command_exit_value = EX_BADUSAGE; jump_to_top_level (ERREXIT); } return (EXECUTION_FAILURE); diff --git a/execute_cmd.c~ b/execute_cmd.c~ index a4d857c1e..7cf4aaadd 100644 --- a/execute_cmd.c~ +++ b/execute_cmd.c~ @@ -669,7 +669,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, add_unwind_protect ((Function *)dispose_redirects, exec_undo_list); ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0; -itrace("execute_command_internal: ignore_return = %d", ignore_return); + QUIT; switch (command->type) @@ -743,7 +743,6 @@ itrace("execute_command_internal: ignore_return = %d", ignore_return); if (was_error_trap && ignore_return == 0 && invert == 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE && exec_result != EXECUTION_SUCCESS) { last_command_exit_value = exec_result; -itrace("execute_command: simple_command: exit_immediately_on_error = %d pipe_in = %d pipe_out = %d running error trap", exit_immediately_on_error, pipe_in, pipe_out); run_error_trap (); } @@ -751,7 +750,6 @@ itrace("execute_command: simple_command: exit_immediately_on_error = %d pipe_in ((posixly_correct && interactive == 0 && special_builtin_failed) || (exit_immediately_on_error && pipe_in == NO_PIPE && pipe_out == NO_PIPE && exec_result != EXECUTION_SUCCESS))) { -itrace("execute_command: simple_command: exec_result = %d, exiting immediately", exec_result); last_command_exit_value = exec_result; run_pending_traps (); jump_to_top_level (ERREXIT); @@ -1930,7 +1928,6 @@ execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close) prev = pipe_in; cmd = command; -itrace("execute_pipeline: ignore_return = %d", ignore_return); while (cmd && cmd->type == cm_connection && cmd->value.Connection && cmd->value.Connection->connector == '|') { @@ -2175,7 +2172,7 @@ execute_for_command (for_command) { if (posixly_correct && interactive_shell == 0) { - last_command_exit_value = EX_USAGE; + last_command_exit_value = EX_BADUSAGE; jump_to_top_level (ERREXIT); } return (EXECUTION_FAILURE); @@ -3410,7 +3407,7 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close) /* Do this now, because execute_disk_command will do it anyway in the vast majority of cases. */ maybe_make_export_env (); -itrace("execute_simple_command: %s: dofork = 1", the_printed_command_except_trap); + /* Don't let a DEBUG trap overwrite the command string to be saved with the process/job associated with this child. */ if (make_child (savestring (the_printed_command_except_trap), async) == 0) @@ -3446,7 +3443,6 @@ itrace("execute_simple_command: %s: dofork = 1", the_printed_command_except_trap #endif command_line = (char *)NULL; /* don't free this. */ bind_lastarg ((char *)NULL); -itrace("execute_simple_command: parent: returning %d", result); return (result); } } @@ -4030,7 +4026,6 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var, ((subshell_environment & SUBSHELL_ASYNC) == 0 || pipe_out != NO_PIPE); #endif -itrace("execute_subshell_builtin_or_function:"); /* A subshell is neither a login shell nor interactive. */ login_shell = interactive = 0; diff --git a/parse.y b/parse.y index 740721f9b..df950cf07 100644 --- a/parse.y +++ b/parse.y @@ -115,7 +115,7 @@ extern int extended_glob; extern int eof_encountered; extern int no_line_editing, running_under_emacs; extern int current_command_number; -extern int sourcelevel; +extern int sourcelevel, parse_and_execute_level; extern int posixly_correct; extern int last_command_exit_value; extern char *shell_name, *current_host_name; @@ -392,7 +392,7 @@ inputunit: simple_list simple_list_terminator global_command = (COMMAND *)NULL; eof_encountered = 0; /* discard_parser_constructs (1); */ - if (interactive) + if (interactive && parse_and_execute_level == 0) { YYACCEPT; } @@ -3024,6 +3024,16 @@ parse_matched_pair (qc, open, close, lenp, flags) ret[retind++] = ch; continue; } + /* If we're reparsing the input (e.g., from parse_string_to_word_list), + we've already prepended CTLESC to single-quoted results of $'...'. + We may want to do this for other CTLESC-quoted characters in + reparse, too. */ + else if MBTEST((parser_state & PST_REPARSE) && open == '\'' && (ch == CTLESC || ch == CTLNUL)) + { + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = ch; + continue; + } else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */ { RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64); @@ -5341,7 +5351,7 @@ parse_string_to_word_list (s, flags, whom) wl = (WORD_LIST *)NULL; if (flags & 1) - parser_state |= PST_COMPASSIGN; + parser_state |= PST_COMPASSIGN|PST_REPARSE; while ((tok = read_token (READ)) != yacc_EOF) { @@ -5381,7 +5391,7 @@ parse_string_to_word_list (s, flags, whom) shell_input_line_terminator = orig_input_terminator; if (flags & 1) - parser_state &= ~PST_COMPASSIGN; + parser_state &= ~(PST_COMPASSIGN|PST_REPARSE); if (wl == &parse_string_error) { diff --git a/parse.y~ b/parse.y~ index 83446771c..df950cf07 100644 --- a/parse.y~ +++ b/parse.y~ @@ -1,22 +1,22 @@ -/* Yacc grammar for bash. */ +/* parse.y - Yacc grammar for bash. */ /* Copyright (C) 1989-2008 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. - Bash is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2, or (at your option) any later - version. + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - Bash is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with Bash; see the file LICENSE. If not, write to the Free Software - Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ %{ #include "config.h" @@ -115,7 +115,7 @@ extern int extended_glob; extern int eof_encountered; extern int no_line_editing, running_under_emacs; extern int current_command_number; -extern int sourcelevel; +extern int sourcelevel, parse_and_execute_level; extern int posixly_correct; extern int last_command_exit_value; extern char *shell_name, *current_host_name; @@ -392,7 +392,7 @@ inputunit: simple_list simple_list_terminator global_command = (COMMAND *)NULL; eof_encountered = 0; /* discard_parser_constructs (1); */ - if (interactive) + if (interactive && parse_and_execute_level == 0) { YYACCEPT; } @@ -3024,6 +3024,16 @@ parse_matched_pair (qc, open, close, lenp, flags) ret[retind++] = ch; continue; } + /* If we're reparsing the input (e.g., from parse_string_to_word_list), + we've already prepended CTLESC to single-quoted results of $'...'. + We may want to do this for other CTLESC-quoted characters in + reparse, too. */ + else if MBTEST((parser_state & PST_REPARSE) && open == '\'' && (ch == CTLESC || ch == CTLNUL)) + { + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = ch; + continue; + } else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */ { RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64); @@ -3058,9 +3068,10 @@ parse_matched_pair (qc, open, close, lenp, flags) tflags |= LEX_PASSNEXT; #if 0 - /* The big hammer. Single quotes aren't special in double quotes, even - double-quoted parameter expansions. XXX - do the same thing for - command substitution/arithmetic expansion? */ + /* The big hammer. Single quotes aren't special in double quotes. The + problem is that Posix says the single quotes are semi-special: + within a double-quoted ${...} construct "an even number of + unescaped double-quotes or single-quotes, if any, shall occur." */ if MBTEST(open == '{' && (flags & P_DQUOTE) && ch == '\'') /* } */ continue; #endif @@ -5340,7 +5351,7 @@ parse_string_to_word_list (s, flags, whom) wl = (WORD_LIST *)NULL; if (flags & 1) - parser_state |= PST_COMPASSIGN; + parser_state |= PST_COMPASSIGN|PST_REPARSE; while ((tok = read_token (READ)) != yacc_EOF) { @@ -5380,7 +5391,7 @@ parse_string_to_word_list (s, flags, whom) shell_input_line_terminator = orig_input_terminator; if (flags & 1) - parser_state &= ~PST_COMPASSIGN; + parser_state &= ~(PST_COMPASSIGN|PST_REPARSE); if (wl == &parse_string_error) { diff --git a/parser.h b/parser.h index 826322ce4..4d958e917 100644 --- a/parser.h +++ b/parser.h @@ -44,6 +44,7 @@ #define PST_EOFTOKEN 0x08000 /* yylex checks against shell_eof_token */ #define PST_REGEXP 0x10000 /* parsing an ERE/BRE as a single word */ #define PST_HEREDOC 0x20000 /* reading body of here-document */ +#define PST_REPARSE 0x40000 /* re-parsing in parse_string_to_word_list */ /* Definition of the delimiter stack. Needed by parse.y and bashhist.c. */ struct dstack { diff --git a/parser.h~ b/parser.h~ index d9937c38a..826322ce4 100644 --- a/parser.h~ +++ b/parser.h~ @@ -1,23 +1,23 @@ /* parser.h -- Everything you wanted to know about the parser, but were afraid to ask. */ -/* Copyright (C) 1995 Free Software Foundation, Inc. +/* Copyright (C) 1995, 2008 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. - Bash is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2, or (at your option) any later - version. + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - Bash is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with Bash; see the file COPYING. If not, write to the Free Software - Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ #if !defined (_PARSER_H_) # define _PARSER_H_ @@ -43,6 +43,7 @@ #define PST_ASSIGNOK 0x04000 /* assignment statement ok in this context */ #define PST_EOFTOKEN 0x08000 /* yylex checks against shell_eof_token */ #define PST_REGEXP 0x10000 /* parsing an ERE/BRE as a single word */ +#define PST_HEREDOC 0x20000 /* reading body of here-document */ /* Definition of the delimiter stack. Needed by parse.y and bashhist.c. */ struct dstack { diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index 3efcf32d6..72ec06a2c 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -1,4 +1,4 @@ -BUILD_DIR=/usr/local/build/chet/bash/bash-current +BUILD_DIR=/usr/local/build/bash/bash-current THIS_SH=$BUILD_DIR/bash PATH=$PATH:$BUILD_DIR diff --git a/tests/array.right b/tests/array.right index c836b7ee0..f9c7eee7c 100644 --- a/tests/array.right +++ b/tests/array.right @@ -299,3 +299,16 @@ argv[1] = argv[2] = <> argv[3] = argv[4] = <> +126 +127 +128 +argv[1] = <€> +argv[1] = <~> +argv[2] = <^?> +argv[3] = <€> +argv[1] = <~> +argv[2] = <^?> +argv[3] = <€> +argv[1] = <~> +argv[2] = <^?> +argv[3] = <€> diff --git a/tests/array.tests b/tests/array.tests index 3e3786a70..1ac614bf3 100644 --- a/tests/array.tests +++ b/tests/array.tests @@ -382,3 +382,5 @@ ${THIS_SH} ./array6.sub ${THIS_SH} ./array7.sub ${THIS_SH} ./array8.sub + +${THIS_SH} ./array9.sub diff --git a/tests/array.tests~ b/tests/array.tests~ index 025ea0e9e..3e3786a70 100644 --- a/tests/array.tests~ +++ b/tests/array.tests~ @@ -379,3 +379,6 @@ ${THIS_SH} ./array5.sub # tests for post-bash-3.2 problems, most fixed in bash-3.2 patches ${THIS_SH} ./array6.sub +${THIS_SH} ./array7.sub + +${THIS_SH} ./array8.sub diff --git a/tests/array9.sub b/tests/array9.sub new file mode 100644 index 000000000..444247fa3 --- /dev/null +++ b/tests/array9.sub @@ -0,0 +1,27 @@ +echo $(( 0x7e )) +echo $(( 0x7f )) +echo $(( 0x80 )) + +a=$'\x80' +recho "$a" + +a=( $'\x7e' $'\x7f' $'\x80' ) + +recho "${a[@]}" + +unset a +a[0]=$'\x7e' +a[1]=$'\x7f' +a[2]=$'\x80' + +recho "${a[@]}" + +b1=$'\x7e' +b2=$'\x7f' +b3=$'\x80' + +unset a +a=( "$b1" "$b2" "$b3" ) + +recho "${a[@]}" +