SDL_mixer: stb_vorbis: Increase setup_malloc() size parameter to uint64 (52afb)

From 52afb20701c7f67cf1aa27046378835be1af2f1c Mon Sep 17 00:00:00 2001
From: AliceLR <[EMAIL REDACTED]>
Date: Fri, 5 Jun 2026 06:33:32 +0300
Subject: [PATCH] stb_vorbis: Increase setup_malloc() size parameter to uint64

Expands the setup_malloc size parameter, and various calculations
that the Vorbis spec allows to exceed 32 bits, to uint64. setup_malloc
and setup_temp_malloc still reject allocations that exceed INT_MAX,
as the underlying memory fields are still 32 bit signed integers.

Reference issue: https://github.com/libxmp/libxmp/issues/996
Reference issue: https://github.com/nothings/stb/issues/1947
Reference issue: https://github.com/nothings/stb/issues/1933
Also see       : https://github.com/nothings/stb/issues/1168#issuecomment-1082625780
Mainstream P/R : https://github.com/nothings/stb/pull/1960
---
 src/decoder_stb_vorbis.c    |  1 +
 src/stb_vorbis/stb_vorbis.h | 48 ++++++++++++++++++++++++++-----------
 2 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/src/decoder_stb_vorbis.c b/src/decoder_stb_vorbis.c
index eea7dc09f..3a15e734f 100644
--- a/src/decoder_stb_vorbis.c
+++ b/src/decoder_stb_vorbis.c
@@ -70,6 +70,7 @@ typedef Uint16 uint16;
 typedef Sint16 int16;
 typedef Uint32 uint32;
 typedef Sint32 int32;
+typedef Uint64 uint64;
 
 #include "stb_vorbis/stb_vorbis.h"
 
diff --git a/src/stb_vorbis/stb_vorbis.h b/src/stb_vorbis/stb_vorbis.h
index fca54cdb1..3ab0e7edd 100644
--- a/src/stb_vorbis/stb_vorbis.h
+++ b/src/stb_vorbis/stb_vorbis.h
@@ -652,13 +652,28 @@ enum STBVorbisError
 #define MAX_BLOCKSIZE      (1 << MAX_BLOCKSIZE_LOG)
 
 #ifndef STB_VORBIS_STDINT_DEFINED /* for using SDL types */
+#if defined B_BEOS_VERSION
+   #include <SupportDefs.h>
+#elif defined __amigaos4__
+   #include <exec/types.h>
+#elif defined _arch_dreamcast /* KallistiOS */
+   #include <arch/types.h>
+#else
 typedef unsigned char  uint8;
 typedef   signed char   int8;
 typedef unsigned short uint16;
 typedef   signed short  int16;
 typedef unsigned int   uint32;
 typedef   signed int    int32;
-#endif
+#ifdef _MSC_VER /* MSVC6 has no long long */
+typedef unsigned __int64 uint64;
+#elif defined(_LP64) || defined(__LP64__)
+typedef unsigned long uint64;
+#else
+typedef unsigned long long uint64;
+#endif /* uint64 */
+#endif /* !BeOS && !AmigaOS4 && !KallistiOS */
+#endif /* !STB_VORBIS_STDINT_DEFINED */
 
 #ifdef __has_feature
 #if __has_feature(undefined_behavior_sanitizer)
@@ -710,7 +725,7 @@ typedef struct
    uint8  lookup_type;
    uint8  sequence_p;
    uint8  sparse;
-   uint32 lookup_values;
+   uint64 lookup_values; /* entries (24 bits) * dimensions (16 bits) */
    codetype *multiplicands;
    uint32 *codewords;
    #ifdef STB_VORBIS_FAST_HUFFMAN_SHORT
@@ -996,14 +1011,15 @@ static void *make_block_array(void *mem, int count, int size)
   }
 }
 
-static void *setup_malloc(vorb *f, int sz)
+static void *setup_malloc(vorb *f, uint64 siz)
 {
-   if (sz <= 0 || INT_MAX - 7 < sz) return NULL;
+   int sz = (int)siz;
+   if (sz <= 0 || (uint64)INT_MAX - 7 < siz) return NULL;
    sz = (sz+7) & ~7; // round up to nearest 8 for alignment of future allocs.
    f->setup_memory_required += sz;
    if (f->alloc.alloc_buffer) {
       void *p = (char *) f->alloc.alloc_buffer + f->setup_offset;
-      if (f->setup_offset + sz > f->temp_offset) return NULL;
+      if (f->temp_offset < sz || f->temp_offset - sz < f->setup_offset) return NULL;
       f->setup_offset += sz;
       return p;
    }
@@ -1016,19 +1032,20 @@ static void setup_free(vorb *f, void *p)
    free(p);
 }
 
-static void *setup_temp_malloc(vorb *f, int sz)
+static void *setup_temp_malloc(vorb *f, uint64 siz)
 {
-   if (sz <= 0 || INT_MAX - 7 < sz) return NULL;
+   int sz = (int)siz;
+   if (sz <= 0 || (uint64)INT_MAX - 7 < siz) return NULL;
    sz = (sz+7) & ~7; // round up to nearest 8 for alignment of future allocs.
    if (f->alloc.alloc_buffer) {
-      if (f->temp_offset - sz < f->setup_offset) return NULL;
+      if (f->temp_offset < sz || f->temp_offset - sz < f->setup_offset) return NULL;
       f->temp_offset -= sz;
       return (char *) f->alloc.alloc_buffer + f->temp_offset;
    }
    return malloc(sz);
 }
 
-static void setup_temp_free(vorb *f, void **_p, int sz)
+static void setup_temp_free(vorb *f, void **_p, uint64 sz)
 {
    void *p = *_p;
    *_p = NULL;
@@ -4014,9 +4031,12 @@ static int start_decoder(vorb *f)
             if (values < 0) return error(f, VORBIS_invalid_setup);
             c->lookup_values = (uint32) values;
          } else {
-            /* unsigned multiply to suppress (legitimate) warning.
-             * https://github.com/nothings/stb/issues/1168 */
-            c->lookup_values = (unsigned)c->entries * (unsigned)c->dimensions;
+            /* changed to unsigned multiply for:
+             * https://github.com/nothings/stb/issues/1168
+             * https://github.com/nothings/stb/issues/1947
+             * https://github.com/nothings/stb/issues/1933
+             * https://github.com/libxmp/libxmp/issues/996 */
+            c->lookup_values = (uint64)c->entries * (uint64)c->dimensions;
          }
          if (c->lookup_values == 0) return error(f, VORBIS_invalid_setup);
          mults = (uint16 *) setup_temp_malloc(f, sizeof(mults[0]) * c->lookup_values);
@@ -4035,9 +4055,9 @@ static int start_decoder(vorb *f)
             // pre-expand the lookup1-style multiplicands, to avoid a divide in the inner loop
             if (sparse) {
                if (c->sorted_entries == 0) goto skip;
-               c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->sorted_entries * c->dimensions);
+               c->multiplicands = (codetype *) setup_malloc(f, (uint64) sizeof(c->multiplicands[0]) * c->sorted_entries * c->dimensions);
             } else
-               c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->entries        * c->dimensions);
+               c->multiplicands = (codetype *) setup_malloc(f, (uint64) sizeof(c->multiplicands[0]) * c->entries        * c->dimensions);
             if (c->multiplicands == NULL) return error(f, VORBIS_outofmem);
             len = sparse ? c->sorted_entries : c->entries;
             for (j=0; j < len; ++j) {