Skip to content

Commit

Permalink
Make SDL error string formatting deal with nasty corner cases.
Browse files Browse the repository at this point in the history
We continued looping while maxlen > 0, but maxlen was unsigned, so an overflow
 would make it a large number instead of negative. Fixed.

Some snprintf() implementations might return a negative value if there isn't
 enough space, and we now check for that.

Don't overrun the SDL error message buffer, if snprintf() returned the number
 of chars it wanted to write instead of the number it did.

snprintf is a portability mess, we should just never use the C runtime for it.

Fixes Bugzilla #2049.
  • Loading branch information
icculus committed Mar 24, 2015
1 parent 54f4725 commit d9f3785
Showing 1 changed file with 27 additions and 9 deletions.
36 changes: 27 additions & 9 deletions src/SDL_error.c
Expand Up @@ -120,7 +120,7 @@ SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
so that it supports internationalization and thread-safe errors.
*/
static char *
SDL_GetErrorMsg(char *errstr, unsigned int maxlen)
SDL_GetErrorMsg(char *errstr, int maxlen)
{
SDL_error *error;

Expand Down Expand Up @@ -163,37 +163,55 @@ SDL_GetErrorMsg(char *errstr, unsigned int maxlen)
len =
SDL_snprintf(msg, maxlen, tmp,
error->args[argi++].value_i);
msg += len;
maxlen -= len;
if (len > 0) {
msg += len;
maxlen -= len;
}
break;

case 'f':
len =
SDL_snprintf(msg, maxlen, tmp,
error->args[argi++].value_f);
msg += len;
maxlen -= len;
if (len > 0) {
msg += len;
maxlen -= len;
}
break;

case 'p':
len =
SDL_snprintf(msg, maxlen, tmp,
error->args[argi++].value_ptr);
msg += len;
maxlen -= len;
if (len > 0) {
msg += len;
maxlen -= len;
}
break;

case 's':
len =
SDL_snprintf(msg, maxlen, tmp,
SDL_LookupString(error->args[argi++].
buf));
msg += len;
maxlen -= len;
if (len > 0) {
msg += len;
maxlen -= len;
}
break;

}
} else {
*msg++ = *fmt++;
maxlen -= 1;
}
}

/* slide back if we've overshot the end of our buffer. */
if (maxlen < 0) {
msg -= (-maxlen) + 1;
}

*msg = 0; /* NULL terminate the string */
}
return (errstr);
Expand Down

0 comments on commit d9f3785

Please sign in to comment.