> Failures on Cygwin 1.7.2
> ------------------------
> 
> test-mbsnrtowcs.c:181: assertion failed
> ./test-mbsnrtowcs2.sh: line 15:  5708 Aborted                 (core dumped) 
> LC_ALL=$LOCALE_FR_UTF8 ./test-mbsnrtowcs${EXEEXT} 2
> FAIL: test-mbsnrtowcs2.sh
> 
> test-mbsrtowcs.c:181: assertion failed
> ./test-mbsrtowcs2.sh: line 15:  4428 Aborted                 (core dumped) 
> LC_ALL=$LOCALE_FR_UTF8 ./test-mbsrtowcs${EXEEXT} 2
> FAIL: test-mbsrtowcs2.sh

These look like a programming error in the testcase or like a gcc bug.
A simplified test case is attached. It crashes when optimized with -O2
and works fine without optimization:


$ gcc foo.c && ./a.exe
gcc foo.c && ./a.exe
buf = FACE FACE FACE FACE FACE FACE FACE FACE FACE FACE
state = 0000000000000000
buf = FACE FACE FACE FACE FACE FACE FACE FACE FACE FACE
state = 01000000C3000000
buf = FACE FACE FACE FACE FACE FACE FACE FACE FACE FACE
state = 01000000C3000000
temps = 00000000C3000000
buf = 00FC 00DF FACE FACE FACE FACE FACE FACE FACE FACE
state = 00000000C3000000

$ gcc -O2 foo.c && ./a.exe
gcc -O2 foo.c && ./a.exe
buf = FACE FACE FACE FACE FACE FACE FACE FACE FACE FACE
state = 0000000000000000
buf = FACE FACE FACE FACE FACE FACE FACE FACE FACE FACE
state = 01000000C3000000
buf = FACE FACE FACE FACE FACE FACE FACE FACE FACE FACE
state = 01000000C3000000
temps = 00000000C3000000
buf = 00FC 00DF FACE FACE FACE FACE FACE FACE FACE FACE
state = 6100000000D4CD22
foo.c:103: assertion failed
bash: [5936: 1] tcsetattr: Inappropriate ioctl for device
Aborted (core dumped)

The same behaviour also occurs when the test case uses the gnulib replacement
of mbsrtowcs. Therefore I think it's not a bug in Cygwin's mbsrtowcs function.

Can someone please look at the attached test case and see if it does something
obviously wrong?

Bruno



#include <wchar.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ASSERT(expr) \
  do                                                                         \
    {                                                                        \
      if (!(expr))                                                           \
        {                                                                    \
          fprintf (stderr, "%s:%d: assertion failed\n",                      \
                   __FILE__, __LINE__);                                      \
          fflush (stderr);                                                   \
          abort ();                                                          \
        }                                                                    \
    }                                                                        \
  while (0)

#define BUFSIZE 10

static void dumpbuf(wchar_t buf[BUFSIZE])
{
  int i;
  printf ("buf =");
  for (i = 0; i < BUFSIZE; i++)
    printf(" %04X", buf[i]);
  printf ("\n");
  fflush (stdout);
}

static void dumpstate(const char *prefix, mbstate_t *statep)
{
  int i;
  printf ("%s = ", prefix);
  for (i = 0; i < sizeof (mbstate_t); i++)
    printf("%02X", ((unsigned char *)statep)[i]);
  printf ("\n");
  fflush (stdout);
}

int
main (int argc, char *argv[])
{
  int unlimited;
  mbstate_t state;
  wchar_t wc;
  size_t ret;

  if (setlocale (LC_ALL, "fr_FR.UTF-8") == NULL)
    return 1;

  for (unlimited = 0; unlimited < 1; unlimited++)
    {
      wchar_t buf[BUFSIZE];
      const char *src;
      mbstate_t temp_state;

      {
        size_t i;
        for (i = 0; i < BUFSIZE; i++)
          buf[i] = (wchar_t) 0xBADFACE;
      }

      /* Locale encoding is UTF-8.  */
      {
        char input[] = "B\303\274\303\237er";
        memset (&state, '\0', sizeof (mbstate_t));
        dumpbuf(buf); dumpstate("state",&state);

        wc = (wchar_t) 0xBADFACE;
        ret = mbrtowc (&wc, input + 1, 1, &state);
        ASSERT (ret == (size_t)(-2));
        ASSERT (wc == (wchar_t) 0xBADFACE);
        ASSERT (!mbsinit (&state));
        input[1] = '\0';
        dumpbuf(buf); dumpstate("state",&state);

        src = input + 2;
        temp_state = state;
        ret = mbsrtowcs (NULL, &src, unlimited ? BUFSIZE : 2, &temp_state);
        ASSERT (ret == 4);
        ASSERT (src == input + 2);
        ASSERT (!mbsinit (&state));
        dumpbuf(buf); dumpstate("state",&state); dumpstate("temps",&temp_state);

        src = input + 2;
        ret = mbsrtowcs (buf, &src, unlimited ? BUFSIZE : 2, &state);
        ASSERT (ret == (unlimited ? 4 : 2));
        ASSERT (src == (unlimited ? NULL : input + 5));
        ASSERT (wctob (buf[0]) == EOF);
        ASSERT (wctob (buf[1]) == EOF);
        dumpbuf(buf); dumpstate("state",&state);
        if (unlimited)
          {
            ASSERT (buf[2] == 'e');
            ASSERT (buf[3] == 'r');
            ASSERT (buf[4] == 0);
            ASSERT (buf[5] == (wchar_t) 0xBADFACE);
          }
        else
          ASSERT (buf[2] == (wchar_t) 0xBADFACE);
        ASSERT (mbsinit (&state));

      }
    }

  return 0;
}

Reply via email to