https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=272218
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: [email protected]
Reporter: [email protected]
Attachment #243004 text/plain
mime type:
Created attachment 243004
--> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=243004&action=edit
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.
================================= foo.c =================================
#include <stdio.h>
#include <string.h>
#include <uchar.h>
#include <wchar.h>
int main ()
{
if (setlocale (LC_ALL, "en_US.UTF-8") == NULL)
return 1;
for (int round = 1; round <= 2; round++) {
printf ("=== Round %d ===\n", round);
mbstate_t state = { 0 };
char input[4] = { (char) 0xF0, (char) 0x9F, (char) 0x99, (char) 0x82 }; /*
U+1F642 */
char16_t wc = (char16_t) 0xDEADBEEF;
int ret = mbrtoc16 (&wc, input, 4, &state);
printf ("ret = %d, wc = 0x%04X, back_to_initial=%d\n", ret, (unsigned int)
wc, mbsinit(&state) != 0);
if (round == 2)
memset (&state, '\0', sizeof(state));
if (ret == 4) {
wc = (char16_t) 0xDEADBEEF;
ret = mbrtoc16 (&wc, input+4, 0, &state);
printf ("ret = %d, wc = 0x%04X, back_to_initial=%d\n", ret, (unsigned
int) wc, mbsinit(&state) != 0);
if (ret == -2 || ret == -3) {
wc = (char16_t) 0xDEADBEEF;
ret = mbrtoc16 (&wc, "", 0, &state);
printf ("ret = %d, wc = 0x%04X, back_to_initial=%d\n", ret, (unsigned
int) wc, mbsinit(&state) != 0);
}
}
}
return 0;
}
/* Expected output (seen on glibc, musl libc):
=== Round 1 ===
ret = 4, wc = 0xD83D, back_to_initial=0
ret = -3, wc = 0xDE42, back_to_initial=1
ret = -2, wc = 0xBEEF, back_to_initial=1
=== Round 2 ===
ret = 4, wc = 0xD83D, back_to_initial=0
ret = -2, wc = 0xBEEF, back_to_initial=1
ret = -2, wc = 0xBEEF, back_to_initial=1
*/
=========================================================================
$ cc -Wall foo.c
$ ./a.out
=== Round 1 ===
ret = 4, wc = 0xD83D, back_to_initial=1
ret = -3, wc = 0xDE42, back_to_initial=1
ret = -2, wc = 0xBEEF, back_to_initial=1
=== Round 2 ===
ret = 4, wc = 0xD83D, back_to_initial=1
ret = -2, wc = 0xBEEF, back_to_initial=1
ret = -2, wc = 0xBEEF, back_to_initial=1
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 (= forces
it into the initial state) or not. But in FreeBSD 13.2, it makes a difference:
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
--
You are receiving this mail because:
You are the assignee for the bug.
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.