[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#824429: libc6: In certain locale combinations mbsrtowcs cannot recover from EILSEQ



Package: libc6
Version: 2.22-7
Severity: normal

Dear Maintainer,

It might be questionable whether this is a bug in glibc at all. But at
least it's surprising behaviour.

The reproducer below calls mbstowcs two times, first time with
an illegal UTF-8 sequence, second time a correct one.

Now if the caller's environment is set to something UTF-8-ish like
"en_US.UTF-8" or "de_DE.UTF-8", also the second and any further
mbsrtowcs invocation fail with EILSEQ. Note setting LC_CTYPE to an
empty string is also required to make this happen.

Also, I didn't make this up, this happened to me in real-life code.
That application needs to be restarted to be usable again. There are
several ways to work around it, still in my opinion it should be
addressed at the libc side.

Or in short:

With LANG set to "C", both tests pass; while set to "en_US.UTF-8" the
second fails.

FWIW, on a 10.3-RELEASE FreeBSD the first fails for "C" (i.e. the
character sequence is accepted) while both pass for "en_US.UTF-8".

    Christoph


====================================================================

#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <wchar.h>

int main (int argc, char **argv) {
    char buffer1[] = "\xf8\xa7";
    char buffer2[] = "a";
    const char *ptr;
    wchar_t wcur;

    setlocale(LC_CTYPE, "");

    ptr = &buffer1[0];
    if (mbsrtowcs (&wcur, &ptr, 1, NULL) == -1) {
        if (errno == EILSEQ) {
            perror ("ok: mbsrtowcs failed as expected");
        } else {
            perror ("not ok: mbsrtowcs failed");
        }
    } else {
        printf ("not ok: mbsrtowcs passed on illegal sequence\n");
    }

    ptr = &buffer2[0];
    if (mbsrtowcs (&wcur, &ptr, 1, NULL) == -1) {
        perror ("not ok: mbsrtowcs failed");
    } else {
        printf ("ok: mbsrtowcs pass\n");
    }
}

====================================================================

-- System Information:
Debian Release: stretch/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 4.4.9 (SMP w/4 CPU cores)
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)
Shell: /bin/sh linked to /bin/dash
Init: unable to detect

Versions of packages libc6 depends on:
ii  libgcc1  1:6.1.1-1

libc6 recommends no packages.

Versions of packages libc6 suggests:
ii  debconf [debconf-2.0]  1.5.59
pn  glibc-doc              <none>
ii  libc-l10n              2.22-7
ii  locales                2.22-7

-- debconf information excluded


Reply to: