Fixed FormatMessage[A|16] against some buffer overflow cases.

This commit is contained in:
Eric Pouech 2000-07-10 13:06:25 +00:00 committed by Alexandre Julliard
parent c8924d3e59
commit 254cd6b6de

View File

@ -486,8 +486,8 @@ DWORD WINAPI FormatMessage16(
TRACE("(0x%lx,%lx,%d,0x%x,%p,%d,%p)\n", TRACE("(0x%lx,%lx,%d,0x%x,%p,%d,%p)\n",
dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args); dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
if (width) if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
FIXME("line wrapping not supported.\n"); FIXME("line wrapping (%lu) not supported.\n", width);
from = NULL; from = NULL;
if (dwFlags & FORMAT_MESSAGE_FROM_STRING) if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
from = HEAP_strdupA( GetProcessHeap(), 0, PTR_SEG_TO_LIN(lpSource)); from = HEAP_strdupA( GetProcessHeap(), 0, PTR_SEG_TO_LIN(lpSource));
@ -523,7 +523,7 @@ DWORD WINAPI FormatMessage16(
while (*f && !eos) { while (*f && !eos) {
if (*f=='%') { if (*f=='%') {
int insertnr; int insertnr;
char *fmtstr,*sprintfbuf,*x,*lastf; char *fmtstr,*x,*lastf;
DWORD *argliststart; DWORD *argliststart;
fmtstr = NULL; fmtstr = NULL;
@ -557,7 +557,7 @@ DWORD WINAPI FormatMessage16(
sprintf(fmtstr,"%%%s",f); sprintf(fmtstr,"%%%s",f);
f=x+1; f=x+1;
} else { } else {
fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)); fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
sprintf(fmtstr,"%%%s",f); sprintf(fmtstr,"%%%s",f);
f+=strlen(f); /*at \0*/ f+=strlen(f); /*at \0*/
} }
@ -567,20 +567,16 @@ DWORD WINAPI FormatMessage16(
else else
fmtstr=HEAP_strdupA(GetProcessHeap(),0,"%s"); fmtstr=HEAP_strdupA(GetProcessHeap(),0,"%s");
if (args) { if (args) {
argliststart=args+insertnr-1; int sz;
if (fmtstr[strlen(fmtstr)-1]=='s') LPSTR b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 100);
sprintfbuf=HeapAlloc(GetProcessHeap(),0,
strlen(PTR_SEG_TO_LIN(argliststart[0]))+1); argliststart=args+insertnr-1;
else
sprintfbuf=HeapAlloc(GetProcessHeap(),0,100);
/* CMF - This makes a BIG assumption about va_list */ /* CMF - This makes a BIG assumption about va_list */
wvsprintf16(sprintfbuf, fmtstr, (va_list) argliststart); while (wvsnprintf16(b, sz, fmtstr, (va_list) argliststart) < 0) {
x=sprintfbuf; b = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, b, sz += 100);
while (*x) {
ADD_TO_T(*x++);
} }
HeapFree(GetProcessHeap(),0,sprintfbuf); for (x=b; *x; x++) ADD_TO_T(*x);
} else { } else {
/* NULL args - copy formatstr /* NULL args - copy formatstr
* (probably wrong) * (probably wrong)
@ -602,10 +598,12 @@ DWORD WINAPI FormatMessage16(
} }
} else { /* '\n' or '\r' gets mapped to "\r\n" */ } else { /* '\n' or '\r' gets mapped to "\r\n" */
if(*f == '\n' || *f == '\r') { if(*f == '\n' || *f == '\r') {
ADD_TO_T('\r'); if (width == 0) {
ADD_TO_T('\n'); ADD_TO_T('\r');
if(*f++ == '\r' && *f == '\n') ADD_TO_T('\n');
f++; if(*f++ == '\r' && *f == '\n')
f++;
}
} else { } else {
ADD_TO_T(*f++); ADD_TO_T(*f++);
} }
@ -659,8 +657,8 @@ DWORD WINAPI FormatMessageA(
TRACE("(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n", TRACE("(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args); dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
if (width) if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
FIXME("line wrapping not supported.\n"); FIXME("line wrapping (%lu) not supported.\n", width);
from = NULL; from = NULL;
if (dwFlags & FORMAT_MESSAGE_FROM_STRING) if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
from = HEAP_strdupA( GetProcessHeap(), 0, (LPSTR)lpSource); from = HEAP_strdupA( GetProcessHeap(), 0, (LPSTR)lpSource);
@ -695,7 +693,7 @@ DWORD WINAPI FormatMessageA(
while (*f && !eos) { while (*f && !eos) {
if (*f=='%') { if (*f=='%') {
int insertnr; int insertnr;
char *fmtstr,*sprintfbuf,*x,*lastf; char *fmtstr,*x,*lastf;
DWORD *argliststart; DWORD *argliststart;
fmtstr = NULL; fmtstr = NULL;
@ -729,7 +727,7 @@ DWORD WINAPI FormatMessageA(
sprintf(fmtstr,"%%%s",f); sprintf(fmtstr,"%%%s",f);
f=x+1; f=x+1;
} else { } else {
fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)); fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
sprintf(fmtstr,"%%%s",f); sprintf(fmtstr,"%%%s",f);
f+=strlen(f); /*at \0*/ f+=strlen(f); /*at \0*/
} }
@ -739,23 +737,21 @@ DWORD WINAPI FormatMessageA(
else else
fmtstr=HEAP_strdupA(GetProcessHeap(),0,"%s"); fmtstr=HEAP_strdupA(GetProcessHeap(),0,"%s");
if (args) { if (args) {
if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY) int sz;
argliststart=args+insertnr-1; LPSTR b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 100);
else
argliststart=(*(DWORD**)args)+insertnr-1;
if (fmtstr[strlen(fmtstr)-1]=='s' && argliststart[0]) if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
sprintfbuf=HeapAlloc(GetProcessHeap(),0,strlen((LPSTR)argliststart[0])+1); argliststart=args+insertnr-1;
else else
sprintfbuf=HeapAlloc(GetProcessHeap(),0,100); argliststart=(*(DWORD**)args)+insertnr-1;
/* CMF - This makes a BIG assumption about va_list */ /* CMF - This makes a BIG assumption about va_list */
wvsprintfA(sprintfbuf, fmtstr, (va_list) argliststart); while (wvsnprintfA(b, sz, fmtstr, (va_list) argliststart) < 0) {
x=sprintfbuf; b = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, b, sz += 100);
while (*x) {
ADD_TO_T(*x++);
} }
HeapFree(GetProcessHeap(),0,sprintfbuf); for (x=b; *x; x++) ADD_TO_T(*x);
HeapFree(GetProcessHeap(),0,b);
} else { } else {
/* NULL args - copy formatstr /* NULL args - copy formatstr
* (probably wrong) * (probably wrong)
@ -781,10 +777,12 @@ DWORD WINAPI FormatMessageA(
} }
} else { /* '\n' or '\r' gets mapped to "\r\n" */ } else { /* '\n' or '\r' gets mapped to "\r\n" */
if(*f == '\n' || *f == '\r') { if(*f == '\n' || *f == '\r') {
ADD_TO_T('\r'); if (width == 0) {
ADD_TO_T('\n'); ADD_TO_T('\r');
if(*f++ == '\r' && *f == '\n') ADD_TO_T('\n');
f++; if(*f++ == '\r' && *f == '\n')
f++;
}
} else { } else {
ADD_TO_T(*f++); ADD_TO_T(*f++);
} }
@ -796,14 +794,13 @@ DWORD WINAPI FormatMessageA(
if (nSize && talloced<nSize) { if (nSize && talloced<nSize) {
target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize); target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
} }
TRACE("-- %s\n",debugstr_a(target)); TRACE("-- %s\n",debugstr_a(target));
if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) { if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
/* nSize is the MINIMUM size */ *((LPVOID*)lpBuffer) = (LPVOID)LocalAlloc(GMEM_ZEROINIT,max(nSize, talloced));
*((LPVOID*)lpBuffer) = (LPVOID)LocalAlloc(GMEM_ZEROINIT,talloced);
memcpy(*(LPSTR*)lpBuffer,target,talloced); memcpy(*(LPSTR*)lpBuffer,target,talloced);
} else { } else {
lstrcpynA(lpBuffer,target,nSize); lstrcpynA(lpBuffer,target,nSize);
} }
HeapFree(GetProcessHeap(),0,target); HeapFree(GetProcessHeap(),0,target);
if (from) HeapFree(GetProcessHeap(),0,from); if (from) HeapFree(GetProcessHeap(),0,from);
return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ? return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
@ -838,7 +835,7 @@ DWORD WINAPI FormatMessageW(
TRACE("(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n", TRACE("(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args); dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
if (width) if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
FIXME("line wrapping not supported.\n"); FIXME("line wrapping not supported.\n");
from = NULL; from = NULL;
if (dwFlags & FORMAT_MESSAGE_FROM_STRING) if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
@ -963,10 +960,12 @@ DWORD WINAPI FormatMessageW(
} }
} else { /* '\n' or '\r' gets mapped to "\r\n" */ } else { /* '\n' or '\r' gets mapped to "\r\n" */
if(*f == '\n' || *f == '\r') { if(*f == '\n' || *f == '\r') {
ADD_TO_T('\r'); if (width == 0) {
ADD_TO_T('\n'); ADD_TO_T('\r');
if(*f++ == '\r' && *f == '\n') ADD_TO_T('\n');
f++; if(*f++ == '\r' && *f == '\n')
f++;
}
} else { } else {
ADD_TO_T(*f++); ADD_TO_T(*f++);
} }