diff options
author | Chet Ramey <chet.ramey@case.edu> | 2011-12-12 22:08:08 -0500 |
---|---|---|
committer | Chet Ramey <chet.ramey@case.edu> | 2011-12-12 22:08:08 -0500 |
commit | 048b249ea3221fe186bef2ada4887587e7973c58 (patch) | |
tree | bb8970368f7609bfdf2c634d5aedaef5f9e38c6f /subst.c | |
parent | aad3dfa27a72b04541419962aa56a22eb621e58c (diff) | |
download | bash-048b249ea3221fe186bef2ada4887587e7973c58.tar.gz |
commit bash-20101015 snapshot
Diffstat (limited to 'subst.c')
-rw-r--r-- | subst.c | 59 |
1 files changed, 37 insertions, 22 deletions
@@ -108,7 +108,7 @@ extern int errno; /* Evaluates to 1 if C is one of the shell's special parameters for which an indirect variable reference may be made. */ #define VALID_INDIR_PARAM(c) \ - ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*') + ((posixly_correct == 0 && (c) == '#') || (posixly_correct == 0 && (c) == '?') || (c) == '@' || (c) == '*') /* Evaluates to 1 if C is one of the OP characters that follows the parameter in ${parameter[:]OPword}. */ @@ -1461,7 +1461,7 @@ extract_dollar_brace_string (string, sindex, quoted, flags) if (c == '\'') { /*itrace("extract_dollar_brace_string: c == single quote flags = %d quoted = %d dolbrace_state = %d", flags, quoted, dolbrace_state);*/ - if (posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE) + if (posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) ADVANCE_CHAR (string, slen, i); else { @@ -5907,7 +5907,7 @@ parameter_brace_expand_length (name) break; case '!': if (last_asynchronous_pid == NO_PID) - t = (char *)NULL; + t = (char *)NULL; /* XXX - error if set -u set? */ else t = itos (last_asynchronous_pid); break; @@ -5929,6 +5929,8 @@ parameter_brace_expand_length (name) if (legal_number (name + 1, &arg_index)) /* ${#1} */ { t = get_dollar_var_value (arg_index); + if (t == 0 && unbound_vars_is_error) + return INTMAX_MIN; number = MB_STRLEN (t); FREE (t); } @@ -5939,6 +5941,8 @@ parameter_brace_expand_length (name) t = assoc_reference (assoc_cell (var), "0"); else t = array_reference (array_cell (var), 0); + if (t == 0 && unbound_vars_is_error) + return INTMAX_MIN; number = MB_STRLEN (t); } #endif @@ -6940,15 +6944,8 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta /* If the name really consists of a special variable, then make sure that we have the entire name. We don't allow indirect references to special variables except `#', `?', `@' and `*'. */ - if ((sindex == t_index && - (string[t_index] == '-' || - string[t_index] == '?' || - string[t_index] == '#')) || - (sindex == t_index - 1 && string[sindex] == '!' && - (string[t_index] == '#' || - string[t_index] == '?' || - string[t_index] == '@' || - string[t_index] == '*'))) + if ((sindex == t_index && VALID_SPECIAL_LENGTH_PARAM (string[t_index])) || + (sindex == t_index - 1 && string[sindex] == '!' && VALID_INDIR_PARAM (string[t_index]))) { t_index++; free (name); @@ -7043,6 +7040,13 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta } number = parameter_brace_expand_length (name); + if (number == INTMAX_MIN && unbound_vars_is_error) + { + last_command_exit_value = EXECUTION_FAILURE; + err_unboundvar (name+1); + free (name); + return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); + } free (name); *indexp = sindex; @@ -7178,6 +7182,21 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta *indexp = sindex; + /* All the cases where an expansion can possibly generate an unbound + variable error. */ + if (want_substring || want_patsub || want_casemod || c == '#' || c == '%' || c == RBRACE) + { + if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1])) + { + last_command_exit_value = EXECUTION_FAILURE; + err_unboundvar (name); + FREE (value); + FREE (temp); + free (name); + return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); + } + } + /* If this is a substring spec, process it and add the result. */ if (want_substring) { @@ -7251,15 +7270,6 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta return &expand_wdesc_error; case RBRACE: - if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1])) - { - last_command_exit_value = EXECUTION_FAILURE; - err_unboundvar (name); - FREE (value); - FREE (temp); - free (name); - return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); - } break; case '#': /* ${param#[#]pattern} */ @@ -9324,6 +9334,7 @@ expand_word_list_internal (list, eflags) if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist) { sh_wassign_func_t *assign_func; + int is_special_builtin; /* If the remainder of the words expand to nothing, Posix.2 requires that the variable and environment assignments affect the shell's @@ -9331,6 +9342,10 @@ expand_word_list_internal (list, eflags) assign_func = new_list ? assign_in_env : do_word_assignment; tempenv_assign_error = 0; + /* Posix says that special builtins exit if a variable assignment error + occurs in an assignment preceding it. */ + is_special_builtin = (posixly_correct && new_list && find_special_builtin (new_list->word->word)); + for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next) { this_command_name = (char *)NULL; @@ -9344,7 +9359,7 @@ expand_word_list_internal (list, eflags) if (assign_func == do_word_assignment) { last_command_exit_value = EXECUTION_FAILURE; - if (interactive_shell == 0 && posixly_correct) + if (interactive_shell == 0 && posixly_correct && is_special_builtin) exp_jump_to_top_level (FORCE_EOF); else exp_jump_to_top_level (DISCARD); |