aboutsummaryrefslogtreecommitdiff
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
glibc-d012b7df7ec1d6c813cfcc85e8f144aff148d516.tar.gz
glibc-d012b7df7ec1d6c813cfcc85e8f144aff148d516.tar.bz2
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;