This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] mbstowcs_r doesn't handle NULL target pointer


Hi,

I just applied the below patch which fixes a serious problem in
mbstowcs/_mbstowcs_r.  The _mbstowcs_r function so far didn't handle
a NULL destination pointer correctly, as is required by POSIX.
Especially the third parameter `n' has to be ignoreed if the destination
parameter is a NULL pointer.  Quote from POSIX-1.2008:

  "If pwcs is a null pointer, mbstowcs() shall return the length
   required to convert the entire array regardless of the value of n,
   but no values are stored."

As a result, expressions like this:

  wchar_t *dest = NULL;
  size_t len = mbstowcs (NULL, src, 0) + 1;
  if (len > 0)
    {
      dest = (wchar_t *) malloc (len * sizeof (wchar_t));
      if (dest)
	mbstowcs (dest, src, len);
    }

didn't work at all.  The first call to mbstowcs always returned 0 in the
above case.


Corinna


	* libc/stdlib/mbstowcs_r.c (_mbstowcs_r): Handle NULL destination
	string correctly.


Index: libc/stdlib/mbstowcs_r.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdlib/mbstowcs_r.c,v
retrieving revision 1.3
diff -u -p -r1.3 mbstowcs_r.c
--- libc/stdlib/mbstowcs_r.c	9 Sep 2002 21:42:14 -0000	1.3
+++ libc/stdlib/mbstowcs_r.c	17 Mar 2009 12:07:35 -0000
@@ -9,25 +9,29 @@ _DEFUN (_mbstowcs_r, (reent, pwcs, s, n,
         size_t         n    _AND
         mbstate_t     *state)
 {
-  wchar_t *ptr = pwcs;
-  size_t max = n;
+  size_t ret = 0;
   char *t = (char *)s;
   int bytes;
 
+  if (!pwcs)
+    n = (size_t) 1; /* Value doesn't matter as long as it's not 0. */
   while (n > 0)
     {
-      bytes = _mbtowc_r (r, ptr, t, MB_CUR_MAX, state);
+      bytes = _mbtowc_r (r, pwcs, t, MB_CUR_MAX, state);
       if (bytes < 0)
 	{
 	  state->__count = 0;
 	  return -1;
 	}
       else if (bytes == 0)
-        return ptr - pwcs;
+	break;
       t += bytes;
-      ++ptr;
-      --n;
+      ++ret;
+      if (pwcs)
+	{
+	  ++pwcs;
+	  --n;
+	}
     }
-
-  return max;
+  return ret;
 }   


-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]