summaryrefslogtreecommitdiffstats
path: root/source/a/bash/bash-5.1-patches/bash51-004
blob: 39a6c647fef4269550554f92d992259c42c9c247 (plain) (blame)
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
120
121
122
123
124
125
126
			     BASH PATCH REPORT
			     =================

Bash-Release:	5.1
Patch-ID:	bash51-004

Bug-Reported-by:	oguzismailuysal@gmail.com
Bug-Reference-ID:	<CAH7i3LoHGmwaghDpCWRUfcY04gQmeDTH3RiG=bf2b=KbU=gyhw@mail.gmail.com>
Bug-Reference-URL:	https://lists.gnu.org/archive/html/bug-bash/2020-12/msg00039.html

Bug-Description:

If a key-value compound array assignment to an associative array is supplied
as an assignment statement argument to the `declare' command that declares the
array, the assignment doesn't perform the correct word expansions.

This patch makes key-value assignment and subscript assignment perform the
same expansions when they're supplied as an argument to `declare'.

Patch (apply with `patch -p0'):

*** ../bash-5.1-patched/arrayfunc.c	2020-10-09 11:38:58.000000000 -0400
--- arrayfunc.c	2020-12-11 15:12:22.000000000 -0500
***************
*** 598,601 ****
--- 598,622 ----
      }
  }
+ 
+ /* Return non-zero if L appears to be a key-value pair associative array
+    compound assignment. */ 
+ int
+ kvpair_assignment_p (l)
+      WORD_LIST *l;
+ {
+   return (l && (l->word->flags & W_ASSIGNMENT) == 0 && l->word->word[0] != '[');	/*]*/
+ }
+ 
+ char *
+ expand_and_quote_kvpair_word (w)
+      char *w;
+ {
+   char *t, *r;
+ 
+   t = w ? expand_assignment_string_to_string (w, 0) : 0;
+   r = sh_single_quote (t ? t : "");
+   free (t);
+   return r;
+ }
  #endif
       
***************
*** 641,645 ****
  
  #if ASSOC_KVPAIR_ASSIGNMENT
!   if (assoc_p (var) && nlist && (nlist->word->flags & W_ASSIGNMENT) == 0 && nlist->word->word[0] != '[')	/*]*/
      {
        iflags = flags & ~ASS_APPEND;
--- 662,666 ----
  
  #if ASSOC_KVPAIR_ASSIGNMENT
!   if (assoc_p (var) && kvpair_assignment_p (nlist))
      {
        iflags = flags & ~ASS_APPEND;
*** ../bash-5.1-patched/arrayfunc.h	2020-04-29 17:24:15.000000000 -0400
--- arrayfunc.h	2020-12-11 14:23:50.000000000 -0500
***************
*** 68,71 ****
--- 68,74 ----
  extern void quote_compound_array_list PARAMS((WORD_LIST *, int));
  
+ extern int kvpair_assignment_p PARAMS((WORD_LIST *));
+ extern char *expand_and_quote_kvpair_word PARAMS((char *));
+ 
  extern int unbind_array_element PARAMS((SHELL_VAR *, char *, int));
  extern int skipsubscript PARAMS((const char *, int, int));
*** ../bash-5.1-patched/subst.c	2020-11-16 10:33:15.000000000 -0500
--- subst.c	2020-12-11 15:11:10.000000000 -0500
***************
*** 11605,11608 ****
--- 11605,11609 ----
    WORD_LIST *l, *nl;
    char *t;
+   int kvpair;
    
    if (flags == 0)
***************
*** 11619,11622 ****
--- 11620,11627 ----
        /* Associative array */
        l = parse_string_to_word_list (value, 1, "array assign");
+ #if ASSOC_KVPAIR_ASSIGNMENT
+       kvpair = kvpair_assignment_p (l);
+ #endif
+ 
        /* For associative arrays, with their arbitrary subscripts, we have to
  	 expand and quote in one step so we don't have to search for the
***************
*** 11624,11627 ****
--- 11629,11638 ----
        for (nl = l; nl; nl = nl->next)
  	{
+ #if ASSOC_KVPAIR_ASSIGNMENT
+ 	  if (kvpair)
+ 	    /* keys and values undergo the same set of expansions */
+ 	    t = expand_and_quote_kvpair_word (nl->word->word);
+ 	  else
+ #endif
  	  if ((nl->word->flags & W_ASSIGNMENT) == 0)
  	    t = sh_single_quote (nl->word->word ? nl->word->word : "");

*** ../bash-5.1/patchlevel.h	2020-06-22 14:51:03.000000000 -0400
--- patchlevel.h	2020-10-01 11:01:28.000000000 -0400
***************
*** 26,30 ****
     looks for to find the patch level (for the sccs version string). */
  
! #define PATCHLEVEL 3
  
  #endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
     looks for to find the patch level (for the sccs version string). */
  
! #define PATCHLEVEL 4
  
  #endif /* _PATCHLEVEL_H_ */