SDL: Handle out of memory errors without any allocation

From 66e532fa61f7915a4f356c24789b5b79b8c9dfad Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 1 Dec 2023 09:05:04 -0800
Subject: [PATCH] Handle out of memory errors without any allocation

---
 src/SDL_error.c   | 26 ++++++++++++++------------
 src/SDL_error_c.h |  9 ++++++++-
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/src/SDL_error.c b/src/SDL_error.c
index 25fe696c79fa..b0db7aa10c08 100644
--- a/src/SDL_error.c
+++ b/src/SDL_error.c
@@ -32,7 +32,7 @@ int SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
         int result;
         SDL_error *error = SDL_GetErrBuf();
 
-        error->error = 1; /* mark error as valid */
+        error->error = SDL_ErrorCodeGeneric;
 
         va_start(ap, fmt);
         result = SDL_vsnprintf(error->str, error->len, fmt, ap);
@@ -63,12 +63,20 @@ int SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
 const char *SDL_GetError(void)
 {
     const SDL_error *error = SDL_GetErrBuf();
-    return error->error ? error->str : "";
+
+    switch (error->error) {
+    case SDL_ErrorCodeGeneric:
+        return error->str;
+    case SDL_ErrorCodeOutOfMemory:
+        return "Out of memory";
+    default:
+        return "";
+    }
 }
 
 void SDL_ClearError(void)
 {
-    SDL_GetErrBuf()->error = 0;
+    SDL_GetErrBuf()->error = SDL_ErrorCodeNone;
 }
 
 /* Very common errors go here */
@@ -76,7 +84,8 @@ int SDL_Error(SDL_errorcode code)
 {
     switch (code) {
     case SDL_ENOMEM:
-        return SDL_SetError("Out of memory");
+        SDL_GetErrBuf()->error = SDL_ErrorCodeOutOfMemory;
+        return -1;
     case SDL_EFREAD:
         return SDL_SetError("Error reading from datastream");
     case SDL_EFWRITE:
@@ -92,13 +101,6 @@ int SDL_Error(SDL_errorcode code)
 
 char *SDL_GetErrorMsg(char *errstr, int maxlen)
 {
-    const SDL_error *error = SDL_GetErrBuf();
-
-    if (error->error) {
-        SDL_strlcpy(errstr, error->str, maxlen);
-    } else {
-        *errstr = '\0';
-    }
-
+    SDL_strlcpy(errstr, SDL_GetError(), maxlen);
     return errstr;
 }
diff --git a/src/SDL_error_c.h b/src/SDL_error_c.h
index 4c63ee00186b..291f04b06872 100644
--- a/src/SDL_error_c.h
+++ b/src/SDL_error_c.h
@@ -27,9 +27,16 @@
 #ifndef SDL_error_c_h_
 #define SDL_error_c_h_
 
+typedef enum
+{
+    SDL_ErrorCodeNone,
+    SDL_ErrorCodeGeneric,
+    SDL_ErrorCodeOutOfMemory,
+} SDL_ErrorCode;
+
 typedef struct SDL_error
 {
-    int error; /* This is a numeric value corresponding to the current error */
+    SDL_ErrorCode error;
     char *str;
     size_t len;
     SDL_realloc_func realloc_func;