mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] swprintf: count returned by %n is wrong after conversion error
@ 2023-03-19 23:48 Bruno Haible
  2023-03-20 12:15 ` Rich Felker
  0 siblings, 1 reply; 5+ messages in thread
From: Bruno Haible @ 2023-03-19 23:48 UTC (permalink / raw)
  To: musl

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




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-03-20 21:19 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-19 23:48 [musl] swprintf: count returned by %n is wrong after conversion error Bruno Haible
2023-03-20 12:15 ` Rich Felker
2023-03-20 18:08   ` Rich Felker
2023-03-20 18:22     ` Bruno Haible
2023-03-20 21:19       ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).