]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20191009 snapshot
authorChet Ramey <chet.ramey@case.edu>
Mon, 14 Oct 2019 13:17:20 +0000 (09:17 -0400)
committerChet Ramey <chet.ramey@case.edu>
Mon, 14 Oct 2019 13:17:20 +0000 (09:17 -0400)
12 files changed:
CWRU/CWRU.chlog
execute_cmd.c
execute_cmd.h
include/shmbutil.h
lib/glob/glob.c
lib/glob/sm_loop.c
lib/glob/smatch.c
lib/sh/shmatch.c
pathexp.c
subst.c
tests/glob.right
tests/glob3.sub

index 515836f76652b4953fc6a89b1c909ce39834c36a..6252141463d636f8c636e6b06175ad60765d3ebe 100644 (file)
@@ -6726,3 +6726,59 @@ pathexp.[ch],{bashline,subst}.c
 subst.c
        - glob_expand_word_list: call shell_glob_filename with QGLOB_CTLESC
          because quote removal hasn't been performed yet
+
+                                  10/7
+                                  ----
+pathexp.c
+       - quote_string_for_globbing: if we have an unquoted backslash followed
+         by a CTLESC-quoted character (not CTLESC-CTLESC), just perform the
+         usual CTLESC-to-backslash conversion instead of skipping over it.
+         Fixes issue raised in austin-group discussion about globbing by
+         Geoff Clare <gwc@opengroup.org> (austin-group issue 1234), though
+         it's still inherently ambiguous
+
+                                  10/8
+                                  ----
+include/shmbutil.h
+       - xwcsrtombs: extern declaration, to match other functions in that file
+
+lib/glob/glob.c
+       - wcdequote_pathname: new function, actual backslash quote removal code
+         from wdequote_pathname; wdequote_pathname calls it
+
+lib/glob/glob.c
+       - {udequote,wcdequote}_pathname: now public void functions
+
+lib/glob/smatch.c
+       - DEQUOTE_PATHNAME: defined appropriately to udequote_pathname or
+         wcdequote_pathname
+
+lib/glob/sm_loop.c
+       - DEQUOTE_PATHNAME: appropriate extern declaration
+       - BRACKMATCH: call DEQUOTE_PATHNAME to dequote a character class name
+         in a bracket expression. This is the result of a discussion on the
+         austin-group mailing list, from Geoff Clare <gwc@opengroup.org> and
+         Robert Elz <kre@bmunnari.oz.au>
+
+                                  10/10
+                                  -----
+execute_cmd.[ch]
+       - async_redirect_stdin: now a global function
+
+subst.c
+       - process_substitute: call async_redirect_stdin in the child to keep
+         it from having stdin connected to the terminal, since it's not a
+         job control process
+
+                                  10/11
+                                  -----
+subst.c
+       - process_substitute: in the child process, set interactive = 0, since
+         an asynchronous process substitution process is not interactive.
+         Seems to fix issue reported by Grisha Levit <grishalevit@gmail.com>
+
+lib/sh/shmatch.c
+       - sh_regmatch: implement a suggestion from Grisha Levit
+         <grishalevit@gmail.com> and don't allow nocaseglob to enable case-
+         insensitive regexp matching. It hasn't been documented that way
+         in years
index f6423e5b2f967dc56e0730c57bdd274b0468c809..21d45cf0e5ccc350beb252229abf133b2bf4375d 100644 (file)
@@ -126,8 +126,6 @@ static void cleanup_redirects PARAMS((REDIRECT *));
 static int restore_signal_mask PARAMS((sigset_t *));
 #endif
 
-static void async_redirect_stdin PARAMS((void));
-
 static int builtin_status PARAMS((int));
 
 static int execute_for_command PARAMS((FOR_COM *));
@@ -521,7 +519,7 @@ open_files ()
 }
 #endif
 
-static void
+void
 async_redirect_stdin ()
 {
   int fd;
index dc2f15ec65d64c601d69ffbae2f4d7337c048bb1..5ec0abef75f6476f0b83adb25c4277d5deaecb08 100644 (file)
@@ -77,6 +77,7 @@ extern int execute_command __P((COMMAND *));
 extern int execute_command_internal __P((COMMAND *, int, int, int, struct fd_bitmap *));
 extern int shell_execve __P((char *, char **, char **));
 extern void setup_async_signals __P((void));
+extern void async_redirect_stdin __P((void));
 
 extern void undo_partial_redirects __P((void));
 extern void dispose_partial_redirects __P((void));
index 36902f16bc57b1981190c935a00ed7a9af497264..835fb80cdb6ee23f2e70216fb1fb8bb3e438bd82 100644 (file)
@@ -1,6 +1,6 @@
 /* shmbutil.h -- utility functions for multibyte characters. */
 
-/* Copyright (C) 2002-2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2019 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
 #if defined (HANDLE_MULTIBYTE)
 #include "shmbchar.h"
 
-extern size_t xmbsrtowcs __P((wchar_t *, const char **, size_t, mbstate_t *));
-extern size_t xdupmbstowcs __P((wchar_t **, char ***, const char *));
+extern size_t xwcsrtombs PARAMS((char *, const wchar_t **, size_t, mbstate_t *));
+extern size_t xmbsrtowcs PARAMS((wchar_t *, const char **, size_t, mbstate_t *));
+extern size_t xdupmbstowcs PARAMS((wchar_t **, char ***, const char *));
 
-extern size_t mbstrlen __P((const char *));
+extern size_t mbstrlen PARAMS((const char *));
 
-extern char *xstrchr __P((const char *, int));
+extern char *xstrchr PARAMS((const char *, int));
 
 extern int locale_mb_cur_max;  /* XXX */
 extern int locale_utf8locale;  /* XXX */
index 4c7e8b95959bd53167a26814e05e7546e5beeaee..cd077899f55f3940e78dc51b6a15fb7252903a7e 100644 (file)
@@ -115,8 +115,9 @@ static int skipname __P((char *, char *, int));
 #if HANDLE_MULTIBYTE
 static int mbskipname __P((char *, char *, int));
 #endif
+void udequote_pathname __P((char *));
 #if HANDLE_MULTIBYTE
-static void udequote_pathname __P((char *));
+void wcdequote_pathname __P((wchar_t *));
 static void wdequote_pathname __P((char *));
 #else
 #  define dequote_pathname udequote_pathname
@@ -409,7 +410,7 @@ mbskipname (pat, dname, flags)
 #endif /* HANDLE_MULTIBYTE */
 
 /* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
-static void
+void
 udequote_pathname (pathname)
      char *pathname;
 {
@@ -431,6 +432,26 @@ udequote_pathname (pathname)
 
 #if HANDLE_MULTIBYTE
 /* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
+void
+wcdequote_pathname (wpathname)
+     wchar_t *wpathname;
+{
+  int i, j;
+
+  for (i = j = 0; wpathname && wpathname[i]; )
+    {
+      if (wpathname[i] == L'\\')
+       i++;
+
+      wpathname[j++] = wpathname[i++];
+
+      if (wpathname[i - 1] == L'\0')
+       break;
+    }
+  if (wpathname)
+    wpathname[j] = L'\0';
+}
+
 static void
 wdequote_pathname (pathname)
      char *pathname;
@@ -458,18 +479,7 @@ wdequote_pathname (pathname)
     }
   orig_wpathname = wpathname;
 
-  for (i = j = 0; wpathname && wpathname[i]; )
-    {
-      if (wpathname[i] == L'\\')
-       i++;
-
-      wpathname[j++] = wpathname[i++];
-
-      if (wpathname[i - 1] == L'\0')
-       break;
-    }
-  if (wpathname)
-    wpathname[j] = L'\0';
+  wcdequote_pathname (wpathname);
 
   /* Convert the wide character string into unibyte character set. */
   memset (&ps, '\0', sizeof(mbstate_t));
@@ -686,7 +696,7 @@ glob_vector (pat, dir, flags)
      a filename `DIR/PAT'.  If there is, and we can access it, just make the
      vector to return and bail immediately. */
   hasglob = 0;
-  if (skip == 0 && (hasglob = glob_pattern_p (pat)) == 0 || hasglob == 2)
+  if (skip == 0 && ((hasglob = glob_pattern_p (pat)) == 0 || hasglob == 2))
     {
       int dirlen;
       struct stat finfo;
index e352cc9fbbe29db3a622e4b08a675edc39eaee7e..bddc965384884a2fe980eb661c8a76c5e623b3a3 100644 (file)
@@ -29,6 +29,8 @@ static CHAR *PARSE_COLLSYM __P((CHAR *, INT *));
 static CHAR *BRACKMATCH __P((CHAR *, U_CHAR, int));
 static int EXTMATCH __P((INT, CHAR *, CHAR *, CHAR *, CHAR *, int));
 
+extern void DEQUOTE_PATHNAME __P((CHAR *));
+
 /*static*/ CHAR *PATSCAN __P((CHAR *, CHAR *, INT));
 
 int
@@ -456,6 +458,9 @@ BRACKMATCH (p, test, flags)
                {
                  bcopy (p + 1, ccname, (close - p - 1) * sizeof (CHAR));
                  *(ccname + (close - p - 1)) = L('\0');
+                 /* As a result of a POSIX discussion, char class names are
+                    allowed to be quoted (?) */
+                 DEQUOTE_PATHNAME (ccname);
                  pc = IS_CCLASS (orig_test, (XCHAR *)ccname);
                }
              if (pc == -1)
@@ -929,6 +934,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
 #undef PATSCAN
 #undef STRCOMPARE
 #undef EXTMATCH
+#undef DEQUOTE_PATHNAME
 #undef STRUCT
 #undef BRACKMATCH
 #undef STRCHR
index b2b8b35e4e119428e4aaca9cd6ab2282fa250b4b..a74fe9ea8a647e9fc1eca4135d297cf3035be1d6 100644 (file)
@@ -260,6 +260,7 @@ is_cclass (c, name)
 #define PATSCAN                        glob_patscan
 #define STRCOMPARE             strcompare
 #define EXTMATCH               extmatch
+#define DEQUOTE_PATHNAME       udequote_pathname
 #define STRUCT                 smat_struct
 #define STRCHR(S, C)           strchr((S), (C))
 #define MEMCHR(S, C, N)                memchr((S), (C), (N))
@@ -500,6 +501,7 @@ posix_cclass_only (pattern)
 #define PATSCAN                        glob_patscan_wc
 #define STRCOMPARE             wscompare
 #define EXTMATCH               extmatch_wc
+#define DEQUOTE_PATHNAME       wcdequote_pathname
 #define STRUCT                 wcsmat_struct
 #define STRCHR(S, C)           wcschr((S), (C))
 #define MEMCHR(S, C, N)                wmemchr((S), (C), (N))
index da05211e848890a27f00b839f8598125f356e1b2..1cca7038abaf2790c0e38cf97a0f75b54cca960c 100644 (file)
@@ -64,7 +64,7 @@ sh_regmatch (string, pattern, flags)
 #endif
 
   rflags = REG_EXTENDED;
-  if (glob_ignore_case || match_ignore_case)
+  if (match_ignore_case)
     rflags |= REG_ICASE;
 #if !defined (ARRAY_VARS)
   rflags |= REG_NOSUB;
index 572db75301f3e65a03b9593f36a459fcaa9b7aa0..c6825736610427ddfb99b38e1dfd1412dbfd0050 100644 (file)
--- a/pathexp.c
+++ b/pathexp.c
@@ -243,6 +243,7 @@ quote_string_for_globbing (pathname, qflags)
        }
       else if (pathname[i] == CTLESC)
        {
+convert_to_backslash:
          if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/')
            continue;
          /* What to do if preceding char is backslash? */
@@ -358,6 +359,16 @@ quote_string_for_globbing (pathname, qflags)
             even when the first CTLESC is preceded by a backslash. */
          if ((qflags & QGLOB_CTLESC) && pathname[i] == CTLESC && (pathname[i+1] == CTLESC || pathname[i+1] == CTLNUL))
            i++;        /* skip over the CTLESC */
+         else if ((qflags & QGLOB_CTLESC) && pathname[i] == CTLESC)
+           /* A little more general: if there is an unquoted backslash in the
+              pattern and we are handling quoted characters in the pattern,
+              convert the CTLESC to backslash and add the next character on
+              the theory that the backslash will quote the next character
+              but it would be inconsistent not to replace the CTLESC with
+              another backslash here. We can't tell at this point whether the
+              CTLESC comes from a backslash or other form of quoting in the
+              original pattern. */
+           goto convert_to_backslash;
        }
       else if (pathname[i] == '\\' && (qflags & QGLOB_REGEXP))
         last_was_backslash = 1;
diff --git a/subst.c b/subst.c
index 0fd33a6f16738ff4946ebcf00bd87da0e33bab92..0d223825762cb28212702964d1297d0032441b15 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -5898,12 +5898,15 @@ process_substitute (string, open_for_read_in_child)
   pid = make_child ((char *)NULL, 1);
   if (pid == 0)
     {
+interactive = 0;
       reset_terminating_signals ();    /* XXX */
       free_pushed_string_input ();
       /* Cancel traps, in trap.c. */
       restore_original_signals ();     /* XXX - what about special builtins? bash-4.2 */
       QUIT;    /* catch any interrupts we got post-fork */
       setup_async_signals ();
+      if (open_for_read_in_child == 0)
+       async_redirect_stdin ();
       subshell_environment |= SUBSHELL_COMSUB|SUBSHELL_PROCSUB;
 
       /* We don't inherit the verbose option for command substitutions now, so
index 82ed3d8ae81b198f19c242445e98d072adb68af8..147a4bab73b7cfe6ad641b4186f513336226538d 100644 (file)
@@ -20,16 +20,22 @@ ok 1
 [a
 [[:alpha:]
 ok 2
+ok 2.1
 ok 3
+ok 4
 == LANG=en_US.UTF-8 ==
 [[:alpha:]
 ok 1
 [a
 [[:alpha:]
 ok 2
+ok 2.1
 ok 3
+ok 4
 invalid character class
 == LANG=C ==
+p
+p
 ok 1
 ok 2
 ok 3
@@ -37,6 +43,8 @@ ok 4
 ok 5
 ok 6
 == LANG=en_US.UTF-8 ==
+p
+p
 ok 1
 ok 2
 ok 3
index 3c92854da1ac717befa3cff28a8921d44f3e0475..662c65e97f98acc9784ec73f28e64f22514037bf 100644 (file)
 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 : ${TMPDIR:=/var/tmp}
-cd $TMPDIR
+
+TESTDIR=${TMPDIR}/glob-test-$$
+mkdir ${TESTDIR}
+cd $TESTDIR ||  {
+        echo "$TESTDIR: cannot cd" >&2
+        exit 1
+}
 
 matchfunc()
 {
@@ -38,10 +44,21 @@ matchfunc()
        *)              echo bad 2;;
        esac
 
+       case x in
+       [[:aeioux:])    echo bad 2.1 ;;
+       *)              echo ok 2.1 ;;
+       esac
+
        case [x in
        [[:alpha:])     echo bad 3;;
        *)              echo ok 3;;
        esac
+
+       # unclosed bracket char class expression just matches against ":alpha"
+       case a in
+       [[:alpha])      echo ok 4;;
+       *)              echo bad 4;;
+       esac
 }
 
 echo invalid bracket expression
@@ -57,6 +74,12 @@ matchfunc()
 {
        echo == LANG=$LANG ==
 
+       touch p
+       # quoted character classes work as if they were unquoted now
+       echo [[:alpha:]]
+       echo [[:"alpha":]]
+       rm -f p
+
        case a] in
        [[:aleph:]])    echo bad 1;;
        *)              echo ok 1;;
@@ -72,9 +95,10 @@ matchfunc()
        *)              echo ok 3;;
        esac
 
-       case a in
-       [[:"alpha":]])  echo bad 4;;
-       *)              echo ok 4;;
+       # Posix says quoted character class names work now
+       case x in
+       [[:"alpha":]])  echo ok 4;;
+       *)              echo bad 4;;
        esac
 
        case a in
@@ -134,3 +158,6 @@ matchfunc
 
 export LANG=en_US.UTF-8
 matchfunc
+
+cd $OLDPWD
+rm -rf $TESTDIR