If `declare -g' is supplied with a compound assignment when referring to an
existing global associative array, it attempts to convert the global
variable to an indexed
array.

$ declare -A A=(x x)
$ f() { declare -g A=([1]=1); }
$ (f)
bash: '1': arithmetic syntax error: operand expected (error token is "'1'")
$ f() { declare -g A=(1 1); }
$ (f; declare -p A)
declare -a A=([0]="'1'" [1]="'1'")

Also there is seemingly a potential for uninitialized access of the
variable `r' in the surrounding code. I don't think it's actually ever an
issue but -Wuninitialized complains.
---
diff --git a/subst.c b/subst.c
index fb69d5dc..c7e64f76 100644
--- a/subst.c
+++ b/subst.c
@@ -3446,8 +3446,7 @@ do_compound_assignment (const char *name, char
*value, int flags)
        v = make_local_assoc_variable (newname, 0);
       else if (v == 0 || (array_p (v) == 0 && assoc_p (v) == 0) ||
v->context != variable_context)
         v = make_local_array_variable (newname, 0);
-      if (v)
-       r = assign_compound_array_list (v, list, flags);
+      r = v ? assign_compound_array_list (v, list, flags) : 0;
       if (list)
        dispose_words (list);
       if (r == 0)              /* compound assignment error */
@@ -3477,10 +3476,9 @@ do_compound_assignment (const char *name, char
*value, int flags)
        v = convert_var_to_assoc (v);
       else if (v == 0)
        v = make_new_array_variable (newname);
-      else if (v && mkassoc == 0 && array_p (v) == 0)
+      else if (v && mkassoc == 0 && array_p (v) == 0 && assoc_p (v) == 0)
        v = convert_var_to_array (v);
-      if (v)
-       r = assign_compound_array_list (v, list, flags);
+      r = v ? assign_compound_array_list (v, list, flags) : 0;
       if (list)
        dispose_words (list);
       if (r == 0)              /* compound assignment error */

Reply via email to