7
Bug-Reported-by: Florian Weimer <fweimer@redhat.com>
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
18
Patch (apply with `patch -p0'):
20
*** ../bash-4.3.26/variables.c 2014-09-25 23:02:18.000000000 -0400
21
--- variables.c 2014-09-27 20:52:04.000000000 -0400
25
#define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
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) */
32
extern char **environ;
36
static void dispose_temporary_env __P((sh_free_func_t *));
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 *));
42
static void dispose_temporary_env __P((sh_free_func_t *));
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 *));
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))
53
string_length = strlen (string);
54
! temp_string = (char *)xmalloc (3 + string_length + char_index);
56
! strcpy (temp_string, name);
57
! temp_string[char_index] = ' ';
58
! strcpy (temp_string + char_index + 1, string);
60
/* Don't import function names that are invalid identifiers from the
61
environment, though we still allow them to be defined as shell
63
! if (legal_identifier (name))
64
! parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
66
! if (temp_var = find_function (name))
68
VSETATTR (temp_var, (att_exported|att_imported));
70
/* If exported function, define it now. Don't import functions from
71
the environment in privileged mode. */
72
! if (privmode == 0 && read_but_dont_execute == 0 &&
73
! STREQN (BASHFUNC_PREFIX, name, BASHFUNC_PREFLEN) &&
74
! STREQ (BASHFUNC_SUFFIX, name + char_index - BASHFUNC_SUFFLEN) &&
75
! STREQN ("() {", string, 4))
78
+ char *tname; /* desired imported function name */
80
+ namelen = char_index - BASHFUNC_PREFLEN - BASHFUNC_SUFFLEN;
82
+ tname = name + BASHFUNC_PREFLEN; /* start of func name */
83
+ tname[namelen] = '\0'; /* now tname == func name */
85
string_length = strlen (string);
86
! temp_string = (char *)xmalloc (namelen + string_length + 2);
88
! memcpy (temp_string, tname, namelen);
89
! temp_string[namelen] = ' ';
90
! memcpy (temp_string + namelen + 1, string, string_length + 1);
92
/* Don't import function names that are invalid identifiers from the
93
environment, though we still allow them to be defined as shell
95
! if (absolute_program (tname) == 0 && (posixly_correct == 0 || legal_identifier (tname)))
96
! parse_and_execute (temp_string, tname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
98
! if (temp_var = find_function (tname))
100
VSETATTR (temp_var, (att_exported|att_imported));
104
last_command_exit_value = 1;
105
! report_error (_("error importing function definition for `%s'"), name);
108
#if defined (ARRAY_VARS)
111
last_command_exit_value = 1;
112
! report_error (_("error importing function definition for `%s'"), tname);
115
+ /* Restore original suffix */
116
+ tname[namelen] = BASHFUNC_SUFFIX[0];
118
#if defined (ARRAY_VARS)
122
INVALIDATE_EXPORTSTR (var);
123
! var->exportstr = mk_env_string (name, value);
125
array_needs_making = 1;
128
INVALIDATE_EXPORTSTR (var);
129
! var->exportstr = mk_env_string (name, value, 0);
131
array_needs_making = 1;
136
! mk_env_string (name, value)
137
const char *name, *value;
139
! int name_len, value_len;
142
name_len = strlen (name);
143
value_len = STRLEN (value);
144
! p = (char *)xmalloc (2 + name_len + value_len);
148
! strcpy (p + name_len + 1, value);
150
! p[name_len + 1] = '\0';
156
! mk_env_string (name, value, isfunc)
157
const char *name, *value;
160
! size_t name_len, value_len;
163
name_len = strlen (name);
164
value_len = STRLEN (value);
166
! /* If we are exporting a shell function, construct the encoded function
168
! if (isfunc && value)
170
! p = (char *)xmalloc (BASHFUNC_PREFLEN + name_len + BASHFUNC_SUFFLEN + value_len + 2);
172
! memcpy (q, BASHFUNC_PREFIX, BASHFUNC_PREFLEN);
173
! q += BASHFUNC_PREFLEN;
174
! memcpy (q, name, name_len);
176
! memcpy (q, BASHFUNC_SUFFIX, BASHFUNC_SUFFLEN);
177
! q += BASHFUNC_SUFFLEN;
181
! p = (char *)xmalloc (2 + name_len + value_len);
182
! memcpy (p, name, name_len);
188
! memcpy (q + 1, value, value_len + 1);
196
using the cached exportstr... */
197
list[list_index] = USE_EXPORTSTR ? savestring (value)
198
! : mk_env_string (var->name, value);
200
if (USE_EXPORTSTR == 0)
202
using the cached exportstr... */
203
list[list_index] = USE_EXPORTSTR ? savestring (value)
204
! : mk_env_string (var->name, value, function_p (var));
206
if (USE_EXPORTSTR == 0)
207
*** ../bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
208
--- patchlevel.h 2014-03-20 20:01:28.000000000 -0400
211
looks for to find the patch level (for the sccs version string). */
213
! #define PATCHLEVEL 26
215
#endif /* _PATCHLEVEL_H_ */
217
looks for to find the patch level (for the sccs version string). */
219
! #define PATCHLEVEL 27
221
#endif /* _PATCHLEVEL_H_ */