This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] stdio/vfprintf.c: Don't drop out on invalid chars in format string


On 09/01/10 06:04 AM, Corinna Vinschen wrote:
Hi,

assume the following test application:

   #include<stdio.h>
   #include<string.h>
   #include<locale.h>

   int
   main ()
   {
     char buf[32];
     int ret;

     setlocale (LC_ALL, "en_US.UTF-8");
     memset (buf, 0, sizeof buf);
     ret = sprintf (buf, "\333%s", "ABCD");
     printf ("(%d) %02x %02x %02x %02x %02x\n",
	    ret, buf[0], buf[1], buf[2], buf[3], buf[4]);
     return 0;
   }

It contains a character in the format string "\333", which is invalid
in the current charset (UTF-8).  Running this application on Linux or
Solaris results in the following output:

(5) ffffffdb 41 42 43 44

Running this under newlib/Cygwin, the result is:

(0) 0 0 0 0 0

In newlib, the loop looking for '%' in the format string converts the
format string chars into wide chars, and then compares the character
with a '%'.  The problem is that the vfprintf function simply exits as
soon as an invalid char is found in the format string and returns the
number of characters printed so far.  This is not defined in POSIX.
Either printf is supposed to go ahead, or it is allowed to exit with
a return value of -1 and errno set to EILSEQ.

For compatiblity with Linux and Solaris, I'd like to opt for just going
ahaead and copy the invalid byte in the format string unchanged to the
output.  The patch below will do that.

Ok to apply?


Yes, go ahead.


-- Jeff J.


Thanks, Corinna


* libc/stdio/vfprintf.c (_VFPRINTF_R): Just wave bytes invalid in the current charset through.


Index: libc/stdio/vfprintf.c =================================================================== RCS file: /cvs/src/src/newlib/libc/stdio/vfprintf.c,v retrieving revision 1.76 diff -u -p -r1.76 vfprintf.c --- libc/stdio/vfprintf.c 18 Nov 2009 09:49:56 -0000 1.76 +++ libc/stdio/vfprintf.c 9 Jan 2010 11:03:39 -0000 @@ -724,8 +724,13 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap) cp = fmt; #ifdef _MB_CAPABLE while ((n = __mbtowc (data,&wc, fmt, MB_CUR_MAX, - __locale_charset (),&state))> 0) { - if (wc == '%') + __locale_charset (),&state)) != 0) { + if (n< 0) { + /* Wave invalid chars through. */ + memset (&state, 0, sizeof state); + n = 1; + } + else if (wc == '%') break; fmt += n; }




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]