Added magic to detect already freed or otherwise invalid windows and textures.
authorSam Lantinga <slouken@libsdl.org>
Sun, 24 Jan 2010 20:21:51 +0000
changeset 3695 f6a8be3fefa0
parent 3694 b0a707f589a6
child 3696 47d923feedb0
Added magic to detect already freed or otherwise invalid windows and textures.
src/video/SDL_sysvideo.h
src/video/SDL_video.c
--- a/src/video/SDL_sysvideo.h	Sun Jan 24 19:47:17 2010 +0000
+++ b/src/video/SDL_sysvideo.h	Sun Jan 24 20:21:51 2010 +0000
@@ -37,6 +37,7 @@
 /* Define the SDL texture structure */
 struct SDL_Texture
 {
+    const void *magic;
     Uint32 format;              /**< The pixel format of the texture */
     int access;                 /**< SDL_TextureAccess */
     int w;                      /**< The width of the texture */
@@ -138,6 +139,7 @@
 /* Define the SDL window structure, corresponding to toplevel windows */
 struct SDL_Window
 {
+    const void *magic;
     Uint32 id;
     char *title;
     int x, y;
@@ -308,6 +310,8 @@
     int num_displays;
     SDL_VideoDisplay *displays;
     int current_display;
+    Uint8 window_magic;
+    Uint8 texture_magic;
     Uint32 next_object_id;
 
     /* * * */
--- a/src/video/SDL_video.c	Sun Jan 24 19:47:17 2010 +0000
+++ b/src/video/SDL_video.c	Sun Jan 24 20:21:51 2010 +0000
@@ -105,6 +105,26 @@
 
 static SDL_VideoDevice *_this = NULL;
 
+#define CHECK_WINDOW_MAGIC(window, retval) \
+    if (!_this) { \
+        SDL_UninitializedVideo(); \
+        return retval; \
+    } \
+	if (!window || window->magic != &_this->window_magic) { \
+        SDL_SetError("Invalid window"); \
+        return retval; \
+    }
+
+#define CHECK_TEXTURE_MAGIC(texture, retval) \
+    if (!_this) { \
+        SDL_UninitializedVideo(); \
+        return retval; \
+    } \
+	if (!texture || texture->magic != &_this->texture_magic) { \
+        SDL_SetError("Invalid texture"); \
+        return retval; \
+    }
+
 /* Various local functions */
 static void SDL_UpdateWindowGrab(SDL_Window * window);
 
@@ -710,9 +730,7 @@
 int
 SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode)
 {
-    if (!window) {
-        return -1;
-    }
+    CHECK_WINDOW_MAGIC(window, -1);
 
     if (mode) {
         window->fullscreen_mode = *mode;
@@ -727,9 +745,7 @@
 {
     SDL_DisplayMode fullscreen_mode;
 
-    if (!window) {
-        return -1;
-    }
+    CHECK_WINDOW_MAGIC(window, -1);
 
     fullscreen_mode = window->fullscreen_mode;
     if (!fullscreen_mode.w) {
@@ -897,6 +913,7 @@
     }
     display = SDL_CurrentDisplay;
     window = (SDL_Window *)SDL_calloc(1, sizeof(*window));
+    window->magic = &_this->window_magic;
     window->id = _this->next_object_id++;
     window->x = x;
     window->y = y;
@@ -944,6 +961,7 @@
     }
     display = SDL_CurrentDisplay;
     window = (SDL_Window *)SDL_calloc(1, sizeof(*window));
+    window->magic = &_this->window_magic;
     window->id = _this->next_object_id++;
     window->flags = SDL_WINDOW_FOREIGN;
     window->display = display;
@@ -1047,9 +1065,8 @@
 Uint32
 SDL_GetWindowID(SDL_Window * window)
 {
-    if (!window) {
-        return 0;
-    }
+    CHECK_WINDOW_MAGIC(window, 0);
+
     return window->id;
 }
 
@@ -1077,16 +1094,17 @@
 Uint32
 SDL_GetWindowFlags(SDL_Window * window)
 {
-    if (!window) {
-        return 0;
-    }
+    CHECK_WINDOW_MAGIC(window, 0);
+
     return window->flags;
 }
 
 void
 SDL_SetWindowTitle(SDL_Window * window, const char *title)
 {
-    if (!window || title == window->title) {
+    CHECK_WINDOW_MAGIC(window, );
+
+    if (title == window->title) {
         return;
     }
     if (window->title) {
@@ -1106,18 +1124,16 @@
 const char *
 SDL_GetWindowTitle(SDL_Window * window)
 {
-    if (!window) {
-        return NULL;
-    }
+    CHECK_WINDOW_MAGIC(window, NULL);
+
     return window->title;
 }
 
 void
 SDL_SetWindowIcon(SDL_Window * window, SDL_Surface * icon)
 {
-    if (!window) {
-        return;
-    }
+    CHECK_WINDOW_MAGIC(window, );
+
     if (_this->SetWindowIcon) {
         _this->SetWindowIcon(_this, window, icon);
     }
@@ -1126,27 +1142,24 @@
 void
 SDL_SetWindowData(SDL_Window * window, void *userdata)
 {
-    if (!window) {
-        return;
-    }
+    CHECK_WINDOW_MAGIC(window, );
+
     window->userdata = userdata;
 }
 
 void *
 SDL_GetWindowData(SDL_Window * window)
 {
-    if (!window) {
-        return NULL;
-    }
+    CHECK_WINDOW_MAGIC(window, NULL);
+
     return window->userdata;
 }
 
 void
 SDL_SetWindowPosition(SDL_Window * window, int x, int y)
 {
-    if (!window) {
-        return;
-    }
+    CHECK_WINDOW_MAGIC(window, );
+
     if (x != SDL_WINDOWPOS_UNDEFINED) {
         window->x = x;
     }
@@ -1162,9 +1175,8 @@
 void
 SDL_GetWindowPosition(SDL_Window * window, int *x, int *y)
 {
-    if (!window) {
-        return;
-    }
+    CHECK_WINDOW_MAGIC(window, );
+
     if (x) {
         *x = window->x;
     }
@@ -1176,9 +1188,8 @@
 void
 SDL_SetWindowSize(SDL_Window * window, int w, int h)
 {
-    if (!window) {
-        return;
-    }
+    CHECK_WINDOW_MAGIC(window, );
+
     window->w = w;
     window->h = h;
 
@@ -1211,7 +1222,9 @@
 void
 SDL_ShowWindow(SDL_Window * window)
 {
-    if (!window || (window->flags & SDL_WINDOW_SHOWN)) {
+    CHECK_WINDOW_MAGIC(window, );
+
+    if (window->flags & SDL_WINDOW_SHOWN) {
         return;
     }
 
@@ -1224,7 +1237,9 @@
 void
 SDL_HideWindow(SDL_Window * window)
 {
-    if (!window || !(window->flags & SDL_WINDOW_SHOWN)) {
+    CHECK_WINDOW_MAGIC(window, );
+
+    if (!(window->flags & SDL_WINDOW_SHOWN)) {
         return;
     }
 
@@ -1237,7 +1252,9 @@
 void
 SDL_RaiseWindow(SDL_Window * window)
 {
-    if (!window || !(window->flags & SDL_WINDOW_SHOWN)) {
+    CHECK_WINDOW_MAGIC(window, );
+
+    if (!(window->flags & SDL_WINDOW_SHOWN)) {
         return;
     }
     if (_this->RaiseWindow) {
@@ -1251,7 +1268,9 @@
 void
 SDL_MaximizeWindow(SDL_Window * window)
 {
-    if (!window || (window->flags & SDL_WINDOW_MAXIMIZED)) {
+    CHECK_WINDOW_MAGIC(window, );
+
+    if (window->flags & SDL_WINDOW_MAXIMIZED) {
         return;
     }
 
@@ -1264,7 +1283,9 @@
 void
 SDL_MinimizeWindow(SDL_Window * window)
 {
-    if (!window || (window->flags & SDL_WINDOW_MINIMIZED)) {
+    CHECK_WINDOW_MAGIC(window, );
+
+    if (window->flags & SDL_WINDOW_MINIMIZED) {
         return;
     }
 
@@ -1277,8 +1298,9 @@
 void
 SDL_RestoreWindow(SDL_Window * window)
 {
-    if (!window
-        || !(window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) {
+    CHECK_WINDOW_MAGIC(window, );
+
+    if (!(window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) {
         return;
     }
 
@@ -1291,9 +1313,8 @@
 int
 SDL_SetWindowFullscreen(SDL_Window * window, int fullscreen)
 {
-    if (!window) {
-        return -1;
-    }
+    CHECK_WINDOW_MAGIC(window, -1);
+
     if (fullscreen) {
         fullscreen = SDL_WINDOW_FULLSCREEN;
     }
@@ -1315,7 +1336,9 @@
 void
 SDL_SetWindowGrab(SDL_Window * window, int mode)
 {
-    if (!window || (!!mode == !!(window->flags & SDL_WINDOW_INPUT_GRABBED))) {
+    CHECK_WINDOW_MAGIC(window, );
+
+    if ((!!mode == !!(window->flags & SDL_WINDOW_INPUT_GRABBED))) {
         return;
     }
     if (mode) {
@@ -1337,9 +1360,8 @@
 int
 SDL_GetWindowGrab(SDL_Window * window)
 {
-    if (!window) {
-        return 0;
-    }
+    CHECK_WINDOW_MAGIC(window, 0);
+
     return ((window->flags & SDL_WINDOW_INPUT_GRABBED) != 0);
 }
 
@@ -1436,10 +1458,8 @@
 {
     SDL_VideoDisplay *display;
 
-    if (!_this || !window || !window->id) {
-        SDL_SetError("Invalid window");
-        return;
-    }
+    CHECK_WINDOW_MAGIC(window, );
+    window->magic = NULL;
 
     if (window->title) {
         SDL_free(window->title);
@@ -1469,9 +1489,6 @@
         display->windows = window->next;
     }
 
-    /* Clear the ID so we know it was destroyed */
-    window->id = 0;
-
     SDL_free(window);
 }
 
@@ -1519,10 +1536,7 @@
 int
 SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
 {
-    if (!window) {
-        SDL_SetError("Invalid window");
-        return -1;
-    }
+    CHECK_WINDOW_MAGIC(window, -1);
 
     /* Free any existing renderer */
     SDL_DestroyRenderer(window);
@@ -1596,10 +1610,8 @@
 {
     SDL_Renderer *renderer;
 
-    if (!window) {
-        SDL_SetError("Invalid window");
-        return -1;
-    }
+    CHECK_WINDOW_MAGIC(window, -1);
+
     renderer = window->renderer;
     if (!renderer) {
         SDL_SetError("Use SDL_CreateRenderer() to create a renderer");
@@ -1644,6 +1656,7 @@
         SDL_OutOfMemory();
         return 0;
     }
+    texture->magic = &_this->texture_magic;
     texture->format = format;
     texture->access = access;
     texture->w = w;
@@ -1972,9 +1985,8 @@
 SDL_QueryTexture(SDL_Texture * texture, Uint32 * format, int *access,
                  int *w, int *h)
 {
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     if (format) {
         *format = texture->format;
     }
@@ -1995,9 +2007,8 @@
 {
     SDL_Renderer *renderer;
 
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     renderer = texture->renderer;
     if (!renderer->QueryTexturePixels) {
         SDL_Unsupported();
@@ -2012,9 +2023,8 @@
 {
     SDL_Renderer *renderer;
 
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     renderer = texture->renderer;
     if (!renderer->SetTexturePalette) {
         SDL_Unsupported();
@@ -2030,9 +2040,8 @@
 {
     SDL_Renderer *renderer;
 
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     renderer = texture->renderer;
     if (!renderer->GetTexturePalette) {
         SDL_Unsupported();
@@ -2047,9 +2056,8 @@
 {
     SDL_Renderer *renderer;
 
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     renderer = texture->renderer;
     if (!renderer->SetTextureColorMod) {
         SDL_Unsupported();
@@ -2072,9 +2080,8 @@
 {
     SDL_Renderer *renderer;
 
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     renderer = texture->renderer;
     if (r) {
         *r = texture->r;
@@ -2093,9 +2100,8 @@
 {
     SDL_Renderer *renderer;
 
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     renderer = texture->renderer;
     if (!renderer->SetTextureAlphaMod) {
         SDL_Unsupported();
@@ -2113,9 +2119,8 @@
 int
 SDL_GetTextureAlphaMod(SDL_Texture * texture, Uint8 * alpha)
 {
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     if (alpha) {
         *alpha = texture->a;
     }
@@ -2127,9 +2132,8 @@
 {
     SDL_Renderer *renderer;
 
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     renderer = texture->renderer;
     if (!renderer->SetTextureBlendMode) {
         SDL_Unsupported();
@@ -2142,9 +2146,8 @@
 int
 SDL_GetTextureBlendMode(SDL_Texture * texture, int *blendMode)
 {
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     if (blendMode) {
         *blendMode = texture->blendMode;
     }
@@ -2156,9 +2159,8 @@
 {
     SDL_Renderer *renderer;
 
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     renderer = texture->renderer;
     if (!renderer->SetTextureScaleMode) {
         SDL_Unsupported();
@@ -2171,9 +2173,8 @@
 int
 SDL_GetTextureScaleMode(SDL_Texture * texture, int *scaleMode)
 {
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     if (scaleMode) {
         *scaleMode = texture->scaleMode;
     }
@@ -2187,9 +2188,8 @@
     SDL_Renderer *renderer;
     SDL_Rect full_rect;
 
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     renderer = texture->renderer;
     if (!renderer->UpdateTexture) {
         SDL_Unsupported();
@@ -2212,9 +2212,8 @@
     SDL_Renderer *renderer;
     SDL_Rect full_rect;
 
-    if (!texture) {
-        return -1;
-    }
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
         SDL_SetError("SDL_LockTexture(): texture must be streaming");
         return -1;
@@ -2240,9 +2239,8 @@
 {
     SDL_Renderer *renderer;
 
-    if (!texture) {
-        return;
-    }
+    CHECK_TEXTURE_MAGIC(texture, );
+
     if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
         return;
     }
@@ -2259,9 +2257,8 @@
 {
     SDL_Renderer *renderer;
 
-    if (!texture) {
-        return;
-    }
+    CHECK_TEXTURE_MAGIC(texture, );
+
     if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
         return;
     }
@@ -2544,14 +2541,12 @@
     SDL_Rect real_srcrect;
     SDL_Rect real_dstrect;
 
+    CHECK_TEXTURE_MAGIC(texture, -1);
+
     renderer = SDL_GetCurrentRenderer(SDL_TRUE);
     if (!renderer) {
         return -1;
     }
-    if (!texture) {
-        SDL_SetError("Texture not found");
-        return -1;
-    }
     if (texture->renderer != renderer) {
         SDL_SetError("Texture was not created with this renderer");
         return -1;
@@ -2704,10 +2699,8 @@
 {
     SDL_Renderer *renderer;
 
-    if (!texture || !texture->renderer) {
-        SDL_SetError("Invalid texture");
-        return;
-    }
+    CHECK_TEXTURE_MAGIC(texture, );
+    texture->magic = NULL;
 
     renderer = texture->renderer;
     if (texture->next) {
@@ -2718,7 +2711,6 @@
     } else {
         renderer->textures = texture->next;
     }
-    texture->renderer = NULL;
 
     renderer->DestroyTexture(renderer, texture);
     SDL_free(texture);
@@ -2729,9 +2721,8 @@
 {
     SDL_Renderer *renderer;
 
-    if (!window) {
-        return;
-    }
+    CHECK_WINDOW_MAGIC(window, );
+
     renderer = window->renderer;
     if (!renderer) {
         return;
@@ -3215,9 +3206,8 @@
 SDL_GLContext
 SDL_GL_CreateContext(SDL_Window * window)
 {
-    if (!window) {
-        return NULL;
-    }
+    CHECK_WINDOW_MAGIC(window, NULL);
+
     if (!(window->flags & SDL_WINDOW_OPENGL)) {
         SDL_SetError("The specified window isn't an OpenGL window");
         return NULL;
@@ -3228,7 +3218,9 @@
 int
 SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext context)
 {
-    if (window && !(window->flags & SDL_WINDOW_OPENGL)) {
+    CHECK_WINDOW_MAGIC(window, -1);
+
+    if (!(window->flags & SDL_WINDOW_OPENGL)) {
         SDL_SetError("The specified window isn't an OpenGL window");
         return -1;
     }
@@ -3271,9 +3263,8 @@
 void
 SDL_GL_SwapWindow(SDL_Window * window)
 {
-    if (!window) {
-        return;
-    }
+    CHECK_WINDOW_MAGIC(window, );
+
     if (!(window->flags & SDL_WINDOW_OPENGL)) {
         SDL_SetError("The specified window isn't an OpenGL window");
         return;
@@ -3393,7 +3384,9 @@
 SDL_bool
 SDL_GetWindowWMInfo(SDL_Window * window, struct SDL_SysWMinfo *info)
 {
-    if (!window || !_this->GetWindowWMInfo) {
+    CHECK_WINDOW_MAGIC(window, SDL_FALSE);
+
+    if (!_this->GetWindowWMInfo) {
         return SDL_FALSE;
     }
     return (_this->GetWindowWMInfo(_this, window, info));