From 54470831d055a429a9b13dc15a34552ec615973f Mon Sep 17 00:00:00 2001
From: Chet Ramey <chet.ramey@case.edu>
Date: Mon, 1 Jul 2019 09:03:53 -0400
Subject: [PATCH] commit bash-20190628 snapshot

---
 MANIFEST          |  2 ++
 bashline.c        | 50 +------------------------------------------
 builtins/help.def |  2 +-
 config.h.in       | 10 ++++++++-
 configure         | 11 ++++++++++
 configure.ac      |  1 +
 doc/bash.1        |  3 ++-
 doc/bashref.texi  |  3 ++-
 lib/glob/glob.c   |  5 ++++-
 pathexp.c         | 16 ++++++++++++--
 shell.c           |  8 +++++++
 tests/glob.tests  |  2 ++
 tests/glob6.sub   | 54 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/glob7.sub   | 11 ++++++++++
 14 files changed, 122 insertions(+), 56 deletions(-)
 create mode 100644 tests/glob6.sub
 create mode 100644 tests/glob7.sub

diff --git a/MANIFEST b/MANIFEST
index 03de221..14d4e1f 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1060,6 +1060,8 @@ tests/glob1.sub		f
 tests/glob2.sub		f
 tests/glob3.sub		f
 tests/glob4.sub		f
+tests/glob6.sub		f
+tests/glob7.sub		f
 tests/glob.right	f
 tests/globstar.tests	f
 tests/globstar.right	f
diff --git a/bashline.c b/bashline.c
index 824ea9d..f2e1c1d 100644
--- a/bashline.c
+++ b/bashline.c
@@ -3718,55 +3718,7 @@ static int
 completion_glob_pattern (string)
      char *string;
 {
-  register int c;
-  char *send;
-  int open;
-
-  DECLARE_MBSTATE;
-
-  open = 0;
-  send = string + strlen (string);
-
-  while (c = *string++)
-    {
-      switch (c)
-	{
-	case '?':
-	case '*':
-	  return (1);
-
-	case '[':
-	  open++;
-	  continue;
-
-	case ']':
-	  if (open)
-	    return (1);
-	  continue;
-
-	case '+':
-	case '@':
-	case '!':
-	  if (*string == '(')	/*)*/
-	    return (1);
-	  continue;
-
-	case '\\':
-	  if (*string++ == 0)
-	    return (0);	 	  
-	}
-
-      /* Advance one fewer byte than an entire multibyte character to
-	 account for the auto-increment in the loop above. */
-#ifdef HANDLE_MULTIBYTE
-      string--;
-      ADVANCE_CHAR_P (string, send - string);
-      string++;
-#else
-      ADVANCE_CHAR_P (string, send - string);
-#endif
-    }
-  return (0);
+  return (glob_pattern_p (string) == 1);
 }
 
 static char *globtext;
diff --git a/builtins/help.def b/builtins/help.def
index 006c4b5..92f9b38 100644
--- a/builtins/help.def
+++ b/builtins/help.def
@@ -128,7 +128,7 @@ help_builtin (list)
 
   /* We should consider making `help bash' do something. */
 
-  if (glob_pattern_p (list->word->word))
+  if (glob_pattern_p (list->word->word) == 1)
     {
       printf ("%s", ngettext ("Shell commands matching keyword `", "Shell commands matching keywords `", (list->next ? 2 : 1)));
       print_word_list (list, ", ");
diff --git a/config.h.in b/config.h.in
index 8b22244..af40689 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,6 +1,6 @@
 /* config.h -- Configuration file for bash. */
 
-/* Copyright (C) 1987-2009,2011-2012 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2009,2011-2012,2013-2019 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -810,6 +810,14 @@
 #undef HAVE_SETREGID
 #undef HAVE_DECL_SETREGID
 
+/* Define if you have the setregid function.  */
+#undef HAVE_SETRESGID
+#undef HAVE_DECL_SETRESGID
+
+/* Define if you have the setresuid function.  */
+#undef HAVE_SETRESUID
+#undef HAVE_DECL_SETRESUID
+
 /* Define if you have the setvbuf function.  */
 #undef HAVE_SETVBUF
 
diff --git a/configure b/configure
index 2f62662..b3321c9 100755
--- a/configure
+++ b/configure
@@ -10281,6 +10281,17 @@ cat >>confdefs.h <<_ACEOF
 #define HAVE_DECL_SETREGID $ac_have_decl
 _ACEOF
 
+ac_fn_c_check_decl "$LINENO" "" "ac_cv_have_decl_" "$ac_includes_default"
+if test "x$ac_cv_have_decl_" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ $ac_have_decl
+_ACEOF
+(setresuid, setresgid)
 ac_fn_c_check_decl "$LINENO" "strcpy" "ac_cv_have_decl_strcpy" "$ac_includes_default"
 if test "x$ac_cv_have_decl_strcpy" = xyes; then :
   ac_have_decl=1
diff --git a/configure.ac b/configure.ac
index 68d2ceb..f62a747 100644
--- a/configure.ac
+++ b/configure.ac
@@ -810,6 +810,7 @@ AC_CHECK_DECLS([confstr])
 AC_CHECK_DECLS([printf])
 AC_CHECK_DECLS([sbrk])
 AC_CHECK_DECLS([setregid])
+AC_CHECK_DECLS[(setresuid, setresgid])
 AC_CHECK_DECLS([strcpy])
 AC_CHECK_DECLS([strsignal])
 
diff --git a/doc/bash.1 b/doc/bash.1
index e6cd08d..9e58a0b 100644
--- a/doc/bash.1
+++ b/doc/bash.1
@@ -4681,7 +4681,8 @@ above).
 .PD
 .SH "SIMPLE COMMAND EXPANSION"
 When a simple command is executed, the shell performs the following
-expansions, assignments, and redirections, from left to right.
+expansions, assignments, and redirections, from left to right, in
+the following order.
 .IP 1.
 The words that the parser has marked as variable assignments (those
 preceding the command name) and redirections are saved for later
diff --git a/doc/bashref.texi b/doc/bashref.texi
index d33cd57..3065126 100644
--- a/doc/bashref.texi
+++ b/doc/bashref.texi
@@ -2964,7 +2964,8 @@ is not specified.  If the file does not exist, it is created.
 @cindex command expansion
 
 When a simple command is executed, the shell performs the following
-expansions, assignments, and redirections, from left to right.
+expansions, assignments, and redirections, from left to right, in
+the following order.
 
 @enumerate
 @item
diff --git a/lib/glob/glob.c b/lib/glob/glob.c
index 398253b..2eaa33e 100644
--- a/lib/glob/glob.c
+++ b/lib/glob/glob.c
@@ -607,6 +607,7 @@ glob_vector (pat, dir, flags)
   register unsigned int i;
   int mflags;		/* Flags passed to strmatch (). */
   int pflags;		/* flags passed to sh_makepath () */
+  int hasglob;		/* return value from glob_pattern_p */
   int nalloca;
   struct globval *firstmalloc, *tmplink;
   char *convfn;
@@ -648,10 +649,12 @@ glob_vector (pat, dir, flags)
   patlen = (pat && *pat) ? strlen (pat) : 0;
 
   /* If the filename pattern (PAT) does not contain any globbing characters,
+     or contains a pattern with only backslash escapes (hasglob == 2),
      we can dispense with reading the directory, and just see if there is
      a filename `DIR/PAT'.  If there is, and we can access it, just make the
      vector to return and bail immediately. */
-  if (skip == 0 && glob_pattern_p (pat) == 0)
+  hasglob = 0;
+  if (skip == 0 && (hasglob = glob_pattern_p (pat)) == 0 || hasglob == 2)
     {
       int dirlen;
       struct stat finfo;
diff --git a/pathexp.c b/pathexp.c
index c1bf2d8..97dfcd6 100644
--- a/pathexp.c
+++ b/pathexp.c
@@ -58,7 +58,10 @@ int extended_glob = EXTGLOB_DEFAULT;
 /* Control enabling special handling of `**' */
 int glob_star = 0;
 
-/* Return nonzero if STRING has any unquoted special globbing chars in it.  */
+/* Return nonzero if STRING has any unquoted special globbing chars in it.
+   This is supposed to be called when pathname expansion is performed, so
+   it implements the rules in Posix 2.13.3, specifically that an unquoted
+   slash cannot appear in a bracket expression. */
 int
 unquoted_glob_pattern_p (string)
      register char *string;
@@ -85,10 +88,14 @@ unquoted_glob_pattern_p (string)
 	  continue;
 
 	case ']':
-	  if (open)
+	  if (open)		/* XXX - if --open == 0? */  
 	    return (1);
 	  continue;
 
+	case '/':
+	  if (open)
+	    open = 0;
+
 	case '+':
 	case '@':
 	case '!':
@@ -106,6 +113,11 @@ unquoted_glob_pattern_p (string)
 	      string++;
 	      continue;
 	    }
+	  else if (open && *string == '/')
+	    {
+	      string++;		/* quoted slashes in bracket expressions are ok */
+	      continue;
+	    }
 	  else if (*string == 0)
 	    return (0);
 	 	  
diff --git a/shell.c b/shell.c
index a2b2a55..6adabc8 100644
--- a/shell.c
+++ b/shell.c
@@ -1293,7 +1293,11 @@ disable_priv_mode ()
 {
   int e;
 
+#if HAVE_DECL_SETRESUID
+  if (setresuid (current_user.uid, current_user.uid, current_user.uid) < 0)
+#else
   if (setuid (current_user.uid) < 0)
+#endif
     {
       e = errno;
       sys_error (_("cannot set uid to %d: effective uid %d"), current_user.uid, current_user.euid);
@@ -1302,7 +1306,11 @@ disable_priv_mode ()
 	exit (e);
 #endif
     }
+#if HAVE_DECL_SETRESGID
+  if (setresgid (current_user.gid, current_user.gid, current_user.gid) < 0)
+#else
   if (setgid (current_user.gid) < 0)
+#endif
     sys_error (_("cannot set gid to %d: effective gid %d"), current_user.gid, current_user.egid);
 
   current_user.euid = current_user.uid;
diff --git a/tests/glob.tests b/tests/glob.tests
index 01913bb..fb012f7 100644
--- a/tests/glob.tests
+++ b/tests/glob.tests
@@ -12,6 +12,8 @@ ${THIS_SH} ./glob1.sub
 ${THIS_SH} ./glob2.sub
 ${THIS_SH} ./glob3.sub
 ${THIS_SH} ./glob4.sub
+${THIS_SH} ./glob6.sub
+${THIS_SH} ./glob7.sub
 
 MYDIR=$PWD	# save where we are
 
diff --git a/tests/glob6.sub b/tests/glob6.sub
new file mode 100644
index 0000000..b099811
--- /dev/null
+++ b/tests/glob6.sub
@@ -0,0 +1,54 @@
+# tests of the backslash-in-glob-patterns discussion on the austin-group ML
+
+: ${TMPDIR:=/var/tmp}
+
+ORIG=$PWD
+GLOBDIR=$TMPDIR/bash-glob-$$
+mkdir $GLOBDIR && cd $GLOBDIR
+
+# does the pattern matcher allow backslashes as escape characters and remove
+# them as part of matching?
+touch abcdefg
+pat='ab\cd*'
+printf '<%s>\n' $pat
+pat='\.'
+printf '<%s>\n' $pat
+rm abcdefg
+
+# how about when escaping pattern characters?
+touch '*abc.c'
+a='\**.c'
+printf '%s\n' $a
+rm -f '*abc.c'
+
+# how about when making the distinction between readable and searchable path
+# components?
+mkdir -m a=x searchable
+mkdir -m a=r readable
+
+p='searchable/\.'
+printf "%s\n" $p
+
+p='searchable/\./.'
+printf "%s\n" $p
+
+p='readable/\.'
+printf "%s\n" $p
+
+p='readable/\./.'
+printf "%s\n" $p
+
+printf "%s\n" 'searchable/\.'
+printf "%s\n" 'readable/\.'
+
+echo */.
+
+p='*/\.'
+echo $p
+
+echo */'.'
+
+rmdir searchable readable
+
+cd $ORIG
+rmdir $GLOBDIR
diff --git a/tests/glob7.sub b/tests/glob7.sub
new file mode 100644
index 0000000..0212b8e
--- /dev/null
+++ b/tests/glob7.sub
@@ -0,0 +1,11 @@
+# according to Posix 2.13.3, a slash in a bracket expression renders that
+# bracket expression invalid
+shopt -s nullglob
+
+echo 1: [qwe/qwe]
+echo 2: [qwe/
+echo 3: [qwe/]
+
+echo 4: [qwe\/qwe]
+echo 5: [qwe\/
+echo 6: [qwe\/]
-- 
2.19.1

