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);           
        }

Reply via email to