diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 7961157ccf3dd..3a7d5e461bf75 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -591,6 +591,25 @@ extern "C" { */ #define SDL_HINT_CAMERA_DRIVER "SDL_CAMERA_DRIVER" +/** + * A variable that controls whether object validity checks are enabled. + * + * Object validity checks prevent undefined behaviour when passing invalid + * pointers to SDL functions. A function will return invalid argument error + * if you pass pointer to uninitialized/freed SDL object. You may want to + * disable these checks to improve performance. + * + * The variable can be set to the following values: + * + * - "0": Disable object validity checks + * - "1": Enable object validity checks + * + * This hint should be set before SDL is initialized. + * + * \since This hint is avaliable since ??? + */ +#define SDL_HINT_CHECK_OBJECT_VALIDITY "SDL_CHECK_OBJECT_VALIDITY" + /** * A variable that limits what CPU features are available. * diff --git a/src/SDL_utils.c b/src/SDL_utils.c index f2090747a8d35..6144330d3b359 100644 --- a/src/SDL_utils.c +++ b/src/SDL_utils.c @@ -137,6 +137,7 @@ Uint32 SDL_GetNextObjectID(void) static SDL_InitState SDL_objects_init; static SDL_HashTable *SDL_objects; +static bool check_validity = true; static Uint32 SDLCALL SDL_HashObject(void *unused, const void *key) { @@ -153,6 +154,7 @@ void SDL_SetObjectValid(void *object, SDL_ObjectType type, bool valid) SDL_assert(object != NULL); if (SDL_ShouldInit(&SDL_objects_init)) { + check_validity = SDL_GetHintBoolean(SDL_HINT_CHECK_OBJECT_VALIDITY, true); SDL_objects = SDL_CreateHashTable(0, true, SDL_HashObject, SDL_KeyMatchObject, NULL, NULL); const bool initialized = (SDL_objects != NULL); SDL_SetInitialized(&SDL_objects_init, initialized); @@ -161,10 +163,12 @@ void SDL_SetObjectValid(void *object, SDL_ObjectType type, bool valid) } } - if (valid) { - SDL_InsertIntoHashTable(SDL_objects, object, (void *)(uintptr_t)type, true); - } else { - SDL_RemoveFromHashTable(SDL_objects, object); + if (check_validity) { + if (valid) { + SDL_InsertIntoHashTable(SDL_objects, object, (void *)(uintptr_t)type, true); + } else { + SDL_RemoveFromHashTable(SDL_objects, object); + } } } @@ -174,6 +178,10 @@ bool SDL_ObjectValid(void *object, SDL_ObjectType type) return false; } + if (!check_validity) { + return true; + } + const void *object_type; if (!SDL_FindInHashTable(SDL_objects, object, &object_type)) { return false;