# HG changeset patch # User Sam Lantinga # Date 1264364511 0 # Node ID f6a8be3fefa01f01d6ce6aa1a0911e688fedfebc # Parent b0a707f589a66798caa94c039fea9d77eadd83db Added magic to detect already freed or otherwise invalid windows and textures. diff -r b0a707f589a6 -r f6a8be3fefa0 src/video/SDL_sysvideo.h --- 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; /* * * */ diff -r b0a707f589a6 -r f6a8be3fefa0 src/video/SDL_video.c --- 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));