From d012b7df7ec1d6c813cfcc85e8f144aff148d516 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 5 Aug 2004 18:55:24 +0000 Subject: Update. Ulrich Drepper * wcsmbs/mbsrtowcs_l.c (__mbsrtowcs_l): Don't read more input character than necessary. 2004-08-05 Ulrich Drepper * wcsmbs/Makefile (tests): Add tst-mbsrtowcs. * wcsmbs/tst-mbsrtowcs.c: New file. * po/fr.po: Update from translation team. 2004-08-04 Jakub Jelinek If neither IPv4 nor IPv6 interface is present we cannot make any --- wcsmbs/Makefile | 4 ++-- wcsmbs/mbsrtowcs_l.c | 32 +++++++++++++++++++------ wcsmbs/tst-mbsrtowcs.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 wcsmbs/tst-mbsrtowcs.c (limited to 'wcsmbs') diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile index 005c49d..47a489a 100644 --- a/wcsmbs/Makefile +++ b/wcsmbs/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1995-2000, 2002, 2003 Free Software Foundation, Inc. +# Copyright (C) 1995-2000, 2002, 2003, 2004 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -40,7 +40,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ wcsmbsload mbsrtowcs_l tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ - tst-wcrtomb tst-wcpncpy + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs include ../Rules diff --git a/wcsmbs/mbsrtowcs_l.c b/wcsmbs/mbsrtowcs_l.c index 1e46856..8da3095 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; diff --git a/wcsmbs/tst-mbsrtowcs.c b/wcsmbs/tst-mbsrtowcs.c new file mode 100644 index 0000000..eb6c8e2 --- /dev/null +++ b/wcsmbs/tst-mbsrtowcs.c @@ -0,0 +1,65 @@ +/* Test NUL handling of mbsrtowcs. + Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2004. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + +int +main (void) +{ + const unsigned char buf[] = { 'a', 'b', '\0', 'c', 'd', '\0', 'e' }; + wchar_t out[sizeof (buf)]; + memset (out, '\xff', sizeof (out)); + + mbstate_t state; + memset (&state, '\0', sizeof (state)); + + const char *in = buf; + size_t n = mbsrtowcs (out, &in, sizeof (out) / sizeof (wchar_t), &state); + + int result = 0; + if (n != 2) + { + printf ("n = %zu, expected 2\n", n); + result = 1; + } + if (in != NULL) + { + printf ("in = %p, expected NULL\n", in); + result = 1; + } + if (out[0] != L'a') + { + printf ("out[0] = L'%lc', expected L'a'\n", (wint_t) out[0]); + result = 1; + } + if (out[1] != L'b') + { + printf ("out[1] = L'%lc', expected L'b'\n", (wint_t) out[1]); + result = 1; + } + if (out[2] != L'\0') + { + printf ("out[2] = L'%lc', expected L'\\0'\n", (wint_t) out[2]); + result = 1; + } + return result; +} -- cgit v1.1