]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/bash/bash50-003
Merge branch 'next'
[ipfire-2.x.git] / src / patches / bash / bash50-003
CommitLineData
415fb8b5
PM
1 BASH PATCH REPORT
2 =================
3
4Bash-Release: 5.0
5Patch-ID: bash50-003
6
7Bug-Reported-by: Andrew Church <achurch+bash@achurch.org>
8Bug-Reference-ID: <5c534aa2.04371@msgid.achurch.org>
9Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2019-01/msg00276.html
10
11Bug-Description:
12
13There are several incompatibilities in how bash-5.0 processes pathname
14expansion (globbing) of filename arguments that have backslashes in the
15directory portion.
16
17Patch (apply with `patch -p0'):
18
19*** ../bash-5.0-patched/lib/glob/glob_loop.c 2019-01-16 16:13:21.000000000 -0500
20--- lib/glob/glob_loop.c 2019-02-01 09:45:11.000000000 -0500
21***************
22*** 27,34 ****
23 register const GCHAR *p;
24 register GCHAR c;
25! int bopen;
26
27 p = pattern;
28! bopen = 0;
29
30 while ((c = *p++) != L('\0'))
31--- 27,34 ----
32 register const GCHAR *p;
33 register GCHAR c;
34! int bopen, bsquote;
35
36 p = pattern;
37! bopen = bsquote = 0;
38
39 while ((c = *p++) != L('\0'))
40***************
41*** 56,66 ****
42 case L('\\'):
43 /* Don't let the pattern end in a backslash (GMATCH returns no match
44! if the pattern ends in a backslash anyway), but otherwise return 1,
45! since the matching engine uses backslash as an escape character
46! and it can be removed. */
47! return (*p != L('\0'));
48 }
49
50! return 0;
51 }
52
53--- 56,75 ----
54 case L('\\'):
55 /* Don't let the pattern end in a backslash (GMATCH returns no match
56! if the pattern ends in a backslash anyway), but otherwise note that
57! we have seen this, since the matching engine uses backslash as an
58! escape character and it can be removed. We return 2 later if we
59! have seen only backslash-escaped characters, so interested callers
60! know they can shortcut and just dequote the pathname. */
61! if (*p != L('\0'))
62! {
63! p++;
64! bsquote = 1;
65! continue;
66! }
67! else /* (*p == L('\0')) */
68! return 0;
69 }
70
71! return bsquote ? 2 : 0;
72 }
73
74*** ../bash-5.0-patched/lib/glob/glob.h 2013-10-28 14:46:12.000000000 -0400
75--- lib/glob/glob.h 2019-03-07 11:06:47.000000000 -0500
76***************
77*** 31,34 ****
78--- 31,35 ----
79 #define GX_ADDCURDIR 0x200 /* internal -- add passed directory name */
80 #define GX_GLOBSTAR 0x400 /* turn on special handling of ** */
81+ #define GX_RECURSE 0x800 /* internal -- glob_filename called recursively */
82
83 extern int glob_pattern_p __P((const char *));
84*** ../bash-5.0-patched/lib/glob/glob.c 2018-09-20 10:53:23.000000000 -0400
85--- lib/glob/glob.c 2019-03-07 14:23:43.000000000 -0500
86***************
87*** 1062,1066 ****
88 unsigned int directory_len;
89 int free_dirname; /* flag */
90! int dflags;
91
92 result = (char **) malloc (sizeof (char *));
93--- 1078,1082 ----
94 unsigned int directory_len;
95 int free_dirname; /* flag */
96! int dflags, hasglob;
97
98 result = (char **) malloc (sizeof (char *));
99***************
100*** 1111,1117 ****
101 }
102
103 /* If directory_name contains globbing characters, then we
104! have to expand the previous levels. Just recurse. */
105! if (directory_len > 0 && glob_pattern_p (directory_name))
106 {
107 char **directories, *d, *p;
108--- 1127,1136 ----
109 }
110
111+ hasglob = 0;
112 /* If directory_name contains globbing characters, then we
113! have to expand the previous levels. Just recurse.
114! If glob_pattern_p returns != [0,1] we have a pattern that has backslash
115! quotes but no unquoted glob pattern characters. We dequote it below. */
116! if (directory_len > 0 && (hasglob = glob_pattern_p (directory_name)) == 1)
117 {
118 char **directories, *d, *p;
119***************
120*** 1176,1180 ****
121 d[directory_len - 1] = '\0';
122
123! directories = glob_filename (d, dflags);
124
125 if (free_dirname)
126--- 1195,1199 ----
127 d[directory_len - 1] = '\0';
128
129! directories = glob_filename (d, dflags|GX_RECURSE);
130
131 if (free_dirname)
132***************
133*** 1333,1336 ****
134--- 1352,1369 ----
135 return (NULL);
136 }
137+ /* If we have a directory name with quoted characters, and we are
138+ being called recursively to glob the directory portion of a pathname,
139+ we need to dequote the directory name before returning it so the
140+ caller can read the directory */
141+ if (directory_len > 0 && hasglob == 2 && (flags & GX_RECURSE) != 0)
142+ {
143+ dequote_pathname (directory_name);
144+ directory_len = strlen (directory_name);
145+ }
146+
147+ /* We could check whether or not the dequoted directory_name is a
148+ directory and return it here, returning the original directory_name
149+ if not, but we don't do that yet. I'm not sure it matters. */
150+
151 /* Handle GX_MARKDIRS here. */
152 result[0] = (char *) malloc (directory_len + 1);
153*** ../bash-5.0-patched/pathexp.c 2018-04-29 17:44:48.000000000 -0400
154--- pathexp.c 2019-01-31 20:19:41.000000000 -0500
155***************
156*** 66,74 ****
157 register int c;
158 char *send;
159! int open;
160
161 DECLARE_MBSTATE;
162
163! open = 0;
164 send = string + strlen (string);
165
166--- 66,74 ----
167 register int c;
168 char *send;
169! int open, bsquote;
170
171 DECLARE_MBSTATE;
172
173! open = bsquote = 0;
174 send = string + strlen (string);
175
176***************
177*** 101,105 ****
178 globbing. */
179 case '\\':
180! return (*string != 0);
181
182 case CTLESC:
183--- 101,112 ----
184 globbing. */
185 case '\\':
186! if (*string != '\0' && *string != '/')
187! {
188! bsquote = 1;
189! string++;
190! continue;
191! }
192! else if (*string == 0)
193! return (0);
194
195 case CTLESC:
196***************
197*** 118,122 ****
198 #endif
199 }
200! return (0);
201 }
202
203--- 125,130 ----
204 #endif
205 }
206!
207! return (bsquote ? 2 : 0);
208 }
209
210*** ../bash-5.0-patched/bashline.c 2019-01-16 16:13:21.000000000 -0500
211--- bashline.c 2019-02-22 09:29:08.000000000 -0500
212***************
213*** 3753,3757 ****
214
215 case '\\':
216! if (*string == 0)
217 return (0);
218 }
219--- 3766,3770 ----
220
221 case '\\':
222! if (*string++ == 0)
223 return (0);
224 }
225*** ../bash-5.0/patchlevel.h 2016-06-22 14:51:03.000000000 -0400
226--- patchlevel.h 2016-10-01 11:01:28.000000000 -0400
227***************
228*** 26,30 ****
229 looks for to find the patch level (for the sccs version string). */
230
231! #define PATCHLEVEL 2
232
233 #endif /* _PATCHLEVEL_H_ */
234--- 26,30 ----
235 looks for to find the patch level (for the sccs version string). */
236
237! #define PATCHLEVEL 3
238
239 #endif /* _PATCHLEVEL_H_ */