diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index c23914a8..798f0eb6 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -6130,3 +6130,33 @@ execute_cmd.c builtin (flags&CMD_COMMAND_BUILTIN), don't bother to print the command words if set -x is enabled. From a report by Martijn Dekker back in 4/2018 + + 6/19 + ---- +lib/glob/glob.c + - glob_filename: if we are not being called recursively, and there is + only a directory name, dequote the passed pathname and see if it + names an existing directory. If it does, return it; otherwise return + failure ((char **)&glob_error_return). This is what makes backslash + escaped-characters in pathnames in shell variables work the same as + the same value passed directly. From an anonymous comment on + https://savannah.gnu.org/support/?109629 and a discussion on the + austin-group list. + + 6/20 + ---- +pathexp.c,lib/glob/glob.c + - posix_glob_backslash: variable to control whether or not pathname + expansion handles backslashes in the pattern the way Posix says it + should. Enabled by default + +pathexp.h + - posix_glob_backslash: new extern declaration + +builtins/shopt.def + - posixglob: new option, reflects the value of posix_glob_backslash + +general.c + - posix_vars: add posix_glob_backslash to the table + - posix_initialize: set posix_glob_backslash to 1 when turning on + posix mode diff --git a/Makefile.in b/Makefile.in index 20a0dd6e..f0e5926e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1051,6 +1051,7 @@ general.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command. general.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h general.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h general.o: make_cmd.h subst.h sig.h pathnames.h externs.h flags.h parser.h +general.o: pathexp.h general.o: ${BASHINCDIR}/maxpath.h ${BASHINCDIR}/posixtime.h general.o: ${BASHINCDIR}/chartypes.h hashcmd.o: config.h ${BASHINCDIR}/posixstat.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h diff --git a/builtins/shopt.def b/builtins/shopt.def index 1c485361..223642ed 100644 --- a/builtins/shopt.def +++ b/builtins/shopt.def @@ -93,6 +93,7 @@ extern int lastpipe_opt; extern int inherit_errexit; extern int localvar_inherit; extern int localvar_unset; +extern int posix_glob_backslash; #if defined (EXTENDED_GLOB) extern int extended_glob; @@ -229,6 +230,7 @@ static struct { { "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL }, { "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL }, { "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL }, + { "posixglob", &posix_glob_backslash, (shopt_set_func_t *)NULL }, #if defined (PROGRAMMABLE_COMPLETION) { "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL }, # if defined (ALIAS) diff --git a/doc/bash.1 b/doc/bash.1 index b372c258..d79f3a65 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -5,12 +5,12 @@ .\" Case Western Reserve University .\" chet.ramey@case.edu .\" -.\" Last Change: Mon May 20 10:45:39 EDT 2019 +.\" Last Change: Wed Jun 19 11:22:28 EDT 2019 .\" .\" bash_builtins, strip all but Built-Ins section .if \n(zZ=1 .ig zZ .if \n(zY=1 .ig zY -.TH BASH 1 "2019 May 20" "GNU Bash 5.0" +.TH BASH 1 "2019 June 19" "GNU Bash 5.0" .\" .\" There's some problem with having a `@' .\" in a tagged paragraph with the BSD man macros. @@ -4493,6 +4493,8 @@ A null value evaluates to 0. A shell variable need not have its \fIinteger\fP attribute turned on to be used in an expression. .PP +Integer constants follow the C language definition, without suffixes or +character constants. Constants with a leading 0 are interpreted as octal numbers. A leading 0x or 0X denotes hexadecimal. Otherwise, numbers take the form [\fIbase#\fP]n, where the optional \fIbase\fP @@ -4500,6 +4502,7 @@ is a decimal number between 2 and 64 representing the arithmetic base, and \fIn\fP is a number in that base. If \fIbase#\fP is omitted, then base 10 is used. When specifying \fIn\fP, +if a non-digit is required, the digits greater than 9 are represented by the lowercase letters, the uppercase letters, @, and _, in that order. If \fIbase\fP is less than or equal to 36, lowercase and uppercase diff --git a/doc/bashref.texi b/doc/bashref.texi index f115484c..984e8901 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -7083,6 +7083,8 @@ A null value evaluates to 0. A shell variable need not have its @var{integer} attribute turned on to be used in an expression. +Integer constants follow the C language definition, without suffixes or +character constants. Constants with a leading 0 are interpreted as octal numbers. A leading @samp{0x} or @samp{0X} denotes hexadecimal. Otherwise, numbers take the form [@var{base}@code{#}]@var{n}, where the optional @var{base} @@ -7090,6 +7092,7 @@ is a decimal number between 2 and 64 representing the arithmetic base, and @var{n} is a number in that base. If @var{base}@code{#} is omitted, then base 10 is used. When specifying @var{n}, +if a non-digit is required, the digits greater than 9 are represented by the lowercase letters, the uppercase letters, @samp{@@}, and @samp{_}, in that order. If @var{base} is less than or equal to 36, lowercase and uppercase diff --git a/doc/version.texi b/doc/version.texi index cbadea72..a5a6f5ba 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -2,10 +2,10 @@ Copyright (C) 1988-2019 Free Software Foundation, Inc. @end ignore -@set LASTCHANGE Thu Jun 13 15:43:41 EDT 2019 +@set LASTCHANGE Wed Jun 19 11:22:46 EDT 2019 @set EDITION 5.0 @set VERSION 5.0 -@set UPDATED 13 June 2019 +@set UPDATED 19 June 2019 @set UPDATED-MONTH June 2019 diff --git a/general.c b/general.c index 2a6edc1c..f8eae57c 100644 --- a/general.c +++ b/general.c @@ -1,6 +1,6 @@ /* general.c -- Stuff that is used by all files. */ -/* Copyright (C) 1987-2016 Free Software Foundation, Inc. +/* Copyright (C) 1987-2019 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -44,6 +44,7 @@ #include "findcmd.h" #include "test.h" #include "trap.h" +#include "pathexp.h" #include "builtins/common.h" @@ -75,6 +76,7 @@ const char * const bash_getcwd_errstr = N_("getcwd: cannot access parent directo expand_aliases inherit_errexit print_shift_error + posixglob and the following variables which cannot be user-modified: @@ -91,6 +93,7 @@ static struct { &source_uses_path, &expand_aliases, &inherit_errexit, + &posix_glob_backslash, &print_shift_error, 0 }; @@ -106,7 +109,7 @@ posix_initialize (on) inherit_errexit = 1; source_searches_cwd = 0; print_shift_error = 1; - + posix_glob_backslash = 1; } /* Things that should be turned on when posix mode is disabled. */ diff --git a/lib/glob/glob.c b/lib/glob/glob.c index ee0dd14f..e1cbce28 100644 --- a/lib/glob/glob.c +++ b/lib/glob/glob.c @@ -1,6 +1,6 @@ /* glob.c -- file-name wildcard pattern matching for Bash. - Copyright (C) 1985-2017 Free Software Foundation, Inc. + Copyright (C) 1985-2019 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne-Again SHell. @@ -91,6 +91,7 @@ extern int signal_is_pending __P((int)); extern void run_pending_traps __P((void)); extern int extended_glob; +extern int posix_glob_backslash; /* Global variable which controls whether or not * matches .*. Non-zero means don't match .*. */ @@ -1410,7 +1411,25 @@ only_filename: /* 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. */ + if not, but we don't do that. We do return the dequoted directory + name if we're not being called recursively and the dequoted name + corresponds to an actual directory. For better backwards compatibility, + we can return &glob_error_return unconditionally in this case. */ + + if (directory_len > 0 && hasglob == 2 && (flags & GX_RECURSE) == 0) + { +#if 1 + dequote_pathname (directory_name); + if (glob_testdir (directory_name, 0) < 0) + { + if (free_dirname) + free (directory_name); + return ((char **)&glob_error_return); + } +#else + return ((char **)&glob_error_return); +#endif + } /* Handle GX_MARKDIRS here. */ result[0] = (char *) malloc (directory_len + 1); diff --git a/lib/glob/glob_loop.c b/lib/glob/glob_loop.c index 3a4f4f1e..92329b3e 100644 --- a/lib/glob/glob_loop.c +++ b/lib/glob/glob_loop.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2017 Free Software Foundation, Inc. +/* Copyright (C) 1991-2019 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -70,7 +70,7 @@ INTERNAL_GLOB_PATTERN_P (pattern) return 0; } - return bsquote ? 2 : 0; + return ((bsquote && posix_glob_backslash) ? 2 : 0); } #undef INTERNAL_GLOB_PATTERN_P diff --git a/pathexp.c b/pathexp.c index c1bf2d89..eee5dad8 100644 --- a/pathexp.c +++ b/pathexp.c @@ -58,6 +58,9 @@ int extended_glob = EXTGLOB_DEFAULT; /* Control enabling special handling of `**' */ int glob_star = 0; +/* Do we handle backslashes in patterns the way Posix specifies? */ +int posix_glob_backslash = 1; + /* Return nonzero if STRING has any unquoted special globbing chars in it. */ int unquoted_glob_pattern_p (string) @@ -125,7 +128,7 @@ unquoted_glob_pattern_p (string) #endif } - return (bsquote ? 2 : 0); + return ((bsquote && posix_glob_backslash) ? 2 : 0); } /* Return 1 if C is a character that is `special' in a POSIX ERE and needs to @@ -433,11 +436,12 @@ shell_glob_filename (pathname) #else /* !USE_POSIX_GLOB_LIBRARY */ char *temp, **results; - int gflags; + int gflags, quoted_pattern; noglob_dot_filenames = glob_dot_filenames == 0; temp = quote_string_for_globbing (pathname, QGLOB_FILENAME); + quoted_pattern = STREQ (pathname, temp) == 0; gflags = glob_star ? GX_GLOBSTAR : 0; results = glob_filename (temp, gflags); free (temp); diff --git a/pathexp.h b/pathexp.h index adef8b2a..d72d99a3 100644 --- a/pathexp.h +++ b/pathexp.h @@ -51,6 +51,7 @@ extern int glob_dot_filenames; extern int extended_glob; extern int glob_star; extern int match_ignore_case; /* doesn't really belong here */ +extern int posix_glob_backslash; extern int unquoted_glob_pattern_p __P((char *)); diff --git a/tests/errors.right b/tests/errors.right index 83338ae0..d5fc6325 100644 --- a/tests/errors.right +++ b/tests/errors.right @@ -12,7 +12,6 @@ unset: usage: unset [-f] [-v] [-n] [name ...] ./errors.tests: line 42: unset: func: cannot unset: readonly function ./errors.tests: line 45: declare: func: readonly function ./errors.tests: line 49: unset: XPATH: cannot unset: readonly variable -./errors.tests: line 52: unset: `/bin/sh': not a valid identifier ./errors.tests: line 55: unset: cannot simultaneously unset a function and a variable ./errors.tests: line 58: declare: -z: invalid option declare: usage: declare [-aAfFgilnrtux] [-p] [name[=value] ...] diff --git a/tests/glob.right b/tests/glob.right index 754aa12d..12433841 100644 --- a/tests/glob.right +++ b/tests/glob.right @@ -79,8 +79,8 @@ argv[1] = <./t\mp/a/*> argv[1] = <./tmp/a/b/c> argv[1] = <./tmp/a/> argv[1] = <./tmp/a/b/> -argv[1] = <./t\mp/a/> -argv[1] = <./t\mp/a/b/> +argv[1] = <./tmp/a/> +argv[1] = <./tmp/a/b/> argv[1] = <./tmp/a/*> argv[1] = <./tmp/a/b/c> argv[1] = <./tmp/a> @@ -88,6 +88,9 @@ argv[1] = <./tmp/a/b*> argv[1] = <./tmp/a> argv[1] = <./tmp/a/b*> argv[1] = <./tmp/> +argv[1] = <\$foo> +argv[2] = <\$foo> +argv[1] = argv[1] = argv[2] = argv[3] = diff --git a/tests/glob5.sub b/tests/glob5.sub index aaa9076d..b8fa3b22 100644 --- a/tests/glob5.sub +++ b/tests/glob5.sub @@ -50,5 +50,14 @@ recho ./t\mp/ chmod +r ./tmp/a rm -rf ./tmp/a +a='$foo' +b='$bar' +a=$(echo "$a" | sed 's/\$/\\$/g') + +recho $a "$a" +recho 'mixed'$a/ + +unset a b + cd $ORIGD rm -rf $SD diff --git a/tests/shopt.right b/tests/shopt.right index 08db75f1..07277f90 100644 --- a/tests/shopt.right +++ b/tests/shopt.right @@ -47,6 +47,7 @@ shopt -u no_empty_cmd_completion shopt -u nocaseglob shopt -u nocasematch shopt -u nullglob +shopt -s posixglob shopt -s progcomp shopt -u progcomp_alias shopt -s promptvars @@ -68,6 +69,7 @@ shopt -s force_fignore shopt -s globasciiranges shopt -s hostcomplete shopt -s interactive_comments +shopt -s posixglob shopt -s progcomp shopt -s promptvars shopt -s sourcepath