Date: Mon, 26 Jun 2023 07:34:43 +0000 From: bugzilla-noreply@freebsd.org To: standards@FreeBSD.org Subject: [Bug 272218] mbsinit returns true for a state that is not in the initial state Message-ID: <bug-272218-99@https.bugs.freebsd.org/bugzilla/>
next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D272218 Bug ID: 272218 Summary: mbsinit returns true for a state that is not in the initial state Product: Base System Version: 13.2-RELEASE Hardware: Any OS: Any Status: New Severity: Affects Some People Priority: --- Component: standards Assignee: standards@FreeBSD.org Reporter: bruno@clisp.org Attachment #243004 text/plain mime type: Created attachment 243004 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=3D243004&action= =3Dedit test case foo.c The following program makes 3 calls to the mbrtoc16 function and each time prints the results, including whether the mbstate_t in then in the initial state or not. Then it makes a second round, clearing the mbstate_t after the first call. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D foo.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D #include <stdio.h> #include <string.h> #include <uchar.h> #include <wchar.h> int main () { if (setlocale (LC_ALL, "en_US.UTF-8") =3D=3D NULL) return 1; for (int round =3D 1; round <=3D 2; round++) { printf ("=3D=3D=3D Round %d =3D=3D=3D\n", round); mbstate_t state =3D { 0 }; char input[4] =3D { (char) 0xF0, (char) 0x9F, (char) 0x99, (char) 0x82 = }; /* U+1F642 */ char16_t wc =3D (char16_t) 0xDEADBEEF; int ret =3D mbrtoc16 (&wc, input, 4, &state); printf ("ret =3D %d, wc =3D 0x%04X, back_to_initial=3D%d\n", ret, (unsi= gned int) wc, mbsinit(&state) !=3D 0); if (round =3D=3D 2) memset (&state, '\0', sizeof(state)); if (ret =3D=3D 4) { wc =3D (char16_t) 0xDEADBEEF; ret =3D mbrtoc16 (&wc, input+4, 0, &state); printf ("ret =3D %d, wc =3D 0x%04X, back_to_initial=3D%d\n", ret, (un= signed int) wc, mbsinit(&state) !=3D 0); if (ret =3D=3D -2 || ret =3D=3D -3) { wc =3D (char16_t) 0xDEADBEEF; ret =3D mbrtoc16 (&wc, "", 0, &state); printf ("ret =3D %d, wc =3D 0x%04X, back_to_initial=3D%d\n", ret, (= unsigned int) wc, mbsinit(&state) !=3D 0); } } } return 0; } /* Expected output (seen on glibc, musl libc): =3D=3D=3D Round 1 =3D=3D=3D ret =3D 4, wc =3D 0xD83D, back_to_initial=3D0 ret =3D -3, wc =3D 0xDE42, back_to_initial=3D1 ret =3D -2, wc =3D 0xBEEF, back_to_initial=3D1 =3D=3D=3D Round 2 =3D=3D=3D ret =3D 4, wc =3D 0xD83D, back_to_initial=3D0 ret =3D -2, wc =3D 0xBEEF, back_to_initial=3D1 ret =3D -2, wc =3D 0xBEEF, back_to_initial=3D1 */ =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D $ cc -Wall foo.c $ ./a.out =3D=3D=3D Round 1 =3D=3D=3D ret =3D 4, wc =3D 0xD83D, back_to_initial=3D1 ret =3D -3, wc =3D 0xDE42, back_to_initial=3D1 ret =3D -2, wc =3D 0xBEEF, back_to_initial=3D1 =3D=3D=3D Round 2 =3D=3D=3D ret =3D 4, wc =3D 0xD83D, back_to_initial=3D1 ret =3D -2, wc =3D 0xBEEF, back_to_initial=3D1 ret =3D -2, wc =3D 0xBEEF, back_to_initial=3D1 Since, after the first call, mbsinit() reports that the mbstate_t is in the initial state, it should make no difference if the program clears it (=3D f= orces it into the initial state) or not. But in FreeBSD 13.2, it makes a differen= ce: The output of round 2 is different from the output of round 1. This proves = that the mbstate_t was not in the initial state. That is, in the first line, mbsinit() should have returned zero instead of non-zero. Reference: https://pubs.opengroup.org/onlinepubs/9699919799/functions/mbsinit.html --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-272218-99>