From: Chet Ramey Date: Mon, 14 Oct 2019 13:17:20 +0000 (-0400) Subject: commit bash-20191009 snapshot X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aa99ef520f943369c826b02f3398fa8eab7bfdfb;p=thirdparty%2Fbash.git commit bash-20191009 snapshot --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 515836f76..625214146 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -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 (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 and + Robert Elz + + 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 + +lib/sh/shmatch.c + - sh_regmatch: implement a suggestion from Grisha Levit + and don't allow nocaseglob to enable case- + insensitive regexp matching. It hasn't been documented that way + in years diff --git a/execute_cmd.c b/execute_cmd.c index f6423e5b2..21d45cf0e 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -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; diff --git a/execute_cmd.h b/execute_cmd.h index dc2f15ec6..5ec0abef7 100644 --- a/execute_cmd.h +++ b/execute_cmd.h @@ -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)); diff --git a/include/shmbutil.h b/include/shmbutil.h index 36902f16b..835fb80cd 100644 --- a/include/shmbutil.h +++ b/include/shmbutil.h @@ -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. @@ -29,12 +29,13 @@ #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 */ diff --git a/lib/glob/glob.c b/lib/glob/glob.c index 4c7e8b959..cd077899f 100644 --- a/lib/glob/glob.c +++ b/lib/glob/glob.c @@ -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; diff --git a/lib/glob/sm_loop.c b/lib/glob/sm_loop.c index e352cc9fb..bddc96538 100644 --- a/lib/glob/sm_loop.c +++ b/lib/glob/sm_loop.c @@ -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 diff --git a/lib/glob/smatch.c b/lib/glob/smatch.c index b2b8b35e4..a74fe9ea8 100644 --- a/lib/glob/smatch.c +++ b/lib/glob/smatch.c @@ -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)) diff --git a/lib/sh/shmatch.c b/lib/sh/shmatch.c index da05211e8..1cca7038a 100644 --- a/lib/sh/shmatch.c +++ b/lib/sh/shmatch.c @@ -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; diff --git a/pathexp.c b/pathexp.c index 572db7530..c68257366 100644 --- 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 0fd33a6f1..0d2238257 100644 --- 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 diff --git a/tests/glob.right b/tests/glob.right index 82ed3d8ae..147a4bab7 100644 --- a/tests/glob.right +++ b/tests/glob.right @@ -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 diff --git a/tests/glob3.sub b/tests/glob3.sub index 3c92854da..662c65e97 100644 --- a/tests/glob3.sub +++ b/tests/glob3.sub @@ -12,7 +12,13 @@ # along with this program. If not, see . # : ${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