7 Bug-Reported-by: Andrew Church <achurch+bash@achurch.org>
8 Bug-Reference-ID: <5c534aa2.04371@msgid.achurch.org>
9 Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2019-01/msg00276.html
13 There are several incompatibilities in how bash-5.0 processes pathname
14 expansion (globbing) of filename arguments that have backslashes in the
17 Patch (apply with `patch -p0'):
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
23 register const GCHAR *p;
30 while ((c = *p++) != L('\0'))
32 register const GCHAR *p;
37 ! bopen = bsquote = 0;
39 while ((c = *p++) != L('\0'))
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'));
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. */
67 ! else /* (*p == L('\0')) */
71 ! return bsquote ? 2 : 0;
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
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 */
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
88 unsigned int directory_len;
89 int free_dirname; /* flag */
92 result = (char **) malloc (sizeof (char *));
94 unsigned int directory_len;
95 int free_dirname; /* flag */
96 ! int dflags, hasglob;
98 result = (char **) malloc (sizeof (char *));
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))
107 char **directories, *d, *p;
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)
118 char **directories, *d, *p;
121 d[directory_len - 1] = '\0';
123 ! directories = glob_filename (d, dflags);
127 d[directory_len - 1] = '\0';
129 ! directories = glob_filename (d, dflags|GX_RECURSE);
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)
143 + dequote_pathname (directory_name);
144 + directory_len = strlen (directory_name);
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. */
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
164 send = string + strlen (string);
173 ! open = bsquote = 0;
174 send = string + strlen (string);
180 ! return (*string != 0);
186 ! if (*string != '\0' && *string != '/')
192 ! else if (*string == 0)
207 ! return (bsquote ? 2 : 0);
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
222 ! if (*string++ == 0)
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
229 looks for to find the patch level (for the sccs version string). */
231 ! #define PATCHLEVEL 2
233 #endif /* _PATCHLEVEL_H_ */
235 looks for to find the patch level (for the sccs version string). */
237 ! #define PATCHLEVEL 3
239 #endif /* _PATCHLEVEL_H_ */