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