Commit 216e3f10bb18022049235c7c82c38d5b4d8dbd4a

Sam Lantinga 2022-09-19T15:42:11

Implemented size_t format specifiers for SDL_snprintf() and SDL_sscanf() Fixes https://github.com/libsdl-org/SDL/issues/6264

diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c
index e454cf0..f1dbb65 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;