BASH PATCH REPORT ================= Bash-Release: 4.2 Patch-ID: bash42-025 Bug-Reported-by: Bill Gradwohl Bug-Reference-ID: Bug-Reference-URL: http://lists.gnu.org/archive/html/help-bash/2012-03/msg00078.html Bug-Description: When used in a shell function, `declare -g -a array=(compound assignment)' creates a local variable instead of a global one. Patch (apply with `patch -p0'): *** ../bash-4.2-patched/command.h 2010-08-02 19:36:51.000000000 -0400 --- ./command.h 2012-04-01 12:38:35.000000000 -0400 *************** *** 98,101 **** --- 98,102 ---- #define W_ASSIGNASSOC 0x400000 /* word looks like associative array assignment */ #define W_ARRAYIND 0x800000 /* word is an array index being expanded */ + #define W_ASSNGLOBAL 0x1000000 /* word is a global assignment to declare (declare/typeset -g) */ /* Possible values for subshell_environment */ *** ../bash-4.2-patched/execute_cmd.c 2011-11-21 18:03:41.000000000 -0500 --- ./execute_cmd.c 2012-04-01 12:42:03.000000000 -0400 *************** *** 3581,3585 **** WORD_LIST *w; struct builtin *b; ! int assoc; if (words == 0) --- 3581,3585 ---- WORD_LIST *w; struct builtin *b; ! int assoc, global; if (words == 0) *************** *** 3587,3591 **** b = 0; ! assoc = 0; for (w = words; w; w = w->next) --- 3587,3591 ---- b = 0; ! assoc = global = 0; for (w = words; w; w = w->next) *************** *** 3604,3607 **** --- 3604,3609 ---- if (assoc) w->word->flags |= W_ASSIGNASSOC; + if (global) + w->word->flags |= W_ASSNGLOBAL; #endif } *************** *** 3609,3613 **** /* Note that we saw an associative array option to a builtin that takes assignment statements. This is a bit of a kludge. */ ! else if (w->word->word[0] == '-' && strchr (w->word->word, 'A')) { if (b == 0) --- 3611,3618 ---- /* Note that we saw an associative array option to a builtin that takes assignment statements. This is a bit of a kludge. */ ! else if (w->word->word[0] == '-' && (strchr (w->word->word+1, 'A') || strchr (w->word->word+1, 'g'))) ! #else ! else if (w->word->word[0] == '-' && strchr (w->word->word+1, 'g')) ! #endif { if (b == 0) *************** *** 3619,3626 **** words->word->flags |= W_ASSNBLTIN; } ! if (words->word->flags & W_ASSNBLTIN) assoc = 1; } - #endif } --- 3624,3632 ---- words->word->flags |= W_ASSNBLTIN; } ! if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'A')) assoc = 1; + if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'g')) + global = 1; } } *** ../bash-4.2-patched/subst.c 2012-03-11 17:35:13.000000000 -0400 --- ./subst.c 2012-04-01 12:38:35.000000000 -0400 *************** *** 367,370 **** --- 367,375 ---- fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : ""); } + if (f & W_ASSNGLOBAL) + { + f &= ~W_ASSNGLOBAL; + fprintf (stderr, "W_ASSNGLOBAL%s", f ? "|" : ""); + } if (f & W_COMPASSIGN) { *************** *** 2804,2808 **** else if (assign_list) { ! if (word->flags & W_ASSIGNARG) aflags |= ASS_MKLOCAL; if (word->flags & W_ASSIGNASSOC) --- 2809,2813 ---- else if (assign_list) { ! if ((word->flags & W_ASSIGNARG) && (word->flags & W_ASSNGLOBAL) == 0) aflags |= ASS_MKLOCAL; if (word->flags & W_ASSIGNASSOC) *** ../bash-4.2-patched/patchlevel.h Sat Jun 12 20:14:48 2010 --- ./patchlevel.h Thu Feb 24 21:41:34 2011 *************** *** 26,30 **** looks for to find the patch level (for the sccs version string). */ ! #define PATCHLEVEL 24 #endif /* _PATCHLEVEL_H_ */ --- 26,30 ---- looks for to find the patch level (for the sccs version string). */ ! #define PATCHLEVEL 25 #endif /* _PATCHLEVEL_H_ */