fnmatch: Use __mbstowcs_alloc [BZ #23519]

Message ID 20180814154642.09826405971F7@oldenburg.str.redhat.com
State Superseded
Headers

Commit Message

Florian Weimer Aug. 14, 2018, 3:46 p.m. UTC
  2018-08-14  Florian Weimer  <fweimer@redhat.com>

	[BZ #23519]
	* posix/fnmatch.c [HANDLE_MULTIBYTE] (fnmatch): Use
	__mbstowcs_alloc.
  

Patch

diff --git a/posix/fnmatch.c b/posix/fnmatch.c
index a9b762624f..d2a86839c6 100644
--- a/posix/fnmatch.c
+++ b/posix/fnmatch.c
@@ -325,119 +325,28 @@  fnmatch (const char *pattern, const char *string, int flags)
       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;
 
-      /* 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))
-	{
-	  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;
-	    }
-	}
-      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);
-	}
+      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;
 
-      assert (mbsinit (&ps));
-#ifdef _LIBC
-      n = __strnlen (string, 1024);
-#else
-      n = strlen (string);
-#endif
-      p = string;
-      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)
 	{
-	  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;
-	    }
+	  free (to_free1);
+	  return -1;
 	}
-      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.  */