about summary refs log tree commit diff
path: root/wcsmbs/mbsrtowcs_l.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-08-05 18:55:24 +0000
committerUlrich Drepper <drepper@redhat.com>2004-08-05 18:55:24 +0000
commitd012b7df7ec1d6c813cfcc85e8f144aff148d516 (patch)
tree15dd0ea978d574f06f5f6a0e9d0fec32064495e4 /wcsmbs/mbsrtowcs_l.c
parent08bcfb594bceff6d74bce2d8298239881cef8d7d (diff)
downloadglibc-d012b7df7ec1d6c813cfcc85e8f144aff148d516.tar.gz
glibc-d012b7df7ec1d6c813cfcc85e8f144aff148d516.tar.xz
glibc-d012b7df7ec1d6c813cfcc85e8f144aff148d516.zip
Update.
	    Ulrich Drepper  <drepper@redhat.com>

	* wcsmbs/mbsrtowcs_l.c (__mbsrtowcs_l): Don't read more input
	character than necessary.

2004-08-05  Ulrich Drepper  <drepper@redhat.com>

	* wcsmbs/Makefile (tests): Add tst-mbsrtowcs.
	* wcsmbs/tst-mbsrtowcs.c: New file.

	* po/fr.po: Update from translation team.

2004-08-04  Jakub Jelinek  <jakub@redhat.com>
	If neither IPv4 nor IPv6 interface is present we cannot make any
Diffstat (limited to 'wcsmbs/mbsrtowcs_l.c')
-rw-r--r--wcsmbs/mbsrtowcs_l.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/wcsmbs/mbsrtowcs_l.c b/wcsmbs/mbsrtowcs_l.c
index 1e46856172..8da3095566 100644
--- a/wcsmbs/mbsrtowcs_l.c
+++ b/wcsmbs/mbsrtowcs_l.c
@@ -102,18 +102,36 @@ __mbsrtowcs_l (dst, src, len, ps, l)
       /* This code is based on the safe assumption that all internal
 	 multi-byte encodings use the NUL byte only to mark the end
 	 of the string.  */
+      const unsigned char *srcp = (const unsigned char *) *src;
       const unsigned char *srcend;
 
-      srcend = (const unsigned char *) (*src
-					+ __strnlen (*src, len * MB_CUR_MAX)
-					+ 1);
-
       data.__outbuf = (unsigned char *) dst;
       data.__outbufend = data.__outbuf + len * sizeof (wchar_t);
 
-      status = DL_CALL_FCT (towc->__fct,
-			    (towc, &data, (const unsigned char **) src, srcend,
-			     NULL, &non_reversible, 0, 1));
+      status = __GCONV_FULL_OUTPUT;
+
+      while (len > 0)
+	{
+	  /* Pessimistic guess as to how much input we can use.  In the
+	     worst case we need one input byte for one output wchar_t.  */
+	  srcend = srcp + __strnlen (srcp, len) + 1;
+
+	  status = DL_CALL_FCT (towc->__fct,
+				(towc, &data, &srcp, srcend, NULL,
+				 &non_reversible, 0, 1));
+	  if ((status != __GCONV_EMPTY_INPUT
+	       && status != __GCONV_INCOMPLETE_INPUT)
+	      /* Not all input read.  */
+	      || srcp != srcend
+	      /* Reached the end of the input.  */
+	      || srcend[-1] == '\0')
+	    break;
+
+	  len = (wchar_t *) data.__outbufend - (wchar_t *) data.__outbuf;
+	}
+
+      /* Make the end if the input known to the caller.  */
+      *src = srcp;
 
       result = (wchar_t *) data.__outbuf - dst;