1 |
BASH PATCH REPORT |
2 |
================= |
3 |
|
4 |
Bash-Release: 4.2 |
5 |
Patch-ID: bash42-050 |
6 |
|
7 |
Bug-Reported-by: Florian Weimer <fweimer@redhat.com> |
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.2.49/variables.c 2014-09-16 19:35:45.000000000 -0400 |
21 |
--- variables.c 2014-09-27 20:54:00.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 |
*** 2538,2542 **** |
117 |
|
118 |
INVALIDATE_EXPORTSTR (var); |
119 |
! var->exportstr = mk_env_string (name, value); |
120 |
|
121 |
array_needs_making = 1; |
122 |
--- 2557,2561 ---- |
123 |
|
124 |
INVALIDATE_EXPORTSTR (var); |
125 |
! var->exportstr = mk_env_string (name, value, 0); |
126 |
|
127 |
array_needs_making = 1; |
128 |
*************** |
129 |
*** 3390,3408 **** |
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 |
--- 3409,3448 ---- |
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 |
*** 3490,3494 **** |
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 |
--- 3530,3534 ---- |
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.2-patched/patchlevel.h Sat Jun 12 20:14:48 2010 |
204 |
--- patchlevel.h Thu Feb 24 21:41:34 2011 |
205 |
*************** |
206 |
*** 26,30 **** |
207 |
looks for to find the patch level (for the sccs version string). */ |
208 |
|
209 |
! #define PATCHLEVEL 49 |
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 50 |
216 |
|
217 |
#endif /* _PATCHLEVEL_H_ */ |