mirror of https://github.com/encounter/SDL.git
Fixed potential buffer overflow in SDL_vsnprintf() (thanks, Taylor!).
Fixes Bugzilla #3441. "When using internal SDL_vsnprintf(), and source string length is greater than destination, the final NULL char will be written beyond destination size. Primary issue that is SDL_strlcpy returns length of source string (SDL_PrintString()), not how much is written to destination. The destination ptr is then incremented by this length before the sanity check is done. Destination string is properly terminated, but an extra NULL char will be written beyond destination buffer length. Patch used internally is attached which fixes primary issue with SDL_strlcpy() in SDL_PrintString() and adjusts sanity checks to increment destination ptr safely."
This commit is contained in:
parent
351adf156a
commit
46f44f66f8
|
@ -1315,6 +1315,7 @@ static size_t
|
|||
SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *string)
|
||||
{
|
||||
size_t length = 0;
|
||||
size_t slen;
|
||||
|
||||
if (info && info->width && (size_t)info->width > SDL_strlen(string)) {
|
||||
char fill = info->pad_zeroes ? '0' : ' ';
|
||||
|
@ -1326,7 +1327,8 @@ SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *str
|
|||
}
|
||||
}
|
||||
|
||||
length += SDL_strlcpy(text, string, maxlen);
|
||||
slen = SDL_strlcpy(text, string, maxlen);
|
||||
length += SDL_min(slen, maxlen);
|
||||
|
||||
if (info) {
|
||||
if (info->force_case == SDL_CASE_LOWER) {
|
||||
|
@ -1402,10 +1404,11 @@ SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg)
|
|||
}
|
||||
value = (unsigned long) arg;
|
||||
len = SDL_PrintUnsignedLong(text, left, NULL, value);
|
||||
text += len;
|
||||
if (len >= left) {
|
||||
text += (left > 1) ? left - 1 : 0;
|
||||
left = SDL_min(left, 1);
|
||||
} else {
|
||||
text += len;
|
||||
left -= len;
|
||||
}
|
||||
arg -= value;
|
||||
|
@ -1422,10 +1425,11 @@ SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg)
|
|||
while (info->precision-- > 0) {
|
||||
value = (unsigned long) (arg * mult);
|
||||
len = SDL_PrintUnsignedLong(text, left, NULL, value);
|
||||
text += len;
|
||||
if (len >= left) {
|
||||
text += (left > 1) ? left - 1 : 0;
|
||||
left = SDL_min(left, 1);
|
||||
} else {
|
||||
text += len;
|
||||
left -= len;
|
||||
}
|
||||
arg -= (double) value / mult;
|
||||
|
@ -1458,10 +1462,11 @@ SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg)
|
|||
}
|
||||
}
|
||||
len = (size_t)width;
|
||||
text += len;
|
||||
if (len >= left) {
|
||||
text += (left > 1) ? left - 1 : 0;
|
||||
left = SDL_min(left, 1);
|
||||
} else {
|
||||
text += len;
|
||||
left -= len;
|
||||
}
|
||||
while (len--) {
|
||||
|
@ -1637,10 +1642,11 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt,
|
|||
}
|
||||
++fmt;
|
||||
}
|
||||
text += len;
|
||||
if (len >= left) {
|
||||
text += (left > 1) ? left - 1 : 0;
|
||||
left = SDL_min(left, 1);
|
||||
} else {
|
||||
text += len;
|
||||
left -= len;
|
||||
}
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue