commit bash-20180921 snapshot

This commit is contained in:
Chet Ramey
2018-09-25 09:54:29 -04:00
parent 9282e182d8
commit 3d31a311da
25 changed files with 306 additions and 57 deletions
+94
View File
@@ -4349,3 +4349,97 @@ lib/readline/undo.c
by having the entry being removed as part of the undo list in
_rl_saved_line_for_history. Fixes fuzzing bug reported by
Eduardo Bustamante <dualbus@gmail.com>
9/17
----
[bash-5.0-beta released]
9/18
----
lib/readline/bind.c
- name_and_keymap: new struct for keymap names and maps
- builtin_keymap_names: static array of builtin keymap names and
maps; preparing for allowing applications to set the names of
keymaps they create; keymap_names is initially a pointer to
this array
- _rl_get_keymap_by_name,_rl_get_keymap_by_map: new functions for
searching the keymap_names array and returning an index
- rl_get_keymap_by_name, rl_get_keymap_name: rewritten in terms of
new functions above
- rl_set_keymap_name (char *name, Keymap map): new function, set
name of MAP to NAME. NAME must not be builtin; MAP must not be one
of the builtin keymaps. Request and initial implementation from
Tom Tromey <tom@tromey.com>
lib/readline/readline.h
- rl_set_keymap_name: new extern declaration for new public function
lib/readline/doc/rltech.texi
- rl_set_keymap_name: add documentation
lib/readline/doc/rluser.texi
- add text to `set keymap' description to note that applications
can add keymap names that can be used there
9/20
----
parse.y
- shell_getc: don't execute the alias hack (returning a space at the
end of the string) if we are parsing a command substitution that
starts with a double paren (subshell inside a comsub), in which
case the flags are PSH_DPAREN. Fixes fuzzing bug reported by
Eduardo Bustamante <dualbus@gmail.com>
lib/readline/isearch.c
- _rl_isearch_dispatch: default case: make sure we check multibyte
char length when deciding whether to enlarge the search string
buffer, instead of using the old assumption. Fixes fuzzing bug
reported by Eduardo Bustamante <dualbus@gmail.com>
builtins/fc.def,execute_cmd.c
- fixed some missing free()s uncovered by coverity. Report from
Siteshwar Vashisht <svashisht@redhat.com>
lib/glob/glob.c
- glob_vector: make sure name_vector is initialized to NULL
lib/sh/{pathcanon,pathphys}.c
- {pathcanon,pathphys}: use memmove instead of strcpy on a possibly-
overlapping region of memory
subst.c
- parameter_list_transform: make sure to dispose the word list in all
cases before returning
- parameter_brace_expand_rhs: make sure t1 is freed before returning
due to an invalid name resulting from an indirect expansion
support/man2html.c
- fixed a couple of memory leaks
9/21
----
subst.c
- process_substitute: if we are part of a job control process chain
(pipeline_pgrp != shell_pgrp), have the child shell forked to run
the process substitution set pipeline_pgrp to its own PID,
effectively becoming a process group leader without changing
its own process group. Fixes stray SIGHUP issue reported by
Jeremy Townshend <jeremy.townshend@gmail.com>
9/23
----
arrayfunc.c
- assign_array_element: if we are assigning to an existing associative
array, and assoc_expand_once is set, allow `*' and `@' as subscripts.
Partial fix for report from Grisha Levit <grishalevit@gmail.com>
variables.c
- bind_int_variable: if valid_array_reference (lhs) is not true,
make sure that the lhs is a valid identifier before assigning the
value
arrayfunc.c
- valid_array_reference: allow blank subscripts. They are treated as
`normal' keys for associative arrays and evaluate to 0 for indexed
arrays. More of fix for report from Grisha Levit
<grishalevit@gmail.com>
+6 -4
View File
@@ -283,7 +283,7 @@ assign_array_element (name, value, flags)
int flags;
{
char *sub, *vname;
int sublen;
int sublen, isassoc;
SHELL_VAR *entry;
vname = array_variable_name (name, (flags & ASS_NOEXPAND) != 0, &sub, &sublen);
@@ -291,14 +291,16 @@ assign_array_element (name, value, flags)
if (vname == 0)
return ((SHELL_VAR *)NULL);
if ((ALL_ELEMENT_SUB (sub[0]) && sub[1] == ']') || (sublen <= 1))
entry = find_variable (vname);
isassoc = entry && assoc_p (entry);
if (((isassoc == 0 || (flags & ASS_NOEXPAND) == 0) && (ALL_ELEMENT_SUB (sub[0]) && sub[1] == ']')) || (sublen <= 1))
{
free (vname);
err_badarraysub (name);
return ((SHELL_VAR *)NULL);
}
entry = find_variable (vname);
entry = assign_array_element_internal (entry, name, vname, sub, sublen, value, flags);
free (vname);
@@ -910,7 +912,7 @@ valid_array_reference (name, flags)
return 0;
if (t[len+1] != '\0')
return 0;
#if 1
#if 0
/* Could check and allow subscripts consisting only of whitespace for
existing associative arrays. */
for (r = 1; r < len; r++)
+1
View File
@@ -419,6 +419,7 @@ fc_builtin (list)
{
sh_wrerror ();
fclose (stream);
FREE (fn);
return (EXECUTION_FAILURE);
}
fclose (stream);
+5 -1
View File
@@ -2252,7 +2252,10 @@ coproc_setvars (cp)
{
v = find_variable_nameref_for_create (cp->c_name, 1);
if (v == INVALID_NAMEREF_VALUE)
return;
{
free (namevar);
return;
}
if (v && nameref_p (v))
{
free (cp->c_name);
@@ -2265,6 +2268,7 @@ coproc_setvars (cp)
{
if (readonly_p (v))
err_readonly (cp->c_name);
free (namevar);
return;
}
if (v == 0)
+3 -2
View File
@@ -26,8 +26,8 @@
order of decreasing precedence.
"id++", "id--" [post-increment and post-decrement]
"++id", "--id" [pre-increment and pre-decrement]
"-", "+" [(unary operators)]
"++id", "--id" [pre-increment and pre-decrement]
"!", "~"
"**" [(exponentiation)]
"*", "/", "%"
@@ -1438,7 +1438,8 @@ readtok ()
/* Could force parsing as preinc or predec and throw an error */
#if 0
{
/* bash-5.0 */
/* Posix says unary plus and minus have higher priority than
preinc and predec. */
/* This catches something like --4++ */
if (c == '-')
evalerror ("--: assignment requires lvalue");
+2
View File
@@ -617,6 +617,8 @@ glob_vector (pat, dir, flags)
firstmalloc = 0;
nalloca = 0;
name_vector = NULL;
/*itrace("glob_vector: pat = `%s' dir = `%s' flags = 0x%x", pat, dir, flags);*/
/* If PAT is empty, skip the loop, but return one (empty) filename. */
if (pat == 0 || *pat == '\0')
+92 -13
View File
@@ -95,6 +95,9 @@ static const char *string_varname PARAMS((int));
static char *_rl_get_string_variable_value PARAMS((const char *));
static int substring_member_of_array PARAMS((const char *, const char * const *));
static int _rl_get_keymap_by_name PARAMS((const char *));
static int _rl_get_keymap_by_map PARAMS((Keymap));
static int currently_reading_init_file;
/* used only in this file */
@@ -2255,10 +2258,12 @@ glean_key_from_name (char *name)
}
/* Auxiliary functions to manage keymaps. */
static const struct {
const char * const name;
struct name_and_keymap {
char *name;
Keymap map;
} keymap_names[] = {
};
static struct name_and_keymap builtin_keymap_names[] = {
{ "emacs", emacs_standard_keymap },
{ "emacs-standard", emacs_standard_keymap },
{ "emacs-meta", emacs_meta_keymap },
@@ -2272,27 +2277,101 @@ static const struct {
{ (char *)0x0, (Keymap)0x0 }
};
Keymap
rl_get_keymap_by_name (const char *name)
/* -1 for NULL entry */
#define NUM_BUILTIN_KEYMAPS (sizeof (builtin_keymap_names) / sizeof (builtin_keymap_names[0]) - 1)
static struct name_and_keymap *keymap_names = builtin_keymap_names;
static int
_rl_get_keymap_by_name (const char *name)
{
register int i;
for (i = 0; keymap_names[i].name; i++)
if (_rl_stricmp (name, keymap_names[i].name) == 0)
return (keymap_names[i].map);
return ((Keymap) NULL);
return (i);
return -1;
}
Keymap
rl_get_keymap_by_name (const char *name)
{
int i;
i = _rl_get_keymap_by_name (name);
return ((i >= 0) ? keymap_names[i].map : (Keymap) NULL);
}
static int
_rl_get_keymap_by_map (Keymap map)
{
register int i;
for (i = 0; keymap_names[i].name; i++)
if (map == keymap_names[i].map)
return (i);
return -1;
}
char *
rl_get_keymap_name (Keymap map)
{
register int i;
for (i = 0; keymap_names[i].name; i++)
if (map == keymap_names[i].map)
return ((char *)keymap_names[i].name);
return ((char *)NULL);
int i;
i = _rl_get_keymap_by_map (map);
return ((i >= 0) ? keymap_names[i].name : (char *)NULL);
}
int
rl_set_keymap_name (const char *name, Keymap map)
{
int i, ni, mi;
/* First check whether or not we're trying to rename a builtin keymap */
mi = _rl_get_keymap_by_map (map);
if (mi >= 0 && mi < NUM_BUILTIN_KEYMAPS)
return -1;
/* Then reject attempts to set one of the builtin names to a new map */
ni = _rl_get_keymap_by_name (name);
if (ni >= 0 && ni < NUM_BUILTIN_KEYMAPS)
return -1;
/* Renaming a keymap we already added */
if (mi >= 0) /* XXX - could be >= NUM_BUILTIN_KEYMAPS */
{
xfree (keymap_names[mi].name);
keymap_names[mi].name = savestring (name);
return mi;
}
/* Associating new keymap with existing name */
if (ni >= 0)
{
keymap_names[ni].map = map;
return ni;
}
for (i = 0; keymap_names[i].name; i++)
;
if (keymap_names == builtin_keymap_names)
{
keymap_names = xmalloc ((i + 2) * sizeof (struct name_and_keymap));
memcpy (keymap_names, builtin_keymap_names, i * sizeof (struct name_and_keymap));
}
else
keymap_names = xrealloc (keymap_names, (i + 2) * sizeof (struct name_and_keymap));
keymap_names[i].name = savestring (name);
keymap_names[i].map = map;
keymap_names[i+1].name = NULL;
keymap_names[i+1].map = NULL;
return i;
}
void
rl_set_keymap (Keymap map)
{
+15
View File
@@ -720,6 +720,21 @@ Return the name matching @var{keymap}. @var{name} is one which would
be supplied in a @code{set keymap} inputrc line (@pxref{Readline Init File}).
@end deftypefun
@deftypefun void rl_set_keymap (const char *name, Keymap keymap)
Set the name of @var{keymap}. This name will then be "registered" and
available for use in a @code{set keymap} inputrc directive
@pxref{Readline Init File}).
The @var{name} may not be one of Readline's builtin names;
you may not add a different name for one of Readline's builtin keymaps.
Readline will make a copy of @var{name}.
You may replace the name associated with a given keymap by calling this
function two or more times with the same @var{keymap} argument.
You can associate a registered name with a new keymap by calling this
function two or more times with the same @var{name} argument.
There is no way to remove a named keymap once the name has been
registered.
@end deftypefun
@node Binding Keys
@subsection Binding Keys
+2 -1
View File
@@ -606,7 +606,7 @@ If this variable has not been given a value, the characters @key{ESC} and
@item keymap
@vindex keymap
Sets Readline's idea of the current keymap for key binding commands.
Acceptable @code{keymap} names are
Built-in @code{keymap} names are
@code{emacs},
@code{emacs-standard},
@code{emacs-meta},
@@ -617,6 +617,7 @@ Acceptable @code{keymap} names are
@code{vi-insert}.
@code{vi} is equivalent to @code{vi-command} (@code{vi-move} is also a
synonym); @code{emacs} is equivalent to @code{emacs-standard}.
Applications may add additional names.
The default value is @code{emacs}.
The value of the @code{editing-mode} variable also affects the
default keymap.
+3 -3
View File
@@ -4,7 +4,7 @@ Copyright (C) 1988-2018 Free Software Foundation, Inc.
@set EDITION 8.0
@set VERSION 8.0
@set UPDATED 6 July 2018
@set UPDATED-MONTH July 2018
@set UPDATED 18 September 2018
@set UPDATED-MONTH September 2018
@set LASTCHANGE Fri Jul 6 16:25:22 MDT 2018
@set LASTCHANGE Tue Sep 18 13:08:12 EDT 2018
+10 -5
View File
@@ -327,7 +327,7 @@ _rl_search_getchar (_rl_search_cxt *cxt)
int
_rl_isearch_dispatch (_rl_search_cxt *cxt, int c)
{
int n, wstart, wlen, limit, cval;
int n, wstart, wlen, limit, cval, incr;
rl_command_func_t *f;
f = (rl_command_func_t *)NULL;
@@ -622,20 +622,25 @@ add_character:
/* Add character to search string and continue search. */
default:
if (cxt->search_string_index + 2 >= cxt->search_string_size)
#if defined (HANDLE_MULTIBYTE)
wlen = (cxt->mb[0] == 0 || cxt->mb[1] == 0) ? 1 : RL_STRLEN (cxt->mb);
#else
wlen = 1;
#endif
if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size)
{
cxt->search_string_size += 128;
cxt->search_string_size += 128; /* 128 much greater than MB_CUR_MAX */
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int j, l;
int j;
if (cxt->mb[0] == 0 || cxt->mb[1] == 0)
cxt->search_string[cxt->search_string_index++] = cxt->mb[0];
else
for (j = 0, l = RL_STRLEN (cxt->mb); j < l; )
for (j = 0; j < wlen; )
cxt->search_string[cxt->search_string_index++] = cxt->mb[j++];
}
else
+3
View File
@@ -90,6 +90,9 @@ extern Keymap rl_get_keymap PARAMS((void));
/* Set the current keymap to MAP. */
extern void rl_set_keymap PARAMS((Keymap));
/* Set the name of MAP to NAME */
extern int rl_set_keymap_name PARAMS((const char *, Keymap));
#ifdef __cplusplus
}
#endif
+3
View File
@@ -357,6 +357,9 @@ extern Keymap rl_get_keymap_by_name PARAMS((const char *));
extern char *rl_get_keymap_name PARAMS((Keymap));
extern void rl_set_keymap PARAMS((Keymap));
extern Keymap rl_get_keymap PARAMS((void));
extern int rl_set_keymap_name PARAMS((const char *, Keymap));
/* Undocumented; used internally only. */
extern void rl_set_keymap_from_edit_mode PARAMS((void));
extern char *rl_get_keymap_name_from_edit_mode PARAMS((void));
-1
View File
@@ -396,7 +396,6 @@ save_tty_chars (TIOTYPE *tiop)
/* Currently this is only used on AIX */
static void
rltty_warning (char *msg)
char *msg;
{
_rl_errmsg ("warning: %s", msg);
}
+1 -1
View File
@@ -227,7 +227,7 @@ sh_canonpath (path, flags)
if (result[2] == '\0') /* short-circuit for bare `//' */
result[1] = '\0';
else
strcpy (result, result + 1);
memmove (result, result + 1, strlen (result + 1) + 1);
}
return (result);
+1 -1
View File
@@ -245,7 +245,7 @@ error:
if (result[2] == '\0') /* short-circuit for bare `//' */
result[1] = '\0';
else
strcpy (result, result + 1);
memmove (result, result + 1, strlen (result + 1) + 1);
}
return (result);
+2
View File
@@ -2544,6 +2544,7 @@ next_alias_char:
reading a quoted string. */
#ifndef OLD_ALIAS_HACK
if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE &&
pushed_string_list->flags != PSH_DPAREN &&
shell_input_line_index > 0 &&
shell_input_line[shell_input_line_index-1] != ' ' &&
shell_input_line[shell_input_line_index-1] != '\n' &&
@@ -2555,6 +2556,7 @@ next_alias_char:
#endif
pop_alias:
/* This case works for PSH_DPAREN as well */
if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE)
{
pop_string ();
+5 -1
View File
@@ -1989,7 +1989,11 @@ show_shell_usage (fp, extra)
for (i = 0, set_opts = 0; shell_builtins[i].name; i++)
if (STREQ (shell_builtins[i].name, "set"))
set_opts = savestring (shell_builtins[i].short_doc);
{
set_opts = savestring (shell_builtins[i].short_doc);
break;
}
if (set_opts)
{
s = strchr (set_opts, '[');
+3
View File
@@ -574,6 +574,7 @@ termsig_handler (sig)
#if defined (JOB_CONTROL)
if (sig == SIGHUP && (interactive || (subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB))))
hangup_all_jobs ();
if ((subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB)) == 0)
end_job_control ();
#endif /* JOB_CONTROL */
@@ -598,6 +599,8 @@ termsig_handler (sig)
if (dollar_dollar_pid != 1)
exit (128+sig); /* just in case the kill fails? */
/* We get here only under extraordinary circumstances. */
/* We are PID 1, and the kill above failed to kill the process. We assume
this means that we are running as an init process in a pid namespace
on Linux. In this case, we can't send ourselves a fatal signal, so we
+22 -2
View File
@@ -5844,7 +5844,24 @@ process_substitute (string, open_for_read_in_child)
set_sigint_handler ();
#if defined (JOB_CONTROL)
/* make sure we don't have any job control */
set_job_control (0);
/* The idea is that we want all the jobs we start from an async process
substitution to be in the same process group, but not the same pgrp
as our parent shell, since we don't want to affect our parent shell's
jobs if we get a SIGHUP and end up calling hangup_all_jobs, for example.
If pipeline_pgrp != shell_pgrp, we assume that there is a job control
shell somewhere in our parent process chain (since make_child initializes
pipeline_pgrp to shell_pgrp if job_control == 0). What we do in this
case is to set pipeline_pgrp to our PID, so all jobs started by this
process have that same pgrp and we are basically the process group leader.
This should not have negative effects on child processes surviving
after we exit, since we wait for the children we create, but that is
something to watch for. */
if (pipeline_pgrp != shell_pgrp)
pipeline_pgrp = getpid ();
#endif /* JOB_CONTROL */
#if !defined (HAVE_DEV_FD)
@@ -6914,6 +6931,7 @@ parameter_brace_expand_rhs (name, value, op, quoted, pflags, qdollaratp, hasdoll
{
report_error (_("%s: invalid indirect expansion"), name);
free (vname);
free (t1);
dispose_word (w);
return &expand_wdesc_error;
}
@@ -6921,6 +6939,7 @@ parameter_brace_expand_rhs (name, value, op, quoted, pflags, qdollaratp, hasdoll
{
report_error (_("%s: invalid variable name"), vname);
free (vname);
free (t1);
dispose_word (w);
return &expand_wdesc_error;
}
@@ -7523,8 +7542,9 @@ parameter_list_transform (xc, itype, quoted)
if (list == 0)
return ((char *)NULL);
if (xc == 'A')
return (pos_params_assignment (list, itype, quoted));
ret = list_transform (xc, (SHELL_VAR *)0, list, itype, quoted);
ret = pos_params_assignment (list, itype, quoted);
else
ret = list_transform (xc, (SHELL_VAR *)0, list, itype, quoted);
dispose_words (list);
return (ret);
}
+1 -1
View File
@@ -522,6 +522,7 @@ read_man_page(char *filename)
man_buf[buf_size] = '\n';
man_buf[buf_size + 1] = man_buf[buf_size + 2] = '\0';
} else {
free(man_buf);
man_buf = NULL;
}
fclose(man_stream);
@@ -2562,7 +2563,6 @@ scan_request(char *c)
h = name;
if (stat(h, &stbuf) != -1)
l = stbuf.st_size;
buf = stralloc(l + 4);
#if NOCGI
if (!out_length) {
char *t, *s;
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/bash/bash-current
BUILD_DIR=/usr/local/build/chet/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+18 -18
View File
@@ -49,7 +49,7 @@ declare -a f=([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element"
./array.tests: line 103: a: readonly variable
./array.tests: line 105: b[]: bad array subscript
./array.tests: line 106: b[*]: bad array subscript
./array.tests: line 107: ${b[ ]}: bad substitution
this
./array.tests: line 109: c[-2]: bad array subscript
./array.tests: line 110: c: bad array subscript
@@ -579,9 +579,9 @@ def ghi
jkl
1. indexed:
reference:
./array25.sub: line 10: ${a[ ]}: bad substitution
1. 0
./array25.sub: line 11: ' ': syntax error: operand expected (error token is "' '")
./array25.sub: line 12: ${a[ ]}: bad substitution
3. 0
4. 0
5. 0
6. 0
@@ -591,19 +591,19 @@ assignment:
3.declare -a a=([0]="12" [1]="1")
4.declare -a a=([0]="13" [1]="1")
arithmetic:
1.declare -a a=([0]="0" [1]="1")
2.declare -a a=([0]="0" [1]="1")
3.declare -a a=([0]="0" [1]="1")
4.declare -a a=([0]="0" [1]="1")
5.declare -a a=([0]="0" [1]="1")
1.declare -a a=([0]="10" [1]="1")
2.declare -a a=([0]="11" [1]="1")
3.declare -a a=([0]="12" [1]="1")
4.declare -a a=([0]="13" [1]="1")
5.declare -a a=([0]="10" [1]="1")
6.declare -a a=([0]="11" [1]="1")
7.declare -a a=([0]="0" [1]="1")
7.declare -a a=([0]="12" [1]="1")
8.declare -a a=([0]="13" [1]="1")
2. associative:
reference:
./array25.sub: line 47: ${a[ ]}: bad substitution
1.
2.
./array25.sub: line 49: ${a[ ]}: bad substitution
3.
4.
5.
6.
@@ -613,14 +613,14 @@ assignment:
3.declare -A a=([" "]="12" [0]="0" [1]="1" )
4.declare -A a=([" "]="13" [0]="0" [1]="1" )
arithmetic:
1.declare -A a=([" "]="13" [0]="0" [1]="1" )
2.declare -A a=([" "]="13" [0]="0" [1]="1" )
3.declare -A a=([" "]="13" [0]="0" [1]="1" )
1.declare -A a=([" "]="10" [0]="0" [1]="1" )
2.declare -A a=([" "]="11" [0]="0" [1]="1" )
3.declare -A a=([" "]="12" [0]="0" [1]="1" )
4.declare -A a=([" "]="13" [0]="0" [1]="1" )
5.declare -A a=([" "]="13" [0]="0" [1]="1" )
6.declare -A a=([" "]="13" [0]="0" [1]="1" ["\" \""]="11" )
7.declare -A a=([" "]="13" [0]="0" [1]="1" ["\" \""]="11" )
8.declare -A a=([" "]="13" [0]="0" [1]="1" ["\" \""]="13" )
5.declare -A a=([" "]="10" [0]="0" [1]="1" )
6.declare -A a=([" "]="10" [0]="0" [1]="1" ["\" \""]="11" )
7.declare -A a=([" "]="12" [0]="0" [1]="1" ["\" \""]="11" )
8.declare -A a=([" "]="12" [0]="0" [1]="1" ["\" \""]="13" )
argv[1] = <aa>
argv[2] = <bb>
argv[1] = <aa>
+8 -2
View File
@@ -126,8 +126,10 @@ after readonly assignment
after 1: 1
after 2: 1
after 3: 1
array after 1: 1
array after 2: 1
4
array after 1: 0
array after 2: 0
./errors6.sub: uvar: parameter not set
./errors6.sub: uvar: parameter null or not set
@@ -144,6 +146,10 @@ unset
./errors6.sub: line 41: invalid-ident: invalid variable name
./errors6.sub: line 42: invalid-ident: invalid variable name
./errors6.sub: line 43: invalid-ident: invalid variable name
4
array after 1: 0
array after 2: 0
./errors6.sub: uvar: parameter not set
./errors6.sub: uvar: parameter null or not set
+5
View File
@@ -3373,6 +3373,11 @@ bind_int_variable (lhs, rhs, flags)
isarr = 1;
v = array_variable_part (lhs, (flags & ASS_NOEXPAND) != 0, (char **)0, (int *)0);
}
else if (legal_identifier (lhs) == 0)
{
sh_invalidid (lhs);
return ((SHELL_VAR *)NULL);
}
else
#endif
v = find_variable (lhs);