]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/bash/bash50-003
Merge branch 'next'
[people/pmueller/ipfire-2.x.git] / src / patches / bash / bash50-003
diff --git a/src/patches/bash/bash50-003 b/src/patches/bash/bash50-003
new file mode 100644 (file)
index 0000000..f7e5677
--- /dev/null
@@ -0,0 +1,239 @@
+                            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.
+
+Patch (apply with `patch -p0'):
+
+*** ../bash-5.0-patched/lib/glob/glob_loop.c   2019-01-16 16:13:21.000000000 -0500
+--- lib/glob/glob_loop.c       2019-02-01 09:45:11.000000000 -0500
+***************
+*** 27,34 ****
+    register const GCHAR *p;
+    register GCHAR c;
+!   int bopen;
+  
+    p = pattern;
+!   bopen = 0;
+  
+    while ((c = *p++) != L('\0'))
+--- 27,34 ----
+    register const GCHAR *p;
+    register GCHAR c;
+!   int bopen, bsquote;
+  
+    p = pattern;
+!   bopen = bsquote = 0;
+  
+    while ((c = *p++) != L('\0'))
+***************
+*** 56,66 ****
+        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'));
+        }
+  
+!   return 0;
+  }
+  
+--- 56,75 ----
+        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 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 bsquote ? 2 : 0;
+  }
+  
+*** ../bash-5.0-patched/lib/glob/glob.h        2013-10-28 14:46:12.000000000 -0400
+--- lib/glob/glob.h    2019-03-07 11:06:47.000000000 -0500
+***************
+*** 31,34 ****
+--- 31,35 ----
+  #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 *));
+*** ../bash-5.0-patched/lib/glob/glob.c        2018-09-20 10:53:23.000000000 -0400
+--- lib/glob/glob.c    2019-03-07 14:23:43.000000000 -0500
+***************
+*** 1062,1066 ****
+    unsigned int directory_len;
+    int free_dirname;                  /* flag */
+!   int dflags;
+  
+    result = (char **) malloc (sizeof (char *));
+--- 1078,1082 ----
+    unsigned int directory_len;
+    int free_dirname;                  /* flag */
+!   int dflags, hasglob;
+  
+    result = (char **) malloc (sizeof (char *));
+***************
+*** 1111,1117 ****
+      }
+  
+    /* 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))
+      {
+        char **directories, *d, *p;
+--- 1127,1136 ----
+      }
+  
++   hasglob = 0;
+    /* If directory_name contains globbing characters, then we
+!      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;
+***************
+*** 1176,1180 ****
+       d[directory_len - 1] = '\0';
+  
+!       directories = glob_filename (d, dflags);
+  
+        if (free_dirname)
+--- 1195,1199 ----
+       d[directory_len - 1] = '\0';
+  
+!       directories = glob_filename (d, dflags|GX_RECURSE);
+  
+        if (free_dirname)
+***************
+*** 1333,1336 ****
+--- 1352,1369 ----
+         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);
+*** ../bash-5.0-patched/pathexp.c      2018-04-29 17:44:48.000000000 -0400
+--- pathexp.c  2019-01-31 20:19:41.000000000 -0500
+***************
+*** 66,74 ****
+    register int c;
+    char *send;
+!   int open;
+  
+    DECLARE_MBSTATE;
+  
+!   open = 0;
+    send = string + strlen (string);
+  
+--- 66,74 ----
+    register int c;
+    char *send;
+!   int open, bsquote;
+  
+    DECLARE_MBSTATE;
+  
+!   open = bsquote = 0;
+    send = string + strlen (string);
+  
+***************
+*** 101,105 ****
+          globbing. */
+       case '\\':
+!        return (*string != 0);
+                 
+       case CTLESC:
+--- 101,112 ----
+          globbing. */
+       case '\\':
+!        if (*string != '\0' && *string != '/')
+!          {
+!            bsquote = 1;
+!            string++;
+!            continue;
+!          }
+!        else if (*string == 0)
+!          return (0);
+                 
+       case CTLESC:
+***************
+*** 118,122 ****
+  #endif
+      }
+!   return (0);
+  }
+  
+--- 125,130 ----
+  #endif
+      }
+! 
+!   return (bsquote ? 2 : 0);
+  }
+  
+*** ../bash-5.0-patched/bashline.c     2019-01-16 16:13:21.000000000 -0500
+--- bashline.c 2019-02-22 09:29:08.000000000 -0500
+***************
+*** 3753,3757 ****
+  
+       case '\\':
+!        if (*string == 0)
+           return (0);           
+       }
+--- 3766,3770 ----
+  
+       case '\\':
+!        if (*string++ == 0)
+           return (0);           
+       }
+*** ../bash-5.0/patchlevel.h   2016-06-22 14:51:03.000000000 -0400
+--- patchlevel.h       2016-10-01 11:01:28.000000000 -0400
+***************
+*** 26,30 ****
+     looks for to find the patch level (for the sccs version string). */
+  
+! #define PATCHLEVEL 2
+  
+  #endif /* _PATCHLEVEL_H_ */
+--- 26,30 ----
+     looks for to find the patch level (for the sccs version string). */
+  
+! #define PATCHLEVEL 3
+  
+  #endif /* _PATCHLEVEL_H_ */