From 216e3f10bb18022049235c7c82c38d5b4d8dbd4a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 19 Sep 2022 15:42:11 -0700 Subject: [PATCH] Implemented size_t format specifiers for SDL_snprintf() and SDL_sscanf() Fixes https://github.com/libsdl-org/SDL/issues/6264 --- src/stdlib/SDL_string.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index e454cf04f..f1dbb655f 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -1141,7 +1141,8 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) DO_SHORT, DO_INT, DO_LONG, - DO_LONGLONG + DO_LONGLONG, + DO_SIZE_T } inttype = DO_INT; size_t advance; SDL_bool suppress = SDL_FALSE; @@ -1205,6 +1206,9 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) inttype = DO_LONGLONG; } break; + case 'z': + inttype = DO_SIZE_T; + break; case 'i': { int index = 0; @@ -1230,6 +1234,15 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) *valuep = value; ++retval; } + } else if (inttype == DO_SIZE_T) { + Sint64 value = 0; + advance = SDL_ScanLongLong(text, count, radix, &value); + text += advance; + if (advance && !suppress) { + size_t *valuep = va_arg(ap, size_t *); + *valuep = (size_t)value; + ++retval; + } } else { long value = 0; advance = SDL_ScanLong(text, count, radix, &value); @@ -1255,6 +1268,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) } break; case DO_LONGLONG: + case DO_SIZE_T: /* Handled above */ break; } @@ -1284,6 +1298,15 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) *valuep = value; ++retval; } + } else if (inttype == DO_SIZE_T) { + Uint64 value = 0; + advance = SDL_ScanUnsignedLongLong(text, count, radix, &value); + text += advance; + if (advance && !suppress) { + size_t *valuep = va_arg(ap, size_t *); + *valuep = (size_t)value; + ++retval; + } } else { unsigned long value = 0; advance = SDL_ScanUnsignedLong(text, count, radix, &value); @@ -1309,6 +1332,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) } break; case DO_LONGLONG: + case DO_SIZE_T: /* Handled above */ break; } @@ -1652,7 +1676,8 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, { DO_INT, DO_LONG, - DO_LONGLONG + DO_LONGLONG, + DO_SIZE_T } inttype = DO_INT; SDL_zero(info); @@ -1735,6 +1760,9 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, inttype = DO_LONGLONG; } break; + case 'z': + inttype = DO_SIZE_T; + break; case 'i': case 'd': if (info.precision >= 0) { @@ -1753,6 +1781,10 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, length += SDL_PrintLongLong(TEXT_AND_LEN_ARGS, &info, va_arg(ap, Sint64)); break; + case DO_SIZE_T: + length += SDL_PrintLongLong(TEXT_AND_LEN_ARGS, &info, + va_arg(ap, size_t)); + break; } done = SDL_TRUE; break; @@ -1795,6 +1827,10 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, length += SDL_PrintUnsignedLongLong(TEXT_AND_LEN_ARGS, &info, va_arg(ap, Uint64)); break; + case DO_SIZE_T: + length += SDL_PrintUnsignedLongLong(TEXT_AND_LEN_ARGS, &info, + va_arg(ap, size_t)); + break; } done = SDL_TRUE; break;