Skip to content

Commit

Permalink
Fixed digit count in sscanf, e.g. "%1x"
Browse files Browse the repository at this point in the history
(cherry picked from commit 12f14bd)
  • Loading branch information
slouken authored and sezero committed Jun 18, 2022
1 parent 8d368ea commit b1408d1
Showing 1 changed file with 30 additions and 14 deletions.
44 changes: 30 additions & 14 deletions src/stdlib/SDL_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ static unsigned UTF8_TrailingBytes(unsigned char c)

#if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOL)
static size_t
SDL_ScanLong(const char *text, int radix, long *valuep)
SDL_ScanLong(const char *text, int count, int radix, long *valuep)
{
const char *textstart = text;
long value = 0;
Expand All @@ -85,6 +85,10 @@ SDL_ScanLong(const char *text, int radix, long *valuep)
value *= radix;
value += v;
++text;

if (count > 0 && (text - textstart) == count) {
break;
}
}
if (valuep && text > textstart) {
if (negative && value) {
Expand All @@ -99,7 +103,7 @@ SDL_ScanLong(const char *text, int radix, long *valuep)

#if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOUL) || !defined(HAVE_STRTOD)
static size_t
SDL_ScanUnsignedLong(const char *text, int radix, unsigned long *valuep)
SDL_ScanUnsignedLong(const char *text, int count, int radix, unsigned long *valuep)
{
const char *textstart = text;
unsigned long value = 0;
Expand All @@ -121,6 +125,10 @@ SDL_ScanUnsignedLong(const char *text, int radix, unsigned long *valuep)
value *= radix;
value += v;
++text;

if (count > 0 && (text - textstart) == count) {
break;
}
}
if (valuep && text > textstart) {
*valuep = value;
Expand Down Expand Up @@ -163,7 +171,7 @@ SDL_ScanUintPtrT(const char *text, int radix, uintptr_t * valuep)

#if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOLL)
static size_t
SDL_ScanLongLong(const char *text, int radix, Sint64 * valuep)
SDL_ScanLongLong(const char *text, int count, int radix, Sint64 * valuep)
{
const char *textstart = text;
Sint64 value = 0;
Expand All @@ -190,6 +198,10 @@ SDL_ScanLongLong(const char *text, int radix, Sint64 * valuep)
value *= radix;
value += v;
++text;

if (count > 0 && (text - textstart) == count) {
break;
}
}
if (valuep && text > textstart) {
if (negative && value) {
Expand All @@ -204,7 +216,7 @@ SDL_ScanLongLong(const char *text, int radix, Sint64 * valuep)

#if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOULL)
static size_t
SDL_ScanUnsignedLongLong(const char *text, int radix, Uint64 * valuep)
SDL_ScanUnsignedLongLong(const char *text, int count, int radix, Uint64 * valuep)
{
const char *textstart = text;
Uint64 value = 0;
Expand All @@ -226,6 +238,10 @@ SDL_ScanUnsignedLongLong(const char *text, int radix, Uint64 * valuep)
value *= radix;
value += v;
++text;

if (count > 0 && (text - textstart) == count) {
break;
}
}
if (valuep && text > textstart) {
*valuep = value;
Expand All @@ -247,7 +263,7 @@ SDL_ScanFloat(const char *text, double *valuep)
negative = SDL_TRUE;
++text;
}
text += SDL_ScanUnsignedLong(text, 10, &lvalue);
text += SDL_ScanUnsignedLong(text, 0, 10, &lvalue);
value += lvalue;
if (*text == '.') {
int mult = 10;
Expand Down Expand Up @@ -964,7 +980,7 @@ SDL_strtol(const char *string, char **endp, int base)
}
}

len = SDL_ScanLong(string, base, &value);
len = SDL_ScanLong(string, 0, base, &value);
if (endp) {
*endp = (char *) string + len;
}
Expand All @@ -989,7 +1005,7 @@ SDL_strtoul(const char *string, char **endp, int base)
}
}

len = SDL_ScanUnsignedLong(string, base, &value);
len = SDL_ScanUnsignedLong(string, 0, base, &value);
if (endp) {
*endp = (char *) string + len;
}
Expand All @@ -1014,7 +1030,7 @@ SDL_strtoll(const char *string, char **endp, int base)
}
}

len = SDL_ScanLongLong(string, base, &value);
len = SDL_ScanLongLong(string, 0, base, &value);
if (endp) {
*endp = (char *) string + len;
}
Expand All @@ -1039,7 +1055,7 @@ SDL_strtoull(const char *string, char **endp, int base)
}
}

len = SDL_ScanUnsignedLongLong(string, base, &value);
len = SDL_ScanUnsignedLongLong(string, 0, base, &value);
if (endp) {
*endp = (char *) string + len;
}
Expand Down Expand Up @@ -1217,7 +1233,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap)
suppress = SDL_TRUE;
++fmt;
}
fmt += SDL_ScanLong(fmt, 10, &count);
fmt += SDL_ScanLong(fmt, 0, 10, &count);

if (*fmt == 'c') {
if (!count) {
Expand Down Expand Up @@ -1281,7 +1297,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap)
case 'd':
if (inttype == DO_LONGLONG) {
Sint64 value;
advance = SDL_ScanLongLong(text, radix, &value);
advance = SDL_ScanLongLong(text, count, radix, &value);
text += advance;
if (advance && !suppress) {
Sint64 *valuep = va_arg(ap, Sint64 *);
Expand All @@ -1290,7 +1306,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap)
}
} else {
long value;
advance = SDL_ScanLong(text, radix, &value);
advance = SDL_ScanLong(text, count, radix, &value);
text += advance;
if (advance && !suppress) {
switch (inttype) {
Expand Down Expand Up @@ -1335,7 +1351,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap)
case 'u':
if (inttype == DO_LONGLONG) {
Uint64 value = 0;
advance = SDL_ScanUnsignedLongLong(text, radix, &value);
advance = SDL_ScanUnsignedLongLong(text, count, radix, &value);
text += advance;
if (advance && !suppress) {
Uint64 *valuep = va_arg(ap, Uint64 *);
Expand All @@ -1344,7 +1360,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap)
}
} else {
unsigned long value = 0;
advance = SDL_ScanUnsignedLong(text, radix, &value);
advance = SDL_ScanUnsignedLong(text, count, radix, &value);
text += advance;
if (advance && !suppress) {
switch (inttype) {
Expand Down

0 comments on commit b1408d1

Please sign in to comment.