The following program result in an assertion failure in __mbsnrtowcs:
% cat bug.c
const char * string = "Z";
const char *str2 = string;
const char *strend = string + 1;
printf("Locale: %s\n", setlocale(LC_ALL, "vi_VN.tcvn"));
memset (&ps, '\0', sizeof (ps));
while (str2 != NULL && str2 < strend)
if (mbsnrtowcs (ignore, &str2, strend - str2, 1, &ps) == (size_t) -1)
# ./elf/ld.so --library-path . ./a.out
a.out: mbsnrtowcs.c:124: __mbsnrtowcs: Assertion `result > 0' failed.
The reason is that the gconv loop doesn't make progress. I.e. somewhere
there's a problem in ./iconvdata/tcvn5712-1.c . The assert is here in
status = DL_CALL_FCT (fct,
(towc, &data, (const unsigned char **) src,
srcend, NULL, &dummy, 0, 1));
result = (wchar_t *) data.__outbuf - dst;
/* We have to determine whether the last character converted
is the NUL character. */
if ((status == __GCONV_OK || status == __GCONV_EMPTY_INPUT)
&& (assert (result > 0),
status is __GCONV_EMPTY_INPUT, but nothing is written to the output buffer
(and it's not incremented).
I _think_ this is because of the handling of the buffered character in
state->__count. After the iconv call above data.__state->__count is
720, which is 90 << 3, which is the value of the "Z" character. So it's
buffered, but it doesn't seem to be emitted to outbuf when the input
comes to an end.
Patch sent for review: http://sourceware.org/ml/libc-alpha/2012-03/msg00123.html
Fixed in git head with commit e64d2de526d8cfa2908e08892a534316a0bddf5f
A new commit is available to fix a bug in the previous commit: 39c59c35723120c32dc42dde4115bba92305179f
As discussed on libc-alpha (thread starts here
http://sourceware.org/ml/libc-alpha/2012-05/msg00736.html), this patch causes a regression, we cannot really support vi_VN.tcvn in glibc and will instead remove it from the list of supported languages.
Thus, I'm marking this bug as wontfix.