287226
			     BASH PATCH REPORT
287226
			     =================
287226
287226
Bash-Release:	4.2
287226
Patch-ID:	bash42-030
287226
287226
Bug-Reported-by:	Roman Rakus <rrakus@redhat.com>
287226
Bug-Reference-ID:	<4D7DD91E.7040808@redhat.com>
287226
Bug-Reference-URL:	http://lists.gnu.org/archive/html/bug-bash/2011-03/msg00126.html
287226
287226
Bug-Description:
287226
287226
When attempting to glob strings in a multibyte locale, and those strings
287226
contain invalid multibyte characters that cause mbsnrtowcs to return 0,
287226
the globbing code loops infinitely.
287226
287226
Patch (apply with `patch -p0'):
287226
287226
*** ../bash-4.2-patched/lib/glob/xmbsrtowcs.c	2010-05-30 18:36:27.000000000 -0400
287226
--- lib/glob/xmbsrtowcs.c	2011-03-22 16:06:47.000000000 -0400
287226
***************
287226
*** 36,39 ****
287226
--- 36,41 ----
287226
  #if HANDLE_MULTIBYTE
287226
  
287226
+ #define WSBUF_INC 32
287226
+ 
287226
  #ifndef FREE
287226
  #  define FREE(x)	do { if (x) free (x); } while (0)
287226
***************
287226
*** 149,153 ****
287226
    size_t wcnum;		/* Number of wide characters in WSBUF */
287226
    mbstate_t state;	/* Conversion State */
287226
!   size_t wcslength;	/* Number of wide characters produced by the conversion. */
287226
    const char *end_or_backslash;
287226
    size_t nms;	/* Number of multibyte characters to convert at one time. */
287226
--- 151,155 ----
287226
    size_t wcnum;		/* Number of wide characters in WSBUF */
287226
    mbstate_t state;	/* Conversion State */
287226
!   size_t n, wcslength;	/* Number of wide characters produced by the conversion. */
287226
    const char *end_or_backslash;
287226
    size_t nms;	/* Number of multibyte characters to convert at one time. */
287226
***************
287226
*** 172,176 ****
287226
        tmp_p = p;
287226
        tmp_state = state;
287226
!       wcslength = mbsnrtowcs(NULL, &tmp_p, nms, 0, &tmp_state);
287226
  
287226
        /* Conversion failed. */
287226
--- 174,189 ----
287226
        tmp_p = p;
287226
        tmp_state = state;
287226
! 
287226
!       if (nms == 0 && *p == '\\')	/* special initial case */
287226
! 	nms = wcslength = 1;
287226
!       else
287226
! 	wcslength = mbsnrtowcs (NULL, &tmp_p, nms, 0, &tmp_state);
287226
! 
287226
!       if (wcslength == 0)
287226
! 	{
287226
! 	  tmp_p = p;		/* will need below */
287226
! 	  tmp_state = state;
287226
! 	  wcslength = 1;	/* take a single byte */
287226
! 	}
287226
  
287226
        /* Conversion failed. */
287226
***************
287226
*** 187,191 ****
287226
  	  wchar_t *wstmp;
287226
  
287226
! 	  wsbuf_size = wcnum+wcslength+1;	/* 1 for the L'\0' or the potential L'\\' */
287226
  
287226
  	  wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
287226
--- 200,205 ----
287226
  	  wchar_t *wstmp;
287226
  
287226
! 	  while (wsbuf_size < wcnum+wcslength+1) /* 1 for the L'\0' or the potential L'\\' */
287226
! 	    wsbuf_size += WSBUF_INC;
287226
  
287226
  	  wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
287226
***************
287226
*** 200,207 ****
287226
  
287226
        /* Perform the conversion. This is assumed to return 'wcslength'.
287226
!        * It may set 'p' to NULL. */
287226
!       mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state);
287226
  
287226
!       wcnum += wcslength;
287226
  
287226
        if (mbsinit (&state) && (p != NULL) && (*p == '\\'))
287226
--- 214,229 ----
287226
  
287226
        /* Perform the conversion. This is assumed to return 'wcslength'.
287226
! 	 It may set 'p' to NULL. */
287226
!       n = mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state);
287226
  
287226
!       /* Compensate for taking single byte on wcs conversion failure above. */
287226
!       if (wcslength == 1 && (n == 0 || n == (size_t)-1))
287226
! 	{
287226
! 	  state = tmp_state;
287226
! 	  p = tmp_p;
287226
! 	  wsbuf[wcnum++] = *p++;
287226
! 	}
287226
!       else
287226
!         wcnum += wcslength;
287226
  
287226
        if (mbsinit (&state) && (p != NULL) && (*p == '\\'))
287226
***************
287226
*** 231,236 ****
287226
     of DESTP and INDICESP are NULL. */
287226
  
287226
- #define WSBUF_INC 32
287226
- 
287226
  size_t
287226
  xdupmbstowcs (destp, indicesp, src)
287226
--- 253,256 ----
287226
*** ../bash-4.2-patched/lib/glob/glob.c	2009-11-14 18:39:30.000000000 -0500
287226
--- lib/glob/glob.c	2012-07-07 12:09:56.000000000 -0400
287226
***************
287226
*** 201,206 ****
287226
    size_t pat_n, dn_n;
287226
  
287226
    pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
287226
!   dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
287226
  
287226
    ret = 0;
287226
--- 201,209 ----
287226
    size_t pat_n, dn_n;
287226
  
287226
+   pat_wc = dn_wc = (wchar_t *)NULL;
287226
+ 
287226
    pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
287226
!   if (pat_n != (size_t)-1)
287226
!     dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
287226
  
287226
    ret = 0;
287226
***************
287226
*** 222,225 ****
287226
--- 225,230 ----
287226
  	ret = 1;
287226
      }
287226
+   else
287226
+     ret = skipname (pat, dname, flags);
287226
  
287226
    FREE (pat_wc);
287226
***************
287226
*** 267,272 ****
287226
    n = xdupmbstowcs (&wpathname, NULL, pathname);
287226
    if (n == (size_t) -1)
287226
!     /* Something wrong. */
287226
!     return;
287226
    orig_wpathname = wpathname;
287226
  
287226
--- 272,280 ----
287226
    n = xdupmbstowcs (&wpathname, NULL, pathname);
287226
    if (n == (size_t) -1)
287226
!     {
287226
!       /* Something wrong.  Fall back to single-byte */
287226
!       udequote_pathname (pathname);
287226
!       return;
287226
!     }
287226
    orig_wpathname = wpathname;
287226
  
287226
*** ../bash-4.2-patched/patchlevel.h	Sat Jun 12 20:14:48 2010
287226
--- patchlevel.h	Thu Feb 24 21:41:34 2011
287226
***************
287226
*** 26,30 ****
287226
     looks for to find the patch level (for the sccs version string). */
287226
  
287226
! #define PATCHLEVEL 29
287226
  
287226
  #endif /* _PATCHLEVEL_H_ */
287226
--- 26,30 ----
287226
     looks for to find the patch level (for the sccs version string). */
287226
  
287226
! #define PATCHLEVEL 30
287226
  
287226
  #endif /* _PATCHLEVEL_H_ */