Projects
home:linjiaxin11:branches:openEuler:22.03:LTS
bash
_service:tar_scm_kernel_repo:backport-fix-for-n...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm_kernel_repo:backport-fix-for-nofork-comsub-command-printing-fix-for-crash.patch of Package bash
From 4e4cebb6dcf4522243b5b9e87918789aea8f73a1 Mon Sep 17 00:00:00 2001 From: Chet Ramey <chet.ramey@case.edu> Date: Tue, 20 Jun 2023 11:10:39 -0400 Subject: [PATCH] fix for nofork comsub command printing; fix for crash caused by tempvar assignment converted to an array in a function Conflict:code context adaptation and delete modify in CWRU.chlog Reference:https://git.savannah.gnu.org/cgit/bash.git/commit/?id=4e4cebb6dcf4522243b5b9e87918789aea8f73a1 --- arrayfunc.c | 13 ++++++++++ arrayfunc.h | 2 ++ builtins/declare.def | 14 ++++++++--- print_cmd.c | 12 +++++---- shell.h | 2 ++ subst.h | 1 + variables.c | 60 ++++++++++++++++++++++++++++++-------------- 7 files changed, 76 insertions(+), 28 deletions(-) diff --git a/arrayfunc.c b/arrayfunc.c index 58d0222..687b7ab 100644 --- a/arrayfunc.c +++ b/arrayfunc.c @@ -147,6 +147,19 @@ convert_var_to_assoc (var) return var; } +/* Copy the array (ARRAY *) or assoc (HASH_TABLE *) from variable V1 to V2, + and return V2. */ +SHELL_VAR * +arrayvar_copyval (SHELL_VAR *v1, SHELL_VAR *v2) +{ + FREE (value_cell (v2)); + if (array_p (v1)) + var_setarray (v2, array_copy (array_cell (v1))); + else if (assoc_p (v1)) + var_setassoc (v2, assoc_copy (assoc_cell (v1))); + return v2; +} + char * make_array_variable_value (entry, ind, key, value, flags) SHELL_VAR *entry; diff --git a/arrayfunc.h b/arrayfunc.h index 838e76d..ec455fa 100644 --- a/arrayfunc.h +++ b/arrayfunc.h @@ -47,6 +47,8 @@ extern int array_expand_once; extern SHELL_VAR *convert_var_to_array PARAMS((SHELL_VAR *)); extern SHELL_VAR *convert_var_to_assoc PARAMS((SHELL_VAR *)); +extern SHELL_VAR *arrayvar_copyval (SHELL_VAR *, SHELL_VAR *); + extern char *make_array_variable_value PARAMS((SHELL_VAR *, arrayind_t, char *, char *, int)); extern SHELL_VAR *bind_array_variable PARAMS((char *, arrayind_t, char *, int)); diff --git a/builtins/declare.def b/builtins/declare.def index 21e4516..13f20de 100644 --- a/builtins/declare.def +++ b/builtins/declare.def @@ -952,20 +952,26 @@ restart_new_var_name: if ((flags_on & (att_exported|att_readonly)) && tempvar_p (var)) { SHELL_VAR *tv; - char *tvalue; tv = find_tempenv_variable (var->name); if (tv) { - tvalue = var_isset (var) ? savestring (value_cell (var)) : savestring (""); - tv = bind_variable (var->name, tvalue, 0); + /* We don't bother with modifying the temporary env because + we're already using it. */ + tv = bind_variable (name_cell (var), value_cell (var), ASS_NOTEMPENV); + if (tv) { +#if defined (ARRAY_VARS) + /* copy array value if array variable */ + if ((array_p (var) || assoc_p (var))) + arrayvar_copyval (var, tv); +#endif + /* then copy attributes */ tv->attributes |= var->attributes & ~att_tempvar; if (tv->context > 0) VSETATTR (tv, att_propagate); } - free (tvalue); } VSETATTR (var, att_propagate); } diff --git a/print_cmd.c b/print_cmd.c index 3c8c2d8..d497418 100644 --- a/print_cmd.c +++ b/print_cmd.c @@ -666,7 +666,7 @@ print_group_command (group_command) group_command_nesting++; cprintf ("{ "); - if (inside_function_def == 0) + if (inside_function_def == 0 /* && pretty_print_mode == 0 */) skip_this_indent++; else { @@ -680,7 +680,7 @@ print_group_command (group_command) make_command_string_internal (group_command->command); PRINT_DEFERRED_HEREDOCS (""); - if (inside_function_def) + if (inside_function_def /* || pretty_print_mode */) { cprintf ("\n"); indentation -= indentation_amount; @@ -1459,9 +1459,11 @@ indent (amount) static void semicolon () { - if (command_string_index > 0 && - (the_printed_command[command_string_index - 1] == '&' || - the_printed_command[command_string_index - 1] == '\n')) + if ((command_string_index > 0 && + the_printed_command[command_string_index - 1] == '\n') || + (command_string_index > 1 && + the_printed_command[command_string_index - 1] == '&' && + the_printed_command[command_string_index - 2] == ' ')) return; cprintf (";"); } diff --git a/shell.h b/shell.h index 91b31ac..ebc2a26 100644 --- a/shell.h +++ b/shell.h @@ -106,6 +106,8 @@ extern int indirection_level; extern int shell_compatibility_level; extern int running_under_emacs; +extern int pretty_print_mode; + extern int posixly_correct; extern int no_line_editing; diff --git a/subst.h b/subst.h index 1347651..a5a5fae 100644 --- a/subst.h +++ b/subst.h @@ -55,6 +55,7 @@ #define ASS_NOEVAL 0x0100 /* don't evaluate value as expression */ #define ASS_NOLONGJMP 0x0200 /* don't longjmp on fatal assignment error */ #define ASS_NOINVIS 0x0400 /* don't resolve local invisible variables */ +#define ASS_NOTEMPENV 0x2000 /* don't assign into temporary environment */ /* Flags for the string extraction functions. */ #define SX_NOALLOC 0x0001 /* just skip; don't return substring */ diff --git a/variables.c b/variables.c index 73f157f..2529afb 100644 --- a/variables.c +++ b/variables.c @@ -266,6 +266,8 @@ static SHELL_VAR *new_shell_variable PARAMS((const char *)); static SHELL_VAR *make_new_variable PARAMS((const char *, HASH_TABLE *)); static SHELL_VAR *bind_variable_internal PARAMS((const char *, char *, HASH_TABLE *, int, int)); +static void init_shell_variable (SHELL_VAR *); + static void dispose_variable_value PARAMS((SHELL_VAR *)); static void free_variable_hash_data PARAMS((PTR_T)); @@ -2702,6 +2704,21 @@ make_local_variable (name, flags) new_var = make_new_variable (name, vc->table); else { +#if 0 + /* This handles the case where a variable is found in both the temporary + environment *and* declared as a local variable. If we want to avoid + multiple entries with the same name in VC->table (that might mess up + unset), we need to use the existing variable entry and destroy the + current value. Currently disabled because it doesn't matter -- the + right things happen. */ + new_var = 0; + if (was_tmpvar && (new_var = hash_lookup (name, vc->table))) + { + dispose_variable_value (new_var); + init_variable (new_var); + } + if (new_var == 0) +#endif new_var = make_new_variable (name, vc->table); /* If we found this variable in one of the temporary environments, @@ -2761,16 +2778,9 @@ set_local_var_flags: return (new_var); } -/* Create a new shell variable with name NAME. */ -static SHELL_VAR * -new_shell_variable (name) - const char *name; +static void +init_variable (SHELL_VAR *entry) { - SHELL_VAR *entry; - - entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR)); - - entry->name = savestring (name); var_setvalue (entry, (char *)NULL); CLEAR_EXPORTSTR (entry); @@ -2783,7 +2793,18 @@ new_shell_variable (name) make_local_variable has the responsibility of changing the variable context. */ entry->context = 0; +} + +/* Create a new shell variable with name NAME. */ +static SHELL_VAR * +new_shell_variable (const char *name) +{ + SHELL_VAR *entry; + entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR)); + + entry->name = savestring (name); + init_variable (entry); return (entry); } @@ -3265,8 +3286,9 @@ bind_variable (name, value, flags) and, if found, modify the value there before modifying it in the shell_variables table. This allows sourced scripts to modify values given to them in a temporary environment while modifying the variable - value that the caller sees. */ - if (temporary_env && value) /* XXX - can value be null here? */ + value that the caller sees. The caller can inhibit this by setting + ASS_NOTEMPENV in FLAGS. */ + if (temporary_env && value && (flags & ASS_NOTEMPENV) == 0) /* XXX - can value be null here? */ bind_tempenv_variable (name, value); /* XXX -- handle local variables here. */ @@ -4581,6 +4603,11 @@ push_temp_var (data) v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, ASS_FORCE|ASS_NOLONGJMP); +#if defined (ARRAY_VARS) + if (v && (array_p (var) || assoc_p (var))) + arrayvar_copyval (var, v); +#endif + /* XXX - should we set the context here? It shouldn't matter because of how assign_in_env works, but we do it anyway. */ if (v) @@ -5245,6 +5272,7 @@ push_posix_tempvar_internal (var, isbltin) set_current_options (value_cell (var)); set_shellopts (); } + /* This takes variable assignments preceding special builtins that can execute multiple commands (source, eval, etc.) and performs the equivalent of an assignment statement to modify the closest enclosing variable (the @@ -5286,14 +5314,8 @@ push_posix_tempvar_internal (var, isbltin) #if defined (ARRAY_VARS) if (v && (array_p (var) || assoc_p (var))) - { - FREE (value_cell (v)); - if (array_p (var)) - var_setarray (v, array_copy (array_cell (var))); - else - var_setassoc (v, assoc_copy (assoc_cell (var))); - } -#endif + arrayvar_copyval (var, v); +#endif dispose_variable (var); } -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.