On 3/4/19 8:19 AM, wer...@suse.de wrote: > Bash Version: 5.0 > Patch Level: 2 > Release Status: release > > Description: > Since patch bash50-001 there is a regession on path expansion. > The script example below shows: > > bash/bash> bash tmp/bug.sh > 5.0.2(1)-release > drwxr-xr-x 2 nobody root 17 Mar 4 14:08 . > > bash/bash> /dist/unpacked/sle15-x86_64.full/bin/bash tmp/bug.sh > 4.4.23(1)-release > -rw-r--r-- 1 nobody root 0 Mar 4 14:10 > /tmp/bugthroughpatch001/hidden/foo/bar > > Disabling patch bash50-001 solves this problem but cause > other problems. It seems as seen by strace and ltrace that > the bash with patch bash50-001 now makes a stat(2) on every > single part of the path and run onto EACCES error which cause > the regression above.
http://lists.gnu.org/archive/html/bug-bash/2019-02/msg00151.html There is a slightly updated version of that patch attached to this message. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRU c...@case.edu http://tiswww.cwru.edu/~chet/
*** ../bash-5.0-patched/lib/glob/glob_loop.c 2019-01-16 16:13:21.000000000 -0500 --- lib/glob/glob_loop.c 2019-02-01 09:45:11.000000000 -0500 *************** *** 27,34 **** register const GCHAR *p; register GCHAR c; ! int bopen; p = pattern; ! bopen = 0; while ((c = *p++) != L('\0')) --- 27,34 ---- register const GCHAR *p; register GCHAR c; ! int bopen, bsquote; p = pattern; ! bopen = bsquote = 0; while ((c = *p++) != L('\0')) *************** *** 56,66 **** case L('\\'): /* Don't let the pattern end in a backslash (GMATCH returns no match ! if the pattern ends in a backslash anyway), but otherwise return 1, ! since the matching engine uses backslash as an escape character ! and it can be removed. */ ! return (*p != L('\0')); } ! return 0; } --- 56,75 ---- case L('\\'): /* Don't let the pattern end in a backslash (GMATCH returns no match ! if the pattern ends in a backslash anyway), but otherwise note that ! we have seen this, since the matching engine uses backslash as an ! escape character and it can be removed. We return 2 later if we ! have seen only backslash-escaped characters, so interested callers ! know they can shortcut and just dequote the pathname. */ ! if (*p != L('\0')) ! { ! p++; ! bsquote = 1; ! continue; ! } ! else /* (*p == L('\0')) */ ! return 0; } ! return bsquote ? 2 : 0; } *** ../bash-5.0-patched/lib/glob/glob.c 2018-09-20 10:53:23.000000000 -0400 --- lib/glob/glob.c 2019-01-31 19:14:13.000000000 -0500 *************** *** 1062,1066 **** unsigned int directory_len; int free_dirname; /* flag */ ! int dflags; result = (char **) malloc (sizeof (char *)); --- 1078,1082 ---- unsigned int directory_len; int free_dirname; /* flag */ ! int dflags, hasglob; result = (char **) malloc (sizeof (char *)); *************** *** 1111,1117 **** } /* If directory_name contains globbing characters, then we ! have to expand the previous levels. Just recurse. */ ! if (directory_len > 0 && glob_pattern_p (directory_name)) { char **directories, *d, *p; --- 1127,1136 ---- } + hasglob = 0; /* If directory_name contains globbing characters, then we ! have to expand the previous levels. Just recurse. ! If glob_pattern_p returns != [0,1] we have a pattern that has backslash ! quotes but no unquoted glob pattern characters. We dequote it below. */ ! if (directory_len > 0 && (hasglob = glob_pattern_p (directory_name)) == 1) { char **directories, *d, *p; *************** *** 1333,1336 **** --- 1352,1360 ---- return (NULL); } + if (directory_len > 0 && hasglob == 2) /* need to dequote */ + { + dequote_pathname (directory_name); + directory_len = strlen (directory_name); + } /* Handle GX_MARKDIRS here. */ result[0] = (char *) malloc (directory_len + 1); *** ../bash-5.0-patched/pathexp.c 2018-04-29 17:44:48.000000000 -0400 --- pathexp.c 2019-01-31 20:19:41.000000000 -0500 *************** *** 66,74 **** register int c; char *send; ! int open; DECLARE_MBSTATE; ! open = 0; send = string + strlen (string); --- 66,74 ---- register int c; char *send; ! int open, bsquote; DECLARE_MBSTATE; ! open = bsquote = 0; send = string + strlen (string); *************** *** 101,105 **** globbing. */ case '\\': ! return (*string != 0); case CTLESC: --- 101,112 ---- globbing. */ case '\\': ! if (*string != '\0' && *string != '/') ! { ! bsquote = 1; ! string++; ! continue; ! } ! else if (*string == 0) ! return (0); case CTLESC: *************** *** 118,122 **** #endif } ! return (0); } --- 125,130 ---- #endif } ! ! return (bsquote ? 2 : 0); } *** ../bash-5.0-patched/bashline.c 2019-01-16 16:13:21.000000000 -0500 --- bashline.c 2019-02-22 09:29:08.000000000 -0500 *************** *** 3753,3757 **** case '\\': ! if (*string == 0) return (0); } --- 3766,3770 ---- case '\\': ! if (*string++ == 0) return (0); }