From 3d31a311dab4cafaa3400ec2faadf0f384115aed Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Tue, 25 Sep 2018 09:54:29 -0400 Subject: [PATCH] commit bash-20180921 snapshot --- CWRU/CWRU.chlog | 94 ++++++++++++++++++++++++++++++ arrayfunc.c | 10 ++-- builtins/fc.def | 1 + execute_cmd.c | 6 +- expr.c | 5 +- lib/glob/glob.c | 2 + lib/readline/bind.c | 105 +++++++++++++++++++++++++++++----- lib/readline/doc/rltech.texi | 15 +++++ lib/readline/doc/rluser.texi | 3 +- lib/readline/doc/version.texi | 6 +- lib/readline/isearch.c | 15 +++-- lib/readline/keymaps.h | 3 + lib/readline/readline.h | 3 + lib/readline/rltty.c | 1 - lib/sh/pathcanon.c | 2 +- lib/sh/pathphys.c | 2 +- parse.y | 2 + shell.c | 6 +- sig.c | 3 + subst.c | 24 +++++++- support/man2html.c | 2 +- tests/RUN-ONE-TEST | 2 +- tests/array.right | 36 ++++++------ tests/errors.right | 10 +++- variables.c | 5 ++ 25 files changed, 306 insertions(+), 57 deletions(-) diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 7ce075c2..9b411680 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -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 + + 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 + +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 + +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 + +builtins/fc.def,execute_cmd.c + - fixed some missing free()s uncovered by coverity. Report from + Siteshwar Vashisht + +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 + + 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 + +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 + diff --git a/arrayfunc.c b/arrayfunc.c index e3700dd3..9905b44d 100644 --- a/arrayfunc.c +++ b/arrayfunc.c @@ -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++) diff --git a/builtins/fc.def b/builtins/fc.def index da0f0bcb..62a28c4c 100644 --- a/builtins/fc.def +++ b/builtins/fc.def @@ -419,6 +419,7 @@ fc_builtin (list) { sh_wrerror (); fclose (stream); + FREE (fn); return (EXECUTION_FAILURE); } fclose (stream); diff --git a/execute_cmd.c b/execute_cmd.c index 1c95a93b..3735b552 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -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) diff --git a/expr.c b/expr.c index cc7c9e9a..4a1f6070 100644 --- a/expr.c +++ b/expr.c @@ -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"); diff --git a/lib/glob/glob.c b/lib/glob/glob.c index 774435f1..22d90a5c 100644 --- a/lib/glob/glob.c +++ b/lib/glob/glob.c @@ -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') diff --git a/lib/readline/bind.c b/lib/readline/bind.c index 2e05b460..57ae10f7 100644 --- a/lib/readline/bind.c +++ b/lib/readline/bind.c @@ -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) { diff --git a/lib/readline/doc/rltech.texi b/lib/readline/doc/rltech.texi index baf036df..3624ea3e 100644 --- a/lib/readline/doc/rltech.texi +++ b/lib/readline/doc/rltech.texi @@ -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 diff --git a/lib/readline/doc/rluser.texi b/lib/readline/doc/rluser.texi index 1acc8cda..48b32e91 100644 --- a/lib/readline/doc/rluser.texi +++ b/lib/readline/doc/rluser.texi @@ -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. diff --git a/lib/readline/doc/version.texi b/lib/readline/doc/version.texi index 79f41917..7e08db61 100644 --- a/lib/readline/doc/version.texi +++ b/lib/readline/doc/version.texi @@ -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 diff --git a/lib/readline/isearch.c b/lib/readline/isearch.c index fa58e848..3c5f74b2 100644 --- a/lib/readline/isearch.c +++ b/lib/readline/isearch.c @@ -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 diff --git a/lib/readline/keymaps.h b/lib/readline/keymaps.h index af8d5d99..1fa853d8 100644 --- a/lib/readline/keymaps.h +++ b/lib/readline/keymaps.h @@ -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 diff --git a/lib/readline/readline.h b/lib/readline/readline.h index 4e08b2e9..da782716 100644 --- a/lib/readline/readline.h +++ b/lib/readline/readline.h @@ -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)); diff --git a/lib/readline/rltty.c b/lib/readline/rltty.c index 2ee36a7c..d0cd5727 100644 --- a/lib/readline/rltty.c +++ b/lib/readline/rltty.c @@ -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); } diff --git a/lib/sh/pathcanon.c b/lib/sh/pathcanon.c index f19bd55f..f9506dff 100644 --- a/lib/sh/pathcanon.c +++ b/lib/sh/pathcanon.c @@ -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); diff --git a/lib/sh/pathphys.c b/lib/sh/pathphys.c index 26016b76..99390cef 100644 --- a/lib/sh/pathphys.c +++ b/lib/sh/pathphys.c @@ -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); diff --git a/parse.y b/parse.y index 0eb64130..2013d249 100644 --- a/parse.y +++ b/parse.y @@ -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 (); diff --git a/shell.c b/shell.c index a9659bb8..3b60ba7d 100644 --- a/shell.c +++ b/shell.c @@ -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, '['); diff --git a/sig.c b/sig.c index 8daec14b..6f324981 100644 --- a/sig.c +++ b/sig.c @@ -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 diff --git a/subst.c b/subst.c index 906b7ac5..c12670bd 100644 --- a/subst.c +++ b/subst.c @@ -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); } diff --git a/support/man2html.c b/support/man2html.c index 3ab105f3..b10cb959 100644 --- a/support/man2html.c +++ b/support/man2html.c @@ -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; diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index 554f3d6e..58c375b7 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -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 diff --git a/tests/array.right b/tests/array.right index 3c465248..02059257 100644 --- a/tests/array.right +++ b/tests/array.right @@ -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] = argv[2] = argv[1] = diff --git a/tests/errors.right b/tests/errors.right index 4bf478b0..7627450b 100644 --- a/tests/errors.right +++ b/tests/errors.right @@ -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 diff --git a/variables.c b/variables.c index 00872d64..c7429fca 100644 --- a/variables.c +++ b/variables.c @@ -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);