This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] fnmatch: Use __mbstowcs_alloc [BZ #23519]
Sorry, I posted the wrong version of the patch. Try this one.
Subject: [PATCH] fnmatch: Use __mbstowcs_alloc [BZ #23519]
To: libc-alpha@sourceware.org
2018-08-14 Florian Weimer <fweimer@redhat.com>
[BZ #23519]
* posix/fnmatch.c [HANDLE_MULTIBYTE] (fnmatch): Use
__mbstowcs_alloc.
diff --git a/posix/fnmatch.c b/posix/fnmatch.c
index a9b762624f..1ce6c88d6a 100644
--- a/posix/fnmatch.c
+++ b/posix/fnmatch.c
@@ -35,6 +35,7 @@
#endif
#ifdef _LIBC
+# include <array_length.h>
# include <alloca.h>
#else
# define alloca_account(size., var) alloca (size)
@@ -322,122 +323,28 @@ fnmatch (const char *pattern, const char *string, int flags)
# if HANDLE_MULTIBYTE
if (__builtin_expect (MB_CUR_MAX, 1) != 1)
{
- mbstate_t ps;
- size_t n;
- const char *p;
- wchar_t *wpattern_malloc = NULL;
- wchar_t *wpattern;
- wchar_t *wstring_malloc = NULL;
- wchar_t *wstring;
- size_t alloca_used = 0;
+ void *to_free1;
+ wchar_t wpattern_scratch[256];
+ wchar_t *wpattern = __mbstowcs_alloc
+ (pattern, wpattern_scratch, array_length (wpattern_scratch), &to_free1);
+ if (wpattern == NULL)
+ return -1;
- /* Convert the strings into wide characters. */
- memset (&ps, '\0', sizeof (ps));
- p = pattern;
-#ifdef _LIBC
- n = __strnlen (pattern, 1024);
-#else
- n = strlen (pattern);
-#endif
- if (__glibc_likely (n < 1024))
+ void *to_free2;
+ wchar_t wstring_scratch[256];
+ wchar_t *wstring = __mbstowcs_alloc
+ (string, wstring_scratch, array_length (wstring_scratch), &to_free2);
+ if (wstring == NULL)
{
- wpattern = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
- 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;
- if (p)
- {
- memset (&ps, '\0', sizeof (ps));
- goto prepare_wpattern;
- }
+ free (to_free1);
+ return -1;
}
- else
- {
- 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;
- if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
- {
- __set_errno (ENOMEM);
- return -2;
- }
- wpattern_malloc = wpattern
- = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
- assert (mbsinit (&ps));
- if (wpattern == NULL)
- return -2;
- (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
- }
-
- assert (mbsinit (&ps));
-#ifdef _LIBC
- n = __strnlen (string, 1024);
-#else
- n = strlen (string);
-#endif
- p = string;
- if (__glibc_likely (n < 1024))
- {
- wstring = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
- 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;
- }
- if (p)
- {
- memset (&ps, '\0', sizeof (ps));
- goto prepare_wstring;
- }
- }
- else
- {
- 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;
- if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
- {
- free (wpattern_malloc);
- __set_errno (ENOMEM);
- return -2;
- }
-
- wstring_malloc = wstring
- = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
- if (wstring == NULL)
- {
- free (wpattern_malloc);
- return -2;
- }
- assert (mbsinit (&ps));
- (void) mbsrtowcs (wstring, &string, n + 1, &ps);
- }
-
- int res = internal_fnwmatch (wpattern, wstring, wstring + n,
- flags & FNM_PERIOD, flags, NULL,
- alloca_used);
-
- free (wstring_malloc);
- free (wpattern_malloc);
+ int res = internal_fnwmatch (wpattern,
+ wstring, wstring + __wcslen (wstring),
+ flags & FNM_PERIOD, flags, NULL, 0);
+ free (to_free2);
+ free (to_free1);
return res;
}
# endif /* mbstate_t and mbsrtowcs or _LIBC. */