Try to fix buffer overflow detection for Microsoft implementation of vsnprintf()

This commit is contained in:
Stas Degteff 2011-02-22 00:49:01 +00:00
parent e59f2fc9f4
commit 25f0b9c4bc

View File

@ -774,14 +774,21 @@ int gsprintf(TCHAR* buffer, size_t sizeOfBuffer, const TCHAR* __file, int __line
*/ */
# if __VISUAL_C_NOT_LESS(10,00) // defined HAVE__VSTPRINTF // _vsnprintf() exist in VS6 and deprecated in VS2005 # if __VISUAL_C_NOT_LESS(10,00) // defined HAVE__VSTPRINTF // _vsnprintf() exist in VS6 and deprecated in VS2005
ret = _vsnprintf(buffer, sizeof(buffer), format, argptr); char * b1[sizeOfBuffer+1];
if (ret == -1 || ret == sizeof(buffer)) // Microsoft implementation returns -1 when buffer overflow. const size_t endOfBuffer = sizeOfBuffer-1;
ret = _vsnprintf(b1, sizeof(b1), format, argptr);
if (ret == -1 || ret >= sizeOfBuffer) // Microsoft implementation returns -1 when buffer overflow.
{ {
if (sizeOfBuffer>17) strcpy(buffer, " ERROR, see log! "); strncpy(buffer,b1,endOfBuffer);
else if (sizeOfBuffer>7) strcpy(buffer," ERROR "); buffer[endOfBuffer] = '\0'; // Microsoft implementation don't write final '\0' when buffer full.
buffer[sizeOfBuffer-1] = '\0'; // Microsoft implementation don't write final '\0' when buffer full. if (b1[sizeOfBuffer] && strlen(buffer)>=endOfBuffer)
LOG.errmemory(__file, __line); {
LOG.printf("! gsprintf(buffer,%i,%s,...): buffer overflow (need %i bytes).", sizeOfBuffer, format, ret); LOG.printf("! %s", gerrinfo("Memory error", __file, __line));
LOG.printf("! gsprintf(buffer,%i,%s,...): buffer overflow, result in next line:", sizeOfBuffer, format);
LOG.printf("! %s", buffer);
if (sizeOfBuffer>17) memcpy(buffer, " ERROR, see log! ", 17);
else if (sizeOfBuffer>7) memcpy(buffer," ERROR ", 7);
}
} }
else if (ret < 0) else if (ret < 0)
{ {
@ -789,6 +796,11 @@ int gsprintf(TCHAR* buffer, size_t sizeOfBuffer, const TCHAR* __file, int __line
LOG.printf("! gsprintf()(buffer,%i,%s,...): _vsnprintf() error: \"%s\".", sizeOfBuffer, format, strerror(errno)); LOG.printf("! gsprintf()(buffer,%i,%s,...): _vsnprintf() error: \"%s\".", sizeOfBuffer, format, strerror(errno));
TestErrorExit(); TestErrorExit();
} }
else
{
strncpy(buffer,b1,endOfBuffer);
buffer[endOfBuffer] = '\0';
}
# elif defined HAVE_VSNPRINTF // C99 and above # elif defined HAVE_VSNPRINTF // C99 and above
@ -804,7 +816,7 @@ int gsprintf(TCHAR* buffer, size_t sizeOfBuffer, const TCHAR* __file, int __line
if (sizeOfBuffer>17) strcpy(buffer, " ERROR, see log! "); if (sizeOfBuffer>17) strcpy(buffer, " ERROR, see log! ");
else if (sizeOfBuffer>7) strcpy(buffer," ERROR "); else if (sizeOfBuffer>7) strcpy(buffer," ERROR ");
else buffer[sizeOfBuffer-1] = '\0'; else buffer[sizeOfBuffer-1] = '\0';
LOG.errmemory(__file, __line); LOG.printf("! %s", gerrinfo("Memory error", __file, __line));
LOG.printf("! gsprintf(buffer,%i,%s,...): buffer overflow (need %i bytes).", sizeOfBuffer, format, ret); LOG.printf("! gsprintf(buffer,%i,%s,...): buffer overflow (need %i bytes).", sizeOfBuffer, format, ret);
} }