diff -Nrup a/posix/fnmatch.c b/posix/fnmatch.c --- a/posix/fnmatch.c 2012-01-01 07:16:32.000000000 -0500 +++ b/posix/fnmatch.c 2012-05-23 14:14:29.099461189 -0400 @@ -333,6 +333,7 @@ fnmatch (pattern, string, flags) # if HANDLE_MULTIBYTE if (__builtin_expect (MB_CUR_MAX, 1) != 1) { + const char *orig_pattern = pattern; mbstate_t ps; size_t n; const char *p; @@ -356,10 +357,8 @@ fnmatch (pattern, string, flags) alloca_used); n = mbsrtowcs (wpattern, &p, n + 1, &ps); if (__glibc_unlikely (n == (size_t) -1)) - /* Something wrong. - XXX Do we have to set `errno' to something which mbsrtows hasn't - already done? */ - return -1; + /* Something wrong: Fall back to single byte matching. */ + goto try_singlebyte; if (p) { memset (&ps, '\0', sizeof (ps)); @@ -371,10 +370,8 @@ fnmatch (pattern, string, flags) prepare_wpattern: n = mbsrtowcs (NULL, &pattern, 0, &ps); if (__glibc_unlikely (n == (size_t) -1)) - /* Something wrong. - XXX Do we have to set `errno' to something which mbsrtows hasn't - already done? */ - return -1; + /*Something wrong: Fall back to single byte matching. */ + goto try_singlebyte; if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t))) { __set_errno (ENOMEM); @@ -401,14 +398,8 @@ fnmatch (pattern, string, flags) alloca_used); n = mbsrtowcs (wstring, &p, n + 1, &ps); if (__glibc_unlikely (n == (size_t) -1)) - { - /* Something wrong. - XXX Do we have to set `errno' to something which - mbsrtows hasn't already done? */ - free_return: - free (wpattern_malloc); - return -1; - } + /* Something wrong: Fall back to single byte matching. */ + goto free_and_try_singlebyte; if (p) { memset (&ps, '\0', sizeof (ps)); @@ -420,10 +411,8 @@ fnmatch (pattern, string, flags) prepare_wstring: n = mbsrtowcs (NULL, &string, 0, &ps); if (__glibc_unlikely (n == (size_t) -1)) - /* Something wrong. - XXX Do we have to set `errno' to something which mbsrtows hasn't - already done? */ - goto free_return; + /* Something wrong: Fall back to singlebyte matching. */ + goto free_and_try_singlebyte; if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t))) { free (wpattern_malloc); @@ -450,6 +439,10 @@ fnmatch (pattern, string, flags) free (wpattern_malloc); return res; + free_and_try_singlebyte: + free(wpattern_malloc); + try_singlebyte: + pattern = orig_pattern; } # endif /* mbstate_t and mbsrtowcs or _LIBC. */