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: [BUG] wprintf(L"%s", str) expects str to be wide


On Jan 11 16:37, Corinna Vinschen wrote:
> [Can we please not use top-posting here?  Thanks]
> 
> On Jan 11 10:20, Craig Howland wrote:
> > On 01/11/2013 10:07 AM, Corinna Vinschen wrote:
> > >On Jan 11 09:52, Craig Howland wrote:
> > >>Corinna:
> > >>     It appears, taking a quick glance at the source, that the string
> > >>is only treated as regular characters if _MB_CAPABLE is
> > >>defined--otherwise it falls into a wide-character-only case.  This
> > >>could perhaps explain the differing results.
> > >>                 Craig
> > >The _MB_CAPABLE code only handles the case which converts wide chars
> > >into multibyte chars.  The default code right after the #endif handles
> > >the incoming string as plain byte string.
> > >
> > Corinna:
> >      Are we looking at the same place?  Lines 1200-1217 of
> > libc/stdio/vfwprintf.c version 1.10 are what I looked at.  I only
> > see wide functions there.  I'll quote from line 1199 to get the
> > #endif:
> > [...]
> > Craig
> 
> No, we're not looking at the same code.  I was accidentally looking
> into vfprintf.c.  Sorry.
> 
> Looking into the right spot now, I don't see how this could be fixed
> easily.  _MB_CAPABLE is required to define the conversion functions.
> As a fallback we could assume ASCII (or rather ISO-8859-1) and create an
> array of UTF wide chars by allocating a temporary wide char array and
> fill it with the single byte chars 1:1, but other than that I don't see
> a chance.

Here's a matching patch.  I tested it under Cygwin by disabling
_MB_CAPABLE when building vfwprintf.c.  Please review.  If that's ok,
I'll check it in.


Thanks,
Corinna


	* vfwprintf.c (_VFWPRINTF_R): Add code to correctly handle 's'
	format specifier on not _MB_CAPABLE targets.  Fix a formatting
	glitch in _MB_CAPABLE enabled code.  Add a missing 'L' specifier.


Index: libc/stdio/vfwprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vfwprintf.c,v
retrieving revision 1.10
diff -u -p -r1.10 vfwprintf.c
--- libc/stdio/vfwprintf.c	10 Aug 2012 09:37:32 -0000	1.10
+++ libc/stdio/vfwprintf.c	11 Jan 2013 16:10:34 -0000
@@ -1171,11 +1171,11 @@ string:
 					insize = strlen(arg);
 				if (insize >= BUF) {
 				    if ((malloc_buf = (wchar_t *) _malloc_r (data, (insize + 1) * sizeof (wchar_t)))
-								== NULL) {
-							fp->_flags |= __SERR;
-							goto error;
-						}
-						cp = malloc_buf;
+					== NULL) {
+						fp->_flags |= __SERR;
+						goto error;
+					}
+					cp = malloc_buf;
 				} else
 					cp = buf;
 				memset ((_PTR)&ps, '\0', sizeof (mbstate_t));
@@ -1195,9 +1195,31 @@ string:
 				*p = L'\0';
 				size = p - cp;
 			}
-			else
+#else
+			if (ch != L'S' && !(flags & LONGINT)) {
+				char *arg = (char *) cp;
+				size_t insize = 0;
+
+				if (prec >= 0) {
+					char *p = memchr (arg, '\0', prec);
+					insize = p ? p - arg : prec;
+				} else
+					insize = strlen (arg);
+				if (insize >= BUF) {
+				    if ((malloc_buf = (wchar_t *) _malloc_r (data, (insize + 1) * sizeof (wchar_t)))
+					== NULL) {
+						fp->_flags |= __SERR;
+						goto error;
+					}
+					cp = malloc_buf;
+				} else
+					cp = buf;
+				for (size = 0; size < insize; ++size)
+					cp[size] = arg[size];
+				cp[size] = L'\0';
+			}
 #endif /* _MB_CAPABLE */
-			if (prec >= 0) {
+			else if (prec >= 0) {
 				/*
 				 * can't use wcslen; can only look for the
 				 * NUL in the first `prec' characters, and
@@ -1222,7 +1244,7 @@ string:
 		case L'X':
 			xdigs = L"0123456789ABCDEF";
 			goto hex;
-		case 'x':
+		case L'x':
 			xdigs = L"0123456789abcdef";
 hex:			_uquad = UARG ();
 			base = HEX;


-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat


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