Bulletproof the debugger.

Michael Stefaniuc mstefani at redhat.de
Tue Dec 25 18:09:06 CST 2001


On Tue, Dec 25, 2001 at 01:38:26PM -0800, Francois Gouget wrote:
> On Fri, 21 Dec 2001, Michael Stefaniuc wrote:
> 
> > On Fri, Dec 21, 2001 at 01:52:12PM -0800, Medland, Bill wrote:
> > > Bill Medland (medbi01 at accpac.com)
> > > Don't ask me why but on my setup vsnprintf returned a value greater than
> > This is the new and correct behavior according to the C99 standard. All
> > snprintf function should return in error case the number of characters
> > that would have been written to the buffer if the size of buffer would
> > have been big enough.
> > This change while usefull will brake a lot of things. IMO the glibc is
> > still using the old behavior.
I was wrong, it's using the C99 behaviour (at least on Red Hat Linux 7.x)

>    By the way did someone do a systematic check for this problem?
>    Might be worth it...
I did a short check with
camus:~/work/wine$ grep -r -I -C snprintf ./ | less
and this is what I found:
- most of the time the return value of *snprintf isn't checked
- if the return value is checked it's mostly checked for C89 and C99
  style
- the attached patch should fix all the remaining cases.

Changelog:
   Michael Stefaniuc <mstefani at redhat.com>
   check the return value of *snprintf for C99 style

bye
	michael
-- 
Michael Stefaniuc               Tel.: +49-711-96437-199
System Administration           Fax.: +49-711-96437-111
Red Hat GmbH                    Email: mstefani at redhat.de
Hauptstaetterstr. 58            http://www.redhat.de/
D-70178 Stuttgart
-------------- next part --------------
Index: dlls/kernel/format_msg.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/format_msg.c,v
retrieving revision 1.19
diff -u -r1.19 format_msg.c
--- dlls/kernel/format_msg.c	2001/10/10 02:51:24	1.19
+++ dlls/kernel/format_msg.c	2001/12/25 21:52:51
@@ -265,6 +265,7 @@
                             strcpy( fmtstr, "%s" );
                         }
                         if (args) {
+			    int ret;
                             int sz;
                             LPSTR b;
 
@@ -282,7 +283,7 @@
                                 b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 100);
                                 /* CMF - This makes a BIG assumption about va_list */
                                 TRACE("A BIG assumption\n");
-                                while (vsnprintf(b, sz, fmtstr, (va_list) argliststart) < 0) {
+                                while ((ret = vsnprintf(b, sz, fmtstr, (va_list) argliststart) < 0) || (ret >= sz)) {
                                     b = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, b, sz += 100);
                                 }
                             }
Index: dlls/user/lstr.c
===================================================================
RCS file: /home/wine/wine/dlls/user/lstr.c,v
retrieving revision 1.18
diff -u -r1.18 lstr.c
--- dlls/user/lstr.c	2001/10/17 17:50:02	1.18
+++ dlls/user/lstr.c	2001/12/25 21:52:52
@@ -683,13 +683,14 @@
                         strcpy( fmtstr, "%s" );
                     }
 		    if (args) {
+			int	ret;
 		        int	sz;
 			LPSTR	b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 100);
 			
 			argliststart=args+insertnr-1;
 		       
 			/* CMF - This makes a BIG assumption about va_list */
-			while (vsnprintf(b, sz, fmtstr, (va_list) argliststart) < 0) {
+			while ((ret = vsnprintf(b, sz, fmtstr, (va_list) argliststart) < 0) || (ret >= sz)) {
 			    b = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, b, sz += 100);
 			}
 			for (x=b; *x; x++) ADD_TO_T(*x);
Index: programs/wineconsole/wineconsole.c
===================================================================
RCS file: /home/wine/wine/programs/wineconsole/wineconsole.c,v
retrieving revision 1.4
diff -u -r1.4 wineconsole.c
--- programs/wineconsole/wineconsole.c	2001/12/04 20:46:54	1.4
+++ programs/wineconsole/wineconsole.c	2001/12/25 21:52:58
@@ -22,7 +22,7 @@
     len = vsnprintf(buf, sizeof(buf), format, valist);
     va_end(valist);
  
-    if (len <= -1) 
+    if ((len <= -1) || (len >= sizeof(buf)))
     {
         len = sizeof(buf) - 1;
         buf[len] = 0;
Index: win32/console.c
===================================================================
RCS file: /home/wine/wine/win32/console.c,v
retrieving revision 1.84
diff -u -r1.84 console.c
--- win32/console.c	2001/12/21 20:29:10	1.84
+++ win32/console.c	2001/12/25 21:58:06
@@ -62,6 +62,7 @@
 static	BOOL	start_console_renderer(void)
 {
     char		buffer[256];
+    int			ret;
     STARTUPINFOA	si;
     PROCESS_INFORMATION	pi;
     HANDLE		hEvent = 0;
@@ -85,14 +86,16 @@
     /* first try environment variable */
     if ((p = getenv("WINECONSOLE")) != NULL)
     {
-	if (snprintf(buffer, sizeof(buffer), "%s -- --use-event=%d", p, hEvent) > 0 &&
+	ret = snprintf(buffer, sizeof(buffer), "%s -- --use-event=%d", p, hEvent);
+	if (((ret < 0) || (ret >= sizeof(buffer))) &&
 	    CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &si, &pi))
 	    goto succeed;
 	ERR("Couldn't launch Wine console from WINECONSOLE env var... trying default access\n");
     }
 
     /* then the regular installation dir */
-    if (snprintf(buffer, sizeof(buffer), "%s -- --use-event=%d", BINDIR "/wineconsole", hEvent) > 0 &&
+    ret = snprintf(buffer, sizeof(buffer), "%s -- --use-event=%d", BINDIR "/wineconsole", hEvent);
+    if (((ret < 0) || (ret >= sizeof(buffer))) &&
 	CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &si, &pi))
 	goto succeed;
 


More information about the wine-patches mailing list