File: bash42-025.diff

package info (click to toggle)
bash 4.2%2Bdfsg-0.1%2Bdeb7u3
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 3,308 kB
  • sloc: ansic: 452; sh: 418; makefile: 385
file content (119 lines) | stat: -rw-r--r-- 3,639 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
			     BASH PATCH REPORT
			     =================

Bash-Release:	4.2
Patch-ID:	bash42-025

Bug-Reported-by:	Bill Gradwohl <bill@ycc.com>
Bug-Reference-ID:	<CAFyvKis-UfuOWr5THBRKh=vYHDoKEEgdW8hN1RviTuYQ00Lu5A@mail.gmail.com>
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'):

Index: b/bash/command.h
===================================================================
--- a/bash/command.h
+++ b/bash/command.h
@@ -97,6 +97,7 @@
 #define W_HASCTLESC	0x200000	/* word contains literal CTLESC characters */
 #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 */
 #define SUBSHELL_ASYNC	0x01	/* subshell caused by `command &' */
Index: b/bash/execute_cmd.c
===================================================================
--- a/bash/execute_cmd.c
+++ b/bash/execute_cmd.c
@@ -3580,13 +3580,13 @@
 {
   WORD_LIST *w;
   struct builtin *b;
-  int assoc;
+  int assoc, global;
 
   if (words == 0)
     return;
 
   b = 0;
-  assoc = 0;
+  assoc = global = 0;
 
   for (w = words; w; w = w->next)
     if (w->word->flags & W_ASSIGNMENT)
@@ -3603,12 +3603,17 @@
 #if defined (ARRAY_VARS)
 	if (assoc)
 	  w->word->flags |= W_ASSIGNASSOC;
+	if (global)
+	  w->word->flags |= W_ASSNGLOBAL;
 #endif
       }
 #if defined (ARRAY_VARS)
     /* 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'))
+    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)
 	  {
@@ -3618,10 +3623,11 @@
 	    else if (b && (b->flags & ASSIGNMENT_BUILTIN))
 	      words->word->flags |= W_ASSNBLTIN;
 	  }
-	if (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;
       }
-#endif
 }
 
 /* Return 1 if the file found by searching $PATH for PATHNAME, defaulting
Index: b/bash/patchlevel.h
===================================================================
--- a/bash/patchlevel.h
+++ b/bash/patchlevel.h
@@ -25,6 +25,6 @@
    regexp `^#define[ 	]*PATCHLEVEL', since that's what support/mkversion.sh
    looks for to find the patch level (for the sccs version string). */
 
-#define PATCHLEVEL 24
+#define PATCHLEVEL 25
 
 #endif /* _PATCHLEVEL_H_ */
Index: b/bash/subst.c
===================================================================
--- a/bash/subst.c
+++ b/bash/subst.c
@@ -366,6 +366,11 @@
       f &= ~W_ASSNBLTIN;
       fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");
     }
+  if (f & W_ASSNGLOBAL)
+    {
+      f &= ~W_ASSNGLOBAL;
+      fprintf (stderr, "W_ASSNGLOBAL%s", f ? "|" : "");
+    }
   if (f & W_COMPASSIGN)
     {
       f &= ~W_COMPASSIGN;
@@ -2803,7 +2808,7 @@
     }
   else if (assign_list)
     {
-      if (word->flags & W_ASSIGNARG)
+      if ((word->flags & W_ASSIGNARG) && (word->flags & W_ASSNGLOBAL) == 0)
 	aflags |= ASS_MKLOCAL;
       if (word->flags & W_ASSIGNASSOC)
 	aflags |= ASS_MKASSOC;