|
Message-ID: <4620016.0WQXIW03uk@nimes> Date: Mon, 20 Mar 2023 00:48:59 +0100 From: Bruno Haible <bruno@...sp.org> To: musl@...ts.openwall.com Subject: swprintf: count returned by %n is wrong after conversion error Hi, On musl-1.2.3 I see this violation of the POSIX specification of swprintf [1]: ==================================== foo1.c ==================================== #include <stdio.h> #include <wchar.h> int main () { static const wchar_t input[] = { (wchar_t) 1702057263, 114, 0 }; wchar_t buf[12] = { 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF }; int count = -1; int ret = swprintf (buf, 12, L"%ls%n", input, &count); printf ("ret = %d, count = %d, buf[0] = 0x%x, buf[1] = 0x%x, buf[2] = 0x%x\n", ret, count, (unsigned int) buf[0], (unsigned int) buf[1], (unsigned int) buf[2]); return 0; } /* glibc: ret = 2, count = 2, buf[0] = 0x6573552f, buf[1] = 0x72, buf[2] = 0x0 musl libc: ret = -1, count = 2, buf[0] = 0x0, buf[1] = 0xdeadbeef, buf[2] = 0xdeadbeef FreeBSD 13: ret = -1, count = -1, buf[0] = 0x0, buf[1] = 0xdeadbeef, buf[2] = 0xdeadbeef Solaris OI: ret = 2, count = 2, buf[0] = 0x6573552f, buf[1] = 0x72, buf[2] = 0x0 */ ================================================================================ $ gcc -Wall foo1.c $ ./a.out ret = -1, count = 2, buf[0] = 0x0, buf[1] = 0xdeadbeef, buf[2] = 0xdeadbeef The POSIX specification says: "The application shall ensure that the argument is a pointer to an integer into which is written the number of wide characters written to the output so far by this call to one of the fwprintf() functions." From the values of buf[0], buf[1], buf[2] it can be seen that the number of wide characters written after the %ls directive is 0, not 2. Therefore the value of count should be 0 or — if the processing of the format string stops right after the %ls directive, like it does on FreeBSD 13 — -1. It is OK for the %ls directive to fail, because of the invalid wide characters in the input[] arrary. What is not OK is for the %n directive to report 2 written wide characters, when in fact 0 wide characters have been written. For comparison, in snprintf, this case is handled correctly: ==================================== foo2.c ==================================== #include <stdio.h> #include <string.h> #include <wchar.h> int main () { static const wchar_t input[] = { (wchar_t) 1702057263, 114, 0 }; char buf[12] = { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD }; int count = -1; int ret = snprintf (buf, 12, "%ls%n", input, &count); printf ("ret = %d, count = %d, buf[0] = 0x%x, buf[1] = 0x%x, buf[2] = 0x%x\n", ret, count, (unsigned char) buf[0], (unsigned char) buf[1], (unsigned char) buf[2]); return 0; } /* glibc: ret = -1, count = -1, buf[0] = 0x0, buf[1] = 0xdd, buf[2] = 0xdd musl libc: ret = -1, count = -1, buf[0] = 0x0, buf[1] = 0xdd, buf[2] = 0xdd FreeBSD 13: ret = -1, count = -1, buf[0] = 0x0, buf[1] = 0xdd, buf[2] = 0xdd Solaris OI: ret = -1, count = -1, buf[0] = 0x0, buf[1] = 0xdd, buf[2] = 0xdd */ ================================================================================ $ gcc -Wall foo2.c $ ./a.out ret = -1, count = -1, buf[0] = 0x0, buf[1] = 0xdd, buf[2] = 0xdd Here, count remains unchanged, = -1. Bruno [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/swprintf.html
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.