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@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@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@redhat.de Hauptstaetterstr. 58 http://www.redhat.de/ D-70178 Stuttgart
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;