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