- word_list_split: if a word expands to nothing after expansion and
splitting, but we saw a quoted null during the expansion
(W_SAWQUOTEDNULL), return an empty word
+
+ 7/25
+ ----
+
+subst.c
+ - do_compound_assignment: if creating a local variable, make sure to
+ set `newname' to the name of the variable returned from find_variable,
+ since that follows namerefs. Fixes issue raised by Grisha Levit
+ <grishalevit@gmail.com>
+
+ 7/29
+ ----
+subst.c
+ - get_var_and_type: if VALUE is NULL, check before calling dequote_string.
+ Report and fix from Grisha Levit <grishalevit@gmail.com>
/* If we have an assignment builtin that does not create local variables,
make sure we create global variables even if we internally call
`declare'. The CHKLOCAL flag means to set attributes or values on
- an existing local variable */
+ an existing local variable, if there is one. */
if (b && ((b->flags & (ASSIGNMENT_BUILTIN|LOCALVAR_BUILTIN)) == ASSIGNMENT_BUILTIN))
w->word->flags |= W_ASSNGLOBAL|W_CHKLOCAL;
+#if 0
+ else if (b && (b->flags & ASSIGNMENT_BUILTIN) && (b->flags & LOCALVAR_BUILTIN))
+ w->word->flags |= W_CHKLOCAL;
+#endif
}
#if defined (ARRAY_VARS)
/* Note that we saw an associative array option to a builtin that takes
if (mklocal && variable_context)
{
- v = find_variable (name);
- newname = (v == 0) ? nameref_transform_name (name, flags) : name;
+ v = find_variable (name); /* follows namerefs */
+ newname = (v == 0) ? nameref_transform_name (name, flags) : v->name;
if (v && ((readonly_p (v) && (flags & ASS_FORCE) == 0) || noassign_p (v)))
{
if (readonly_p (v))
vtype = VT_VARIABLE;
*varp = v;
if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
- *valp = dequote_string (value);
+ *valp = value ? dequote_string (value) : savestring ("");
else
- *valp = dequote_escapes (value);
+ *valp = value ? dequote_escapes (value) : (char *)NULL;
}
else
{
-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
0000003
0000000 101 040 302 243 040 305 222 012
0000010
-./unicode3.sub: line 3: $'5\247@3\231+\306S8\237\242\352\263': command not found
-./unicode3.sub: line 5: cd: $'5\247@3\231+\306S8\237\242\352\263': No such file or directory
+./unicode3.sub: line 5: $'5\247@3\231+\306S8\237\242\352\263': command not found
+./unicode3.sub: line 7: cd: $'5\247@3\231+\306S8\237\242\352\263': No such file or directory
$'5\247@3\231+\306S8\237\242\352\263'
+ : $'5\247@3\231+\306S8\237\242\352\263'
++ set +x
outside:
./nameref20.sub: line 45: declare: ref: not found
./nameref20.sub: line 45: declare: var: not found
+declare -n ref="var"
+declare -a var=([0]="Y")
declare -p ref var
unset -f f
+
+unset -n ref; unset var
+
+f()
+{
+ declare var=X; declare -n ref=var; declare ref=(Y)
+ declare -p ref var
+}
+f
export LANG=en_US.UTF-8 # make sure
+
+cd $TMPDIR # try to avoid NFS artifacts
payload=$'\065\247\100\063\231\053\306\123\070\237\242\352\263'
"$payload"
printf %q "$payload"
echo
-set -x ; : "$payload"
+set -x ; : "$payload" ; set +x
+cd $OLDPWD
static SHELL_VAR *bind_invalid_envvar __P((const char *, char *, int));
+static int var_sametype __P((SHELL_VAR *, SHELL_VAR *));
+
static SHELL_VAR *hash_lookup __P((const char *, HASH_TABLE *));
static SHELL_VAR *new_shell_variable __P((const char *));
static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *));
/* */
/* **************************************************************** */
+static int
+var_sametype (v1, v2)
+ SHELL_VAR *v1;
+ SHELL_VAR *v2;
+{
+ if (v1 == 0 || v2 == 0)
+ return 0;
+#if defined (ARRAY_VARS)
+ else if (assoc_p (v1) && assoc_p (v2))
+ return 1;
+ else if (array_p (v1) && array_p (v2))
+ return 1;
+ else if (array_p (v1) || array_p (v2))
+ return 0;
+ else if (assoc_p (v1) || assoc_p (v2))
+ return 0;
+#endif
+ else
+ return 1;
+}
+
+int
+validate_inherited_value (var, type)
+ SHELL_VAR *var;
+ int type;
+{
+#if defined (ARRAY_VARS)
+ if (type == att_array && assoc_p (var))
+ return 0;
+ else if (type == att_assoc && array_p (var))
+ return 0;
+ else
+#endif
+ return 1; /* should we run convert_var_to_array here or let the caller? */
+}
+
/* Set NAME to VALUE if NAME has no value. */
SHELL_VAR *
set_if_not (name, value)
if (var == 0 || array_p (var) || (assoc_ok && assoc_p (var)))
return var;
+ /* Validate any value we inherited from a variable instance at a previous
+ scope and disard anything that's invalid. */
+
array = array_create ();
dispose_variable_value (var);
if (var == 0 || assoc_p (var) || (array_ok && array_p (var)))
return var;
+ /* Validate any value we inherited from a variable instance at a previous
+ scope and disard anything that's invalid. */
+
dispose_variable_value (var);
hash = assoc_create (0);
functions no longer behave like assignment statements preceding
special builtins, and do not persist in the current shell environment.
This is austin group interp #654, though nobody implements it yet. */
- posix_var_behavior = posixly_correct && (shell_compatibility_level < 50 || vc_isfuncenv (shell_variables) == 0);
+ posix_var_behavior = posixly_correct;
if (local_p (var) && STREQ (var->name, "-"))
set_current_options (value_cell (var));
extern pid_t dollar_dollar_pid;
extern void initialize_shell_variables __P((char **, int));
+
+extern int validate_inherited_value __P((SHELL_VAR *, int));
+
extern SHELL_VAR *set_if_not __P((char *, char *));
extern void sh_set_lines_and_columns __P((int, int));