Petr Šabata 33fc6c
From 4d2e315490b778707b3a3afdfc514d5083a97a11 Mon Sep 17 00:00:00 2001
Petr Šabata 33fc6c
From: Chet Ramey <chet.ramey@case.edu>
Petr Šabata 33fc6c
Date: Fri, 18 Jan 2019 15:12:37 -0500
Petr Šabata 33fc6c
Subject: [PATCH] Bash-5.0 patch 1: fix pathname expansion of directory names
Petr Šabata 33fc6c
 containing backslashes
Petr Šabata 33fc6c
Petr Šabata 33fc6c
---
Petr Šabata 33fc6c
 bashline.c           | 62 +++++++++++++++++++++++++++++++++++++++++---
Petr Šabata 33fc6c
 lib/glob/glob_loop.c |  6 -----
Petr Šabata 33fc6c
 patchlevel.h         |  2 +-
Petr Šabata 33fc6c
 3 files changed, 60 insertions(+), 10 deletions(-)
Petr Šabata 33fc6c
Petr Šabata 33fc6c
diff --git a/bashline.c b/bashline.c
Petr Šabata 33fc6c
index 2846aabf..75e79f1a 100644
Petr Šabata 33fc6c
--- a/bashline.c
Petr Šabata 33fc6c
+++ b/bashline.c
Petr Šabata 33fc6c
@@ -231,6 +231,7 @@ static int bash_possible_variable_completions __P((int, int));
Petr Šabata 33fc6c
 static int bash_complete_command __P((int, int));
Petr Šabata 33fc6c
 static int bash_possible_command_completions __P((int, int));
Petr Šabata 33fc6c
 
Petr Šabata 33fc6c
+static int completion_glob_pattern __P((char *));
Petr Šabata 33fc6c
 static char *glob_complete_word __P((const char *, int));
Petr Šabata 33fc6c
 static int bash_glob_completion_internal __P((int));
Petr Šabata 33fc6c
 static int bash_glob_complete_word __P((int, int));
Petr Šabata 33fc6c
@@ -1741,7 +1742,7 @@ bash_default_completion (text, start, end, qc, compflags)
Petr Šabata 33fc6c
 
Petr Šabata 33fc6c
   /* This could be a globbing pattern, so try to expand it using pathname
Petr Šabata 33fc6c
      expansion. */
Petr Šabata 33fc6c
-  if (!matches && glob_pattern_p (text))
Petr Šabata 33fc6c
+  if (!matches && completion_glob_pattern ((char *)text))
Petr Šabata 33fc6c
     {
Petr Šabata 33fc6c
       matches = rl_completion_matches (text, glob_complete_word);
Petr Šabata 33fc6c
       /* A glob expression that matches more than one filename is problematic.
Petr Šabata 33fc6c
@@ -1850,7 +1851,7 @@ command_word_completion_function (hint_text, state)
Petr Šabata 33fc6c
 	  glob_matches = (char **)NULL;
Petr Šabata 33fc6c
 	}
Petr Šabata 33fc6c
 
Petr Šabata 33fc6c
-      globpat = glob_pattern_p (hint_text);
Petr Šabata 33fc6c
+      globpat = completion_glob_pattern ((char *)hint_text);
Petr Šabata 33fc6c
 
Petr Šabata 33fc6c
       /* If this is an absolute program name, do not check it against
Petr Šabata 33fc6c
 	 aliases, reserved words, functions or builtins.  We must check
Petr Šabata 33fc6c
@@ -3713,6 +3714,61 @@ bash_complete_command_internal (what_to_do)
Petr Šabata 33fc6c
   return bash_specific_completion (what_to_do, command_word_completion_function);
Petr Šabata 33fc6c
 }
Petr Šabata 33fc6c
 
Petr Šabata 33fc6c
+static int
Petr Šabata 33fc6c
+completion_glob_pattern (string)
Petr Šabata 33fc6c
+     char *string;
Petr Šabata 33fc6c
+{
Petr Šabata 33fc6c
+  register int c;
Petr Šabata 33fc6c
+  char *send;
Petr Šabata 33fc6c
+  int open;
Petr Šabata 33fc6c
+
Petr Šabata 33fc6c
+  DECLARE_MBSTATE;
Petr Šabata 33fc6c
+
Petr Šabata 33fc6c
+  open = 0;
Petr Šabata 33fc6c
+  send = string + strlen (string);
Petr Šabata 33fc6c
+
Petr Šabata 33fc6c
+  while (c = *string++)
Petr Šabata 33fc6c
+    {
Petr Šabata 33fc6c
+      switch (c)
Petr Šabata 33fc6c
+	{
Petr Šabata 33fc6c
+	case '?':
Petr Šabata 33fc6c
+	case '*':
Petr Šabata 33fc6c
+	  return (1);
Petr Šabata 33fc6c
+
Petr Šabata 33fc6c
+	case '[':
Petr Šabata 33fc6c
+	  open++;
Petr Šabata 33fc6c
+	  continue;
Petr Šabata 33fc6c
+
Petr Šabata 33fc6c
+	case ']':
Petr Šabata 33fc6c
+	  if (open)
Petr Šabata 33fc6c
+	    return (1);
Petr Šabata 33fc6c
+	  continue;
Petr Šabata 33fc6c
+
Petr Šabata 33fc6c
+	case '+':
Petr Šabata 33fc6c
+	case '@':
Petr Šabata 33fc6c
+	case '!':
Petr Šabata 33fc6c
+	  if (*string == '(')	/*)*/
Petr Šabata 33fc6c
+	    return (1);
Petr Šabata 33fc6c
+	  continue;
Petr Šabata 33fc6c
+
Petr Šabata 33fc6c
+	case '\\':
Petr Šabata 33fc6c
+	  if (*string == 0)
Petr Šabata 33fc6c
+	    return (0);	 	  
Petr Šabata 33fc6c
+	}
Petr Šabata 33fc6c
+
Petr Šabata 33fc6c
+      /* Advance one fewer byte than an entire multibyte character to
Petr Šabata 33fc6c
+	 account for the auto-increment in the loop above. */
Petr Šabata 33fc6c
+#ifdef HANDLE_MULTIBYTE
Petr Šabata 33fc6c
+      string--;
Petr Šabata 33fc6c
+      ADVANCE_CHAR_P (string, send - string);
Petr Šabata 33fc6c
+      string++;
Petr Šabata 33fc6c
+#else
Petr Šabata 33fc6c
+      ADVANCE_CHAR_P (string, send - string);
Petr Šabata 33fc6c
+#endif
Petr Šabata 33fc6c
+    }
Petr Šabata 33fc6c
+  return (0);
Petr Šabata 33fc6c
+}
Petr Šabata 33fc6c
+
Petr Šabata 33fc6c
 static char *globtext;
Petr Šabata 33fc6c
 static char *globorig;
Petr Šabata 33fc6c
 
Petr Šabata 33fc6c
@@ -3877,7 +3933,7 @@ bash_vi_complete (count, key)
Petr Šabata 33fc6c
       t = substring (rl_line_buffer, p, rl_point);
Petr Šabata 33fc6c
     }      
Petr Šabata 33fc6c
 
Petr Šabata 33fc6c
-  if (t && glob_pattern_p (t) == 0)
Petr Šabata 33fc6c
+  if (t && completion_glob_pattern (t) == 0)
Petr Šabata 33fc6c
     rl_explicit_arg = 1;	/* XXX - force glob_complete_word to append `*' */
Petr Šabata 33fc6c
   FREE (t);
Petr Šabata 33fc6c
 
Petr Šabata 33fc6c
diff --git a/lib/glob/glob_loop.c b/lib/glob/glob_loop.c
Petr Šabata 33fc6c
index 5f319cc2..7d6ae211 100644
Petr Šabata 33fc6c
--- a/lib/glob/glob_loop.c
Petr Šabata 33fc6c
+++ b/lib/glob/glob_loop.c
Petr Šabata 33fc6c
@@ -54,17 +54,11 @@ INTERNAL_GLOB_PATTERN_P (pattern)
Petr Šabata 33fc6c
 	continue;
Petr Šabata 33fc6c
 
Petr Šabata 33fc6c
       case L('\\'):
Petr Šabata 33fc6c
-#if 0
Petr Šabata 33fc6c
 	/* Don't let the pattern end in a backslash (GMATCH returns no match
Petr Šabata 33fc6c
 	   if the pattern ends in a backslash anyway), but otherwise return 1,
Petr Šabata 33fc6c
 	   since the matching engine uses backslash as an escape character
Petr Šabata 33fc6c
 	   and it can be removed. */
Petr Šabata 33fc6c
 	return (*p != L('\0'));
Petr Šabata 33fc6c
-#else
Petr Šabata 33fc6c
-	/* The pattern may not end with a backslash. */
Petr Šabata 33fc6c
-	if (*p++ == L('\0'))
Petr Šabata 33fc6c
-	  return 0;
Petr Šabata 33fc6c
-#endif
Petr Šabata 33fc6c
       }
Petr Šabata 33fc6c
 
Petr Šabata 33fc6c
   return 0;
Petr Šabata 33fc6c
diff --git a/patchlevel.h b/patchlevel.h
Petr Šabata 33fc6c
index 1cd7c96c..40db1a32 100644
Petr Šabata 33fc6c
--- a/patchlevel.h
Petr Šabata 33fc6c
+++ b/patchlevel.h
Petr Šabata 33fc6c
@@ -25,6 +25,6 @@
Petr Šabata 33fc6c
    regexp `^#define[ 	]*PATCHLEVEL', since that's what support/mkversion.sh
Petr Šabata 33fc6c
    looks for to find the patch level (for the sccs version string). */
Petr Šabata 33fc6c
 
Petr Šabata 33fc6c
-#define PATCHLEVEL 0
Petr Šabata 33fc6c
+#define PATCHLEVEL 1
Petr Šabata 33fc6c
 
Petr Šabata 33fc6c
 #endif /* _PATCHLEVEL_H_ */
Petr Šabata 33fc6c
-- 
Petr Šabata 33fc6c
2.17.2
Petr Šabata 33fc6c