|
1 BASH PATCH REPORT |
|
2 ================= |
|
3 |
|
4 Bash-Release: 4.1 |
|
5 Patch-ID: bash41-014 |
|
6 |
|
7 Bug-Reported-by: Florian Weimer <[email protected]> |
|
8 Bug-Reference-ID: |
|
9 Bug-Reference-URL: |
|
10 |
|
11 Bug-Description: |
|
12 |
|
13 This patch changes the encoding bash uses for exported functions to avoid |
|
14 clashes with shell variables and to avoid depending only on an environment |
|
15 variable's contents to determine whether or not to interpret it as a shell |
|
16 function. |
|
17 |
|
18 Patch (apply with `patch -p0'): |
|
19 |
|
20 *** ../bash-4.1.13/variables.c 2014-09-16 19:27:38.000000000 -0400 |
|
21 --- variables.c 2014-09-27 20:57:46.000000000 -0400 |
|
22 *************** |
|
23 *** 80,83 **** |
|
24 --- 80,88 ---- |
|
25 #define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0') |
|
26 |
|
27 + #define BASHFUNC_PREFIX "BASH_FUNC_" |
|
28 + #define BASHFUNC_PREFLEN 10 /* == strlen(BASHFUNC_PREFIX */ |
|
29 + #define BASHFUNC_SUFFIX "%%" |
|
30 + #define BASHFUNC_SUFFLEN 2 /* == strlen(BASHFUNC_SUFFIX) */ |
|
31 + |
|
32 extern char **environ; |
|
33 |
|
34 *************** |
|
35 *** 269,273 **** |
|
36 static void dispose_temporary_env __P((sh_free_func_t *)); |
|
37 |
|
38 ! static inline char *mk_env_string __P((const char *, const char *)); |
|
39 static char **make_env_array_from_var_list __P((SHELL_VAR **)); |
|
40 static char **make_var_export_array __P((VAR_CONTEXT *)); |
|
41 --- 274,278 ---- |
|
42 static void dispose_temporary_env __P((sh_free_func_t *)); |
|
43 |
|
44 ! static inline char *mk_env_string __P((const char *, const char *, int)); |
|
45 static char **make_env_array_from_var_list __P((SHELL_VAR **)); |
|
46 static char **make_var_export_array __P((VAR_CONTEXT *)); |
|
47 *************** |
|
48 *** 339,357 **** |
|
49 /* If exported function, define it now. Don't import functions from |
|
50 the environment in privileged mode. */ |
|
51 ! if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4)) |
|
52 { |
|
53 string_length = strlen (string); |
|
54 ! temp_string = (char *)xmalloc (3 + string_length + char_index); |
|
55 |
|
56 ! strcpy (temp_string, name); |
|
57 ! temp_string[char_index] = ' '; |
|
58 ! strcpy (temp_string + char_index + 1, string); |
|
59 |
|
60 /* Don't import function names that are invalid identifiers from the |
|
61 environment. */ |
|
62 ! if (legal_identifier (name)) |
|
63 ! parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD); |
|
64 |
|
65 ! if (temp_var = find_function (name)) |
|
66 { |
|
67 VSETATTR (temp_var, (att_exported|att_imported)); |
|
68 --- 344,373 ---- |
|
69 /* If exported function, define it now. Don't import functions from |
|
70 the environment in privileged mode. */ |
|
71 ! if (privmode == 0 && read_but_dont_execute == 0 && |
|
72 ! STREQN (BASHFUNC_PREFIX, name, BASHFUNC_PREFLEN) && |
|
73 ! STREQ (BASHFUNC_SUFFIX, name + char_index - BASHFUNC_SUFFLEN) && |
|
74 ! STREQN ("() {", string, 4)) |
|
75 { |
|
76 + size_t namelen; |
|
77 + char *tname; /* desired imported function name */ |
|
78 + |
|
79 + namelen = char_index - BASHFUNC_PREFLEN - BASHFUNC_SUFFLEN; |
|
80 + |
|
81 + tname = name + BASHFUNC_PREFLEN; /* start of func name */ |
|
82 + tname[namelen] = '\0'; /* now tname == func name */ |
|
83 + |
|
84 string_length = strlen (string); |
|
85 ! temp_string = (char *)xmalloc (namelen + string_length + 2); |
|
86 |
|
87 ! memcpy (temp_string, tname, namelen); |
|
88 ! temp_string[namelen] = ' '; |
|
89 ! memcpy (temp_string + namelen + 1, string, string_length + 1); |
|
90 |
|
91 /* Don't import function names that are invalid identifiers from the |
|
92 environment. */ |
|
93 ! if (absolute_program (tname) == 0 && (posixly_correct == 0 || legal_identifier (tname))) |
|
94 ! parse_and_execute (temp_string, tname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD); |
|
95 |
|
96 ! if (temp_var = find_function (tname)) |
|
97 { |
|
98 VSETATTR (temp_var, (att_exported|att_imported)); |
|
99 *************** |
|
100 *** 359,363 **** |
|
101 } |
|
102 else |
|
103 ! report_error (_("error importing function definition for `%s'"), name); |
|
104 } |
|
105 #if defined (ARRAY_VARS) |
|
106 --- 375,382 ---- |
|
107 } |
|
108 else |
|
109 ! report_error (_("error importing function definition for `%s'"), tname); |
|
110 ! |
|
111 ! /* Restore original suffix */ |
|
112 ! tname[namelen] = BASHFUNC_SUFFIX[0]; |
|
113 } |
|
114 #if defined (ARRAY_VARS) |
|
115 *************** |
|
116 *** 2520,2524 **** |
|
117 |
|
118 INVALIDATE_EXPORTSTR (var); |
|
119 ! var->exportstr = mk_env_string (name, value); |
|
120 |
|
121 array_needs_making = 1; |
|
122 --- 2539,2543 ---- |
|
123 |
|
124 INVALIDATE_EXPORTSTR (var); |
|
125 ! var->exportstr = mk_env_string (name, value, 0); |
|
126 |
|
127 array_needs_making = 1; |
|
128 *************** |
|
129 *** 3339,3357 **** |
|
130 |
|
131 static inline char * |
|
132 ! mk_env_string (name, value) |
|
133 const char *name, *value; |
|
134 { |
|
135 ! int name_len, value_len; |
|
136 ! char *p; |
|
137 |
|
138 name_len = strlen (name); |
|
139 value_len = STRLEN (value); |
|
140 ! p = (char *)xmalloc (2 + name_len + value_len); |
|
141 ! strcpy (p, name); |
|
142 ! p[name_len] = '='; |
|
143 if (value && *value) |
|
144 ! strcpy (p + name_len + 1, value); |
|
145 else |
|
146 ! p[name_len + 1] = '\0'; |
|
147 return (p); |
|
148 } |
|
149 --- 3358,3397 ---- |
|
150 |
|
151 static inline char * |
|
152 ! mk_env_string (name, value, isfunc) |
|
153 const char *name, *value; |
|
154 + int isfunc; |
|
155 { |
|
156 ! size_t name_len, value_len; |
|
157 ! char *p, *q; |
|
158 |
|
159 name_len = strlen (name); |
|
160 value_len = STRLEN (value); |
|
161 ! |
|
162 ! /* If we are exporting a shell function, construct the encoded function |
|
163 ! name. */ |
|
164 ! if (isfunc && value) |
|
165 ! { |
|
166 ! p = (char *)xmalloc (BASHFUNC_PREFLEN + name_len + BASHFUNC_SUFFLEN + value_len + 2); |
|
167 ! q = p; |
|
168 ! memcpy (q, BASHFUNC_PREFIX, BASHFUNC_PREFLEN); |
|
169 ! q += BASHFUNC_PREFLEN; |
|
170 ! memcpy (q, name, name_len); |
|
171 ! q += name_len; |
|
172 ! memcpy (q, BASHFUNC_SUFFIX, BASHFUNC_SUFFLEN); |
|
173 ! q += BASHFUNC_SUFFLEN; |
|
174 ! } |
|
175 ! else |
|
176 ! { |
|
177 ! p = (char *)xmalloc (2 + name_len + value_len); |
|
178 ! memcpy (p, name, name_len); |
|
179 ! q = p + name_len; |
|
180 ! } |
|
181 ! |
|
182 ! q[0] = '='; |
|
183 if (value && *value) |
|
184 ! memcpy (q + 1, value, value_len + 1); |
|
185 else |
|
186 ! q[1] = '\0'; |
|
187 ! |
|
188 return (p); |
|
189 } |
|
190 *************** |
|
191 *** 3439,3443 **** |
|
192 using the cached exportstr... */ |
|
193 list[list_index] = USE_EXPORTSTR ? savestring (value) |
|
194 ! : mk_env_string (var->name, value); |
|
195 |
|
196 if (USE_EXPORTSTR == 0) |
|
197 --- 3479,3483 ---- |
|
198 using the cached exportstr... */ |
|
199 list[list_index] = USE_EXPORTSTR ? savestring (value) |
|
200 ! : mk_env_string (var->name, value, function_p (var)); |
|
201 |
|
202 if (USE_EXPORTSTR == 0) |
|
203 *** ../bash-4.1-patched/patchlevel.h 2009-10-01 16:39:22.000000000 -0400 |
|
204 --- patchlevel.h 2010-01-14 09:38:08.000000000 -0500 |
|
205 *************** |
|
206 *** 26,30 **** |
|
207 looks for to find the patch level (for the sccs version string). */ |
|
208 |
|
209 ! #define PATCHLEVEL 13 |
|
210 |
|
211 #endif /* _PATCHLEVEL_H_ */ |
|
212 --- 26,30 ---- |
|
213 looks for to find the patch level (for the sccs version string). */ |
|
214 |
|
215 ! #define PATCHLEVEL 14 |
|
216 |
|
217 #endif /* _PATCHLEVEL_H_ */ |