diff options
Diffstat (limited to '')
-rw-r--r-- | debian/patches/bash50-003.diff | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/debian/patches/bash50-003.diff b/debian/patches/bash50-003.diff new file mode 100644 index 0000000..58b0aae --- /dev/null +++ b/debian/patches/bash50-003.diff @@ -0,0 +1,188 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.0 +Patch-ID: bash50-003 + +Bug-Reported-by: Andrew Church <achurch+bash@achurch.org> +Bug-Reference-ID: <5c534aa2.04371@msgid.achurch.org> +Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2019-01/msg00276.html + +Bug-Description: + +There are several incompatibilities in how bash-5.0 processes pathname +expansion (globbing) of filename arguments that have backslashes in the +directory portion. + +--- a/bashline.c ++++ b/bashline.c +@@ -3752,7 +3752,7 @@ completion_glob_pattern (string) + continue; + + case '\\': +- if (*string == 0) ++ if (*string++ == 0) + return (0); + } + +--- a/lib/glob/glob.c ++++ b/lib/glob/glob.c +@@ -1061,7 +1061,7 @@ glob_filename (pathname, flags) + char *directory_name, *filename, *dname, *fn; + unsigned int directory_len; + int free_dirname; /* flag */ +- int dflags; ++ int dflags, hasglob; + + result = (char **) malloc (sizeof (char *)); + result_size = 1; +@@ -1110,9 +1110,12 @@ glob_filename (pathname, flags) + free_dirname = 1; + } + ++ hasglob = 0; + /* If directory_name contains globbing characters, then we +- have to expand the previous levels. Just recurse. */ +- if (directory_len > 0 && glob_pattern_p (directory_name)) ++ have to expand the previous levels. Just recurse. ++ If glob_pattern_p returns != [0,1] we have a pattern that has backslash ++ quotes but no unquoted glob pattern characters. We dequote it below. */ ++ if (directory_len > 0 && (hasglob = glob_pattern_p (directory_name)) == 1) + { + char **directories, *d, *p; + register unsigned int i; +@@ -1175,7 +1178,7 @@ glob_filename (pathname, flags) + if (d[directory_len - 1] == '/') + d[directory_len - 1] = '\0'; + +- directories = glob_filename (d, dflags); ++ directories = glob_filename (d, dflags|GX_RECURSE); + + if (free_dirname) + { +@@ -1332,6 +1335,20 @@ only_filename: + free (directory_name); + return (NULL); + } ++ /* If we have a directory name with quoted characters, and we are ++ being called recursively to glob the directory portion of a pathname, ++ we need to dequote the directory name before returning it so the ++ caller can read the directory */ ++ if (directory_len > 0 && hasglob == 2 && (flags & GX_RECURSE) != 0) ++ { ++ dequote_pathname (directory_name); ++ directory_len = strlen (directory_name); ++ } ++ ++ /* We could check whether or not the dequoted directory_name is a ++ directory and return it here, returning the original directory_name ++ if not, but we don't do that yet. I'm not sure it matters. */ ++ + /* Handle GX_MARKDIRS here. */ + result[0] = (char *) malloc (directory_len + 1); + if (result[0] == NULL) +--- a/lib/glob/glob.h ++++ b/lib/glob/glob.h +@@ -30,6 +30,7 @@ + #define GX_NULLDIR 0x100 /* internal -- no directory preceding pattern */ + #define GX_ADDCURDIR 0x200 /* internal -- add passed directory name */ + #define GX_GLOBSTAR 0x400 /* turn on special handling of ** */ ++#define GX_RECURSE 0x800 /* internal -- glob_filename called recursively */ + + extern int glob_pattern_p __P((const char *)); + extern char **glob_vector __P((char *, char *, int)); +--- a/lib/glob/glob_loop.c ++++ b/lib/glob/glob_loop.c +@@ -26,10 +26,10 @@ INTERNAL_GLOB_PATTERN_P (pattern) + { + register const GCHAR *p; + register GCHAR c; +- int bopen; ++ int bopen, bsquote; + + p = pattern; +- bopen = 0; ++ bopen = bsquote = 0; + + while ((c = *p++) != L('\0')) + switch (c) +@@ -55,13 +55,22 @@ INTERNAL_GLOB_PATTERN_P (pattern) + + case L('\\'): + /* Don't let the pattern end in a backslash (GMATCH returns no match +- if the pattern ends in a backslash anyway), but otherwise return 1, +- since the matching engine uses backslash as an escape character +- and it can be removed. */ +- return (*p != L('\0')); ++ if the pattern ends in a backslash anyway), but otherwise note that ++ we have seen this, since the matching engine uses backslash as an ++ escape character and it can be removed. We return 2 later if we ++ have seen only backslash-escaped characters, so interested callers ++ know they can shortcut and just dequote the pathname. */ ++ if (*p != L('\0')) ++ { ++ p++; ++ bsquote = 1; ++ continue; ++ } ++ else /* (*p == L('\0')) */ ++ return 0; + } + +- return 0; ++ return bsquote ? 2 : 0; + } + + #undef INTERNAL_GLOB_PATTERN_P +--- a/patchlevel.h ++++ b/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 2 ++#define PATCHLEVEL 3 + + #endif /* _PATCHLEVEL_H_ */ +--- a/pathexp.c ++++ b/pathexp.c +@@ -65,11 +65,11 @@ unquoted_glob_pattern_p (string) + { + register int c; + char *send; +- int open; ++ int open, bsquote; + + DECLARE_MBSTATE; + +- open = 0; ++ open = bsquote = 0; + send = string + strlen (string); + + while (c = *string++) +@@ -100,7 +100,14 @@ unquoted_glob_pattern_p (string) + can be removed by the matching engine, so we have to run it through + globbing. */ + case '\\': +- return (*string != 0); ++ if (*string != '\0' && *string != '/') ++ { ++ bsquote = 1; ++ string++; ++ continue; ++ } ++ else if (*string == 0) ++ return (0); + + case CTLESC: + if (*string++ == '\0') +@@ -117,7 +124,8 @@ unquoted_glob_pattern_p (string) + ADVANCE_CHAR_P (string, send - string); + #endif + } +- return (0); ++ ++ return (bsquote ? 2 : 0); + } + + /* Return 1 if C is a character that is `special' in a POSIX ERE and needs to |