Bug 13691 - Assertion with vi_VN.tcvn locale
Summary: Assertion with vi_VN.tcvn locale
Alias: None
Product: glibc
Classification: Unclassified
Component: localedata (show other bugs)
Version: 2.15
: P2 normal
Target Milestone: ---
Assignee: Tulio Magno Quites Machado Filho
Depends on:
Reported: 2012-02-14 14:57 UTC by Michael Matz
Modified: 2014-06-27 07:18 UTC (History)
4 users (show)

See Also:
Last reconfirmed:
fweimer: security-


Note You need to log in before you can comment on or make changes to this bug.
Description Michael Matz 2012-02-14 14:57:04 UTC
The following program result in an assertion failure in __mbsnrtowcs:

% cat bug.c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <locale.h>
#include <wchar.h>

int main()
  const char * string = "Z";
  size_t len;
  wchar_t ignore[1];
  const char *str2 = string;
  const char *strend = string + 1;
  mbstate_t ps;
  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)
  return 0;

# ./elf/ld.so --library-path . ./a.out
Locale: vi_VN.tcvn
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
wcsmbs/mbsnrtowcs.c :

      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.
Comment 1 Tulio Magno Quites Machado Filho 2012-03-06 19:35:08 UTC
Patch sent for review: http://sourceware.org/ml/libc-alpha/2012-03/msg00123.html
Comment 2 Andreas Jaeger 2012-03-30 08:46:55 UTC
Fixed in git head with commit e64d2de526d8cfa2908e08892a534316a0bddf5f
Comment 3 Tulio Magno Quites Machado Filho 2012-04-03 12:17:29 UTC
A new commit is available to fix a bug in the previous commit: 39c59c35723120c32dc42dde4115bba92305179f
Comment 4 Andreas Jaeger 2012-05-21 07:26:51 UTC
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.