[PATCH] mbstowcs_r doesn't handle NULL target pointer
Corinna Vinschen
vinschen@redhat.com
Tue Mar 17 18:26:00 GMT 2009
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
More information about the Newlib
mailing list