7 Bug-Reported-by: Roman Rakus <rrakus@redhat.com>
8 Bug-Reference-ID: <4D7DD91E.7040808@redhat.com>
9 Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2011-03/msg00126.html
13 When attempting to glob strings in a multibyte locale, and those strings
14 contain invalid multibyte characters that cause mbsnrtowcs to return 0,
15 the globbing code loops infinitely.
17 Patch (apply with `patch -p0'):
19 *** ../bash-4.2-patched/lib/glob/xmbsrtowcs.c 2010-05-30 18:36:27.000000000 -0400
20 --- lib/glob/xmbsrtowcs.c 2011-03-22 16:06:47.000000000 -0400
26 + #define WSBUF_INC 32
29 # define FREE(x) do { if (x) free (x); } while (0)
32 size_t wcnum; /* Number of wide characters in WSBUF */
33 mbstate_t state; /* Conversion State */
34 ! size_t wcslength; /* Number of wide characters produced by the conversion. */
35 const char *end_or_backslash;
36 size_t nms; /* Number of multibyte characters to convert at one time. */
38 size_t wcnum; /* Number of wide characters in WSBUF */
39 mbstate_t state; /* Conversion State */
40 ! size_t n, wcslength; /* Number of wide characters produced by the conversion. */
41 const char *end_or_backslash;
42 size_t nms; /* Number of multibyte characters to convert at one time. */
47 ! wcslength = mbsnrtowcs(NULL, &tmp_p, nms, 0, &tmp_state);
49 /* Conversion failed. */
54 ! if (nms == 0 && *p == '\\') /* special initial case */
55 ! nms = wcslength = 1;
57 ! wcslength = mbsnrtowcs (NULL, &tmp_p, nms, 0, &tmp_state);
61 ! tmp_p = p; /* will need below */
63 ! wcslength = 1; /* take a single byte */
66 /* Conversion failed. */
71 ! wsbuf_size = wcnum+wcslength+1; /* 1 for the L'\0' or the potential L'\\' */
73 wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
77 ! while (wsbuf_size < wcnum+wcslength+1) /* 1 for the L'\0' or the potential L'\\' */
78 ! wsbuf_size += WSBUF_INC;
80 wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
84 /* Perform the conversion. This is assumed to return 'wcslength'.
85 ! * It may set 'p' to NULL. */
86 ! mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state);
90 if (mbsinit (&state) && (p != NULL) && (*p == '\\'))
93 /* Perform the conversion. This is assumed to return 'wcslength'.
94 ! It may set 'p' to NULL. */
95 ! n = mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state);
97 ! /* Compensate for taking single byte on wcs conversion failure above. */
98 ! if (wcslength == 1 && (n == 0 || n == (size_t)-1))
102 ! wsbuf[wcnum++] = *p++;
105 ! wcnum += wcslength;
107 if (mbsinit (&state) && (p != NULL) && (*p == '\\'))
110 of DESTP and INDICESP are NULL. */
112 - #define WSBUF_INC 32
115 xdupmbstowcs (destp, indicesp, src)
117 *** ../bash-4.2-patched/lib/glob/glob.c 2009-11-14 18:39:30.000000000 -0500
118 --- lib/glob/glob.c 2012-07-07 12:09:56.000000000 -0400
123 pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
124 ! dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
130 + pat_wc = dn_wc = (wchar_t *)NULL;
132 pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
133 ! if (pat_n != (size_t)-1)
134 ! dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
143 + ret = skipname (pat, dname, flags);
148 n = xdupmbstowcs (&wpathname, NULL, pathname);
149 if (n == (size_t) -1)
150 ! /* Something wrong. */
152 orig_wpathname = wpathname;
155 n = xdupmbstowcs (&wpathname, NULL, pathname);
156 if (n == (size_t) -1)
158 ! /* Something wrong. Fall back to single-byte */
159 ! udequote_pathname (pathname);
162 orig_wpathname = wpathname;
164 *** ../bash-4.2-patched/patchlevel.h Sat Jun 12 20:14:48 2010
165 --- patchlevel.h Thu Feb 24 21:41:34 2011
168 looks for to find the patch level (for the sccs version string). */
170 ! #define PATCHLEVEL 29
172 #endif /* _PATCHLEVEL_H_ */
174 looks for to find the patch level (for the sccs version string). */
176 ! #define PATCHLEVEL 30
178 #endif /* _PATCHLEVEL_H_ */