]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/bash/bash50-010
bac7aa925156b2564948ad85d07c550fc59ca4b9
[people/pmueller/ipfire-2.x.git] / src / patches / bash / bash50-010
1 BASH PATCH REPORT
2 =================
3
4 Bash-Release: 5.0
5 Patch-ID: bash50-010
6
7 Bug-Reported-by: Thorsten Glaser <tg@mirbsd.de>
8 Bug-Reference-ID: <156622962831.19438.16374961114836556294.reportbug@tglase.lan.tarent.de>
9 Bug-Reference-URL: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=935115
10
11 Bug-Description:
12
13 Bash-5.0 changed the way assignment statements preceding special builtins
14 and shell functions were handled in posix mode. They automatically created
15 or modified global variables instead of modifying existing local variables
16 as in bash-4.4.
17
18 The bash-4.4 posix-mode semantics were buggy, and resulted in creating
19 local variables where they were not intended and modifying global variables
20 and local variables simultaneously.
21
22 The bash-5.0 changes were intended to fix this issue, but did not preserve
23 enough backwards compatibility. The posix standard also changed what it
24 required in these cases, so bash-5.0 is not bound by the strict conformance
25 requirements that existed in previous issues of the standard.
26
27 This patch modifies the bash-5.0 posix mode behavior in an effort to restore
28 some backwards compatibility and rationalize the behavior in the presence of
29 local variables. It
30
31 1. Changes the assignment semantics to be more similar to standalone assignment
32 statements: assignments preceding a function call or special builtin while
33 executing in a shell function will modify the value of a local variable
34 with the same name for the duration of the function's execution;
35
36 2. Changes assignments preceding shell function calls or special builtins
37 from within a shell function to no longer create or modify global variables
38 in the presence of a local variable with the same name;
39
40 3. Assignment statements preceding a shell function call or special builtin
41 at the global scope continue to modify the (global) calling environment,
42 but are unaffected by assignments preceding function calls or special
43 builtins within a function, as described in item 2. This is also similar
44 to the behavior of a standalone assignment statement.
45
46 Patch (apply with `patch -p0'):
47
48 *** ../bash-5.0-patched/variables.c 2018-12-18 11:07:21.000000000 -0500
49 --- variables.c 2019-08-22 10:53:44.000000000 -0400
50 ***************
51 *** 4461,4467 ****
52
53 /* Take a variable from an assignment statement preceding a posix special
54 ! builtin (including `return') and create a global variable from it. This
55 ! is called from merge_temporary_env, which is only called when in posix
56 ! mode. */
57 static void
58 push_posix_temp_var (data)
59 --- 4461,4467 ----
60
61 /* Take a variable from an assignment statement preceding a posix special
62 ! builtin (including `return') and create a variable from it as if a
63 ! standalone assignment statement had been performed. This is called from
64 ! merge_temporary_env, which is only called when in posix mode. */
65 static void
66 push_posix_temp_var (data)
67 ***************
68 *** 4473,4486 ****
69 var = (SHELL_VAR *)data;
70
71 ! binding_table = global_variables->table;
72 ! if (binding_table == 0)
73 ! binding_table = global_variables->table = hash_create (VARIABLES_HASH_BUCKETS);
74 !
75 ! v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, ASS_FORCE|ASS_NOLONGJMP);
76
77 /* global variables are no longer temporary and don't need propagating. */
78 ! var->attributes &= ~(att_tempvar|att_propagate);
79 if (v)
80 ! v->attributes |= var->attributes;
81
82 if (find_special_var (var->name) >= 0)
83 --- 4473,4497 ----
84 var = (SHELL_VAR *)data;
85
86 ! /* Just like do_assignment_internal(). This makes assignments preceding
87 ! special builtins act like standalone assignment statements when in
88 ! posix mode, satisfying the posix requirement that this affect the
89 ! "current execution environment." */
90 ! v = bind_variable (var->name, value_cell (var), ASS_FORCE|ASS_NOLONGJMP);
91 !
92 ! /* If this modifies an existing local variable, v->context will be non-zero.
93 ! If it comes back with v->context == 0, we bound at the global context.
94 ! Set binding_table appropriately. It doesn't matter whether it's correct
95 ! if the variable is local, only that it's not global_variables->table */
96 ! binding_table = v->context ? shell_variables->table : global_variables->table;
97
98 /* global variables are no longer temporary and don't need propagating. */
99 ! if (binding_table == global_variables->table)
100 ! var->attributes &= ~(att_tempvar|att_propagate);
101 !
102 if (v)
103 ! {
104 ! v->attributes |= var->attributes;
105 ! v->attributes &= ~att_tempvar; /* not a temp var now */
106 ! }
107
108 if (find_special_var (var->name) >= 0)
109 ***************
110 *** 4576,4587 ****
111 {
112 int i;
113
114 tempvar_list = strvec_create (HASH_ENTRIES (temporary_env) + 1);
115 tempvar_list[tvlist_ind = 0] = 0;
116 !
117 ! hash_flush (temporary_env, pushf);
118 ! hash_dispose (temporary_env);
119 temporary_env = (HASH_TABLE *)NULL;
120
121 tempvar_list[tvlist_ind] = 0;
122
123 --- 4587,4601 ----
124 {
125 int i;
126 + HASH_TABLE *disposer;
127
128 tempvar_list = strvec_create (HASH_ENTRIES (temporary_env) + 1);
129 tempvar_list[tvlist_ind = 0] = 0;
130 !
131 ! disposer = temporary_env;
132 temporary_env = (HASH_TABLE *)NULL;
133
134 + hash_flush (disposer, pushf);
135 + hash_dispose (disposer);
136 +
137 tempvar_list[tvlist_ind] = 0;
138
139 *** ../bash-5.0-patched/tests/varenv.right 2018-12-17 15:39:48.000000000 -0500
140 --- tests/varenv.right 2019-08-22 16:05:25.000000000 -0400
141 ***************
142 *** 147,153 ****
143 outside: declare -- var="one"
144 inside: declare -x var="value"
145 ! outside: declare -x var="value"
146 ! inside: declare -- var="local"
147 ! outside: declare -x var="global"
148 foo=<unset> environment foo=
149 foo=foo environment foo=foo
150 --- 147,153 ----
151 outside: declare -- var="one"
152 inside: declare -x var="value"
153 ! outside: declare -- var="outside"
154 ! inside: declare -x var="global"
155 ! outside: declare -- var="outside"
156 foo=<unset> environment foo=
157 foo=foo environment foo=foo
158 *** ../bash-5.0/patchlevel.h 2016-06-22 14:51:03.000000000 -0400
159 --- patchlevel.h 2016-10-01 11:01:28.000000000 -0400
160 ***************
161 *** 26,30 ****
162 looks for to find the patch level (for the sccs version string). */
163
164 ! #define PATCHLEVEL 9
165
166 #endif /* _PATCHLEVEL_H_ */
167 --- 26,30 ----
168 looks for to find the patch level (for the sccs version string). */
169
170 ! #define PATCHLEVEL 10
171
172 #endif /* _PATCHLEVEL_H_ */