diff options
author | Ulrich Drepper <drepper@redhat.com> | 2004-08-05 18:55:24 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2004-08-05 18:55:24 +0000 |
commit | d012b7df7ec1d6c813cfcc85e8f144aff148d516 (patch) | |
tree | 15dd0ea978d574f06f5f6a0e9d0fec32064495e4 /wcsmbs/mbsrtowcs_l.c | |
parent | 08bcfb594bceff6d74bce2d8298239881cef8d7d (diff) | |
download | glibc-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.c | 32 |
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; |