Prevent crashes if freed objects are passed to SDL API functions

Instead of using the magic tag in the object, we'll actually keep track of valid objects

Fixes https://github.com/libsdl-org/SDL/issues/9869
Fixes https://github.com/libsdl-org/SDL/issues/9235
This commit is contained in:
Sam Lantinga 2024-06-03 04:09:28 -07:00
parent 57a15933cd
commit b0e93e4e63
28 changed files with 191 additions and 126 deletions

View file

@ -543,6 +543,7 @@ void SDL_Quit(void)
SDL_DBus_Quit();
#endif
SDL_SetObjectsInvalid();
SDL_ClearHints();
SDL_AssertionsQuit();
@ -563,20 +564,6 @@ void SDL_Quit(void)
SDL_bInMainQuit = SDL_FALSE;
}
/* Assume we can wrap SDL_AtomicInt values and cast to Uint32 */
SDL_COMPILE_TIME_ASSERT(sizeof_object_id, sizeof(int) == sizeof(Uint32));
Uint32 SDL_GetNextObjectID(void)
{
static SDL_AtomicInt last_id;
Uint32 id = (Uint32)SDL_AtomicIncRef(&last_id) + 1;
if (id == 0) {
id = (Uint32)SDL_AtomicIncRef(&last_id) + 1;
}
return id;
}
/* Get the library version number */
int SDL_GetVersion(void)
{

View file

@ -83,6 +83,10 @@ SDL_bool SDL_InsertIntoHashTable(SDL_HashTable *table, const void *key, const vo
SDL_HashItem *item;
const Uint32 hash = calc_hash(table, key);
if (!table) {
return SDL_FALSE;
}
if ( (!table->stackable) && (SDL_FindInHashTable(table, key, NULL)) ) {
return SDL_FALSE;
}
@ -107,6 +111,10 @@ SDL_bool SDL_FindInHashTable(const SDL_HashTable *table, const void *key, const
void *data = table->data;
SDL_HashItem *i;
if (!table) {
return SDL_FALSE;
}
for (i = table->table[hash]; i; i = i->next) {
if (table->keymatch(key, i->key, data)) {
if (_value) {
@ -126,6 +134,10 @@ SDL_bool SDL_RemoveFromHashTable(SDL_HashTable *table, const void *key)
SDL_HashItem *prev = NULL;
void *data = table->data;
if (!table) {
return SDL_FALSE;
}
for (item = table->table[hash]; item; item = item->next) {
if (table->keymatch(key, item->key, data)) {
if (prev) {
@ -134,7 +146,9 @@ SDL_bool SDL_RemoveFromHashTable(SDL_HashTable *table, const void *key)
table->table[hash] = item->next;
}
table->nuke(item->key, item->value, data);
if (table->nuke) {
table->nuke(item->key, item->value, data);
}
SDL_free(item);
return SDL_TRUE;
}
@ -149,6 +163,10 @@ SDL_bool SDL_IterateHashTableKey(const SDL_HashTable *table, const void *key, co
{
SDL_HashItem *item = *iter ? ((SDL_HashItem *) *iter)->next : table->table[calc_hash(table, key)];
if (!table) {
return SDL_FALSE;
}
while (item) {
if (table->keymatch(key, item->key, table->data)) {
*_value = item->value;
@ -169,6 +187,10 @@ SDL_bool SDL_IterateHashTable(const SDL_HashTable *table, const void **_key, con
SDL_HashItem *item = (SDL_HashItem *) *iter;
Uint32 idx = 0;
if (!table) {
return SDL_FALSE;
}
if (item) {
const SDL_HashItem *orig = item;
item = item->next;
@ -219,7 +241,9 @@ void SDL_DestroyHashTable(SDL_HashTable *table)
SDL_HashItem *item = table->table[i];
while (item) {
SDL_HashItem *next = item->next;
table->nuke(item->key, item->value, data);
if (table->nuke) {
table->nuke(item->key, item->value, data);
}
SDL_free(item);
item = next;
}

View file

@ -279,6 +279,8 @@
#define SDL_MAIN_NOIMPL /* don't drag in header-only implementation of SDL_main */
#include <SDL3/SDL_main.h>
#include "SDL_utils_c.h"
/* The internal implementations of these functions have up to nanosecond precision.
We can expose these functions as part of the API if we want to later.
*/
@ -287,7 +289,6 @@
extern "C" {
#endif
extern Uint32 SDLCALL SDL_GetNextObjectID(void);
extern int SDLCALL SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS);
extern int SDLCALL SDL_WaitConditionTimeoutNS(SDL_Condition *cond, SDL_Mutex *mutex, Sint64 timeoutNS);
extern SDL_bool SDLCALL SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS);

View file

@ -20,7 +20,7 @@
*/
#include "SDL_internal.h"
#include "SDL_utils_c.h"
#include "SDL_hashtable.h"
/* Common utility functions that aren't in the public API */
@ -100,3 +100,68 @@ SDL_bool SDL_endswith(const char *string, const char *suffix)
}
return SDL_FALSE;
}
/* Assume we can wrap SDL_AtomicInt values and cast to Uint32 */
SDL_COMPILE_TIME_ASSERT(sizeof_object_id, sizeof(int) == sizeof(Uint32));
Uint32 SDL_GetNextObjectID(void)
{
static SDL_AtomicInt last_id;
Uint32 id = (Uint32)SDL_AtomicIncRef(&last_id) + 1;
if (id == 0) {
id = (Uint32)SDL_AtomicIncRef(&last_id) + 1;
}
return id;
}
static SDL_HashTable *SDL_objects;
static Uint32 SDL_HashObject(const void *key, void *unused)
{
return (Uint32)(uintptr_t)key;
}
static SDL_bool SDL_KeyMatchObject(const void *a, const void *b, void *unused)
{
return (a == b);
}
void SDL_SetObjectValid(void *object, SDL_ObjectType type, SDL_bool valid)
{
SDL_assert(object != NULL);
if (valid) {
if (!SDL_objects) {
SDL_objects = SDL_CreateHashTable(NULL, 32, SDL_HashObject, SDL_KeyMatchObject, NULL, SDL_FALSE);
}
SDL_InsertIntoHashTable(SDL_objects, object, (void *)(uintptr_t)type);
} else {
if (SDL_objects) {
SDL_RemoveFromHashTable(SDL_objects, object);
}
}
}
SDL_bool SDL_ObjectValid(void *object, SDL_ObjectType type)
{
if (!object) {
return SDL_FALSE;
}
const void *object_type;
if (!SDL_FindInHashTable(SDL_objects, object, &object_type)) {
return SDL_FALSE;
}
return (((SDL_ObjectType)(uintptr_t)object_type) == type);
}
void SDL_SetObjectsInvalid(void)
{
if (SDL_objects) {
SDL_DestroyHashTable(SDL_objects);
SDL_objects = NULL;
}
}

View file

@ -32,4 +32,24 @@ extern void SDL_CalculateFraction(float x, int *numerator, int *denominator);
extern SDL_bool SDL_endswith(const char *string, const char *suffix);
typedef enum
{
SDL_OBJECT_TYPE_UNKNOWN,
SDL_OBJECT_TYPE_WINDOW,
SDL_OBJECT_TYPE_RENDERER,
SDL_OBJECT_TYPE_TEXTURE,
SDL_OBJECT_TYPE_JOYSTICK,
SDL_OBJECT_TYPE_GAMEPAD,
SDL_OBJECT_TYPE_HAPTIC,
SDL_OBJECT_TYPE_SENSOR,
SDL_OBJECT_TYPE_HIDAPI_DEVICE,
SDL_OBJECT_TYPE_HIDAPI_JOYSTICK,
} SDL_ObjectType;
extern Uint32 SDL_GetNextObjectID(void);
extern void SDL_SetObjectValid(void *object, SDL_ObjectType type, SDL_bool valid);
extern SDL_bool SDL_ObjectValid(void *object, SDL_ObjectType type);
extern void SDL_SetObjectsInvalid(void);
#endif /* SDL_utils_h_ */

View file

@ -23,7 +23,6 @@
#include "SDL_audio_c.h"
#include "SDL_sysaudio.h"
#include "../thread/SDL_systhread.h"
#include "../SDL_utils_c.h"
// Available audio drivers
static const AudioBootStrap *const bootstrap[] = {

View file

@ -37,7 +37,6 @@
#include <sys/soundcard.h>
#include "../SDL_audiodev_c.h"
#include "../../SDL_utils_c.h"
#include "SDL_dspaudio.h"
static void DSP_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture)

View file

@ -891,7 +891,7 @@ int SDL_SetKeyboardFocus(SDL_Window *window)
SDL_Keyboard *keyboard = &SDL_keyboard;
if (window) {
if (!video || window->magic != &video->window_magic || window->is_destroying) {
if (!SDL_ObjectValid(window, SDL_OBJECT_TYPE_WINDOW) || window->is_destroying) {
return SDL_SetError("Invalid window");
}
}

View file

@ -25,10 +25,9 @@
#include "../joystick/SDL_joystick_c.h" /* For SDL_IsJoystickValid */
static SDL_Haptic *SDL_haptics = NULL;
static char SDL_haptic_magic;
#define CHECK_HAPTIC_MAGIC(haptic, retval) \
if (!haptic || haptic->magic != &SDL_haptic_magic) { \
if (!SDL_ObjectValid(haptic, SDL_OBJECT_TYPE_HAPTIC)) { \
SDL_InvalidParamError("haptic"); \
return retval; \
}
@ -135,7 +134,7 @@ SDL_Haptic *SDL_OpenHaptic(SDL_HapticID instance_id)
}
/* Initialize the haptic device */
haptic->magic = &SDL_haptic_magic;
SDL_SetObjectValid(haptic, SDL_OBJECT_TYPE_HAPTIC, SDL_TRUE);
haptic->instance_id = instance_id;
haptic->rumble_id = -1;
if (SDL_SYS_HapticOpen(haptic) < 0) {
@ -318,7 +317,7 @@ void SDL_CloseHaptic(SDL_Haptic *haptic)
}
}
SDL_SYS_HapticClose(haptic);
haptic->magic = NULL;
SDL_SetObjectValid(haptic, SDL_OBJECT_TYPE_HAPTIC, SDL_FALSE);
/* Remove from the list */
hapticlist = SDL_haptics;

View file

@ -40,8 +40,6 @@ struct haptic_effect
*/
struct SDL_Haptic
{
const void *magic;
SDL_HapticID instance_id; /* Device instance, monotonically increasing from 0 */
char *name; /* Device name - system dependent */

View file

@ -1000,19 +1000,17 @@ static const struct hidapi_backend LIBUSB_Backend = {
struct SDL_hid_device
{
const void *magic;
void *device;
const struct hidapi_backend *backend;
SDL_hid_device_info info;
};
static char device_magic;
#if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND) || defined(HAVE_LIBUSB)
static SDL_hid_device *CreateHIDDeviceWrapper(void *device, const struct hidapi_backend *backend)
{
SDL_hid_device *wrapper = (SDL_hid_device *)SDL_malloc(sizeof(*wrapper));
wrapper->magic = &device_magic;
SDL_SetObjectValid(wrapper, SDL_OBJECT_TYPE_HIDAPI_DEVICE, SDL_TRUE);
wrapper->device = device;
wrapper->backend = backend;
SDL_zero(wrapper->info);
@ -1021,20 +1019,20 @@ static SDL_hid_device *CreateHIDDeviceWrapper(void *device, const struct hidapi_
#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB */
static void DeleteHIDDeviceWrapper(SDL_hid_device *device)
static void DeleteHIDDeviceWrapper(SDL_hid_device *wrapper)
{
device->magic = NULL;
SDL_free(device->info.path);
SDL_free(device->info.serial_number);
SDL_free(device->info.manufacturer_string);
SDL_free(device->info.product_string);
SDL_free(device);
SDL_SetObjectValid(wrapper, SDL_OBJECT_TYPE_HIDAPI_DEVICE, SDL_FALSE);
SDL_free(wrapper->info.path);
SDL_free(wrapper->info.serial_number);
SDL_free(wrapper->info.manufacturer_string);
SDL_free(wrapper->info.product_string);
SDL_free(wrapper);
}
#define CHECK_DEVICE_MAGIC(device, retval) \
if (!device || device->magic != &device_magic) { \
SDL_SetError("Invalid device"); \
return retval; \
#define CHECK_DEVICE_MAGIC(device, retval) \
if (!SDL_ObjectValid(device, SDL_OBJECT_TYPE_HIDAPI_DEVICE)) { \
SDL_SetError("Invalid device"); \
return retval; \
}
#define COPY_IF_EXISTS(var) \

View file

@ -22,7 +22,6 @@
/* This is the gamepad API for Simple DirectMedia Layer */
#include "../SDL_utils_c.h"
#include "SDL_sysjoystick.h"
#include "SDL_joystick_c.h"
#include "SDL_steam_virtual_gamepad.h"
@ -104,15 +103,12 @@ static GamepadMapping_t *s_pSupportedGamepads SDL_GUARDED_BY(SDL_joystick_lock)
static GamepadMapping_t *s_pDefaultMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
static GamepadMapping_t *s_pXInputMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
static MappingChangeTracker *s_mappingChangeTracker SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
static char gamepad_magic;
#define _guarded SDL_GUARDED_BY(SDL_joystick_lock)
/* The SDL gamepad structure */
struct SDL_Gamepad
{
const void *magic _guarded;
SDL_Joystick *joystick _guarded; /* underlying joystick device */
int ref_count _guarded;
@ -131,12 +127,12 @@ struct SDL_Gamepad
#undef _guarded
#define CHECK_GAMEPAD_MAGIC(gamepad, retval) \
if (!gamepad || gamepad->magic != &gamepad_magic || \
!SDL_IsJoystickValid(gamepad->joystick)) { \
SDL_InvalidParamError("gamepad"); \
SDL_UnlockJoysticks(); \
return retval; \
#define CHECK_GAMEPAD_MAGIC(gamepad, retval) \
if (!SDL_ObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD) || \
!SDL_IsJoystickValid(gamepad->joystick)) { \
SDL_InvalidParamError("gamepad"); \
SDL_UnlockJoysticks(); \
return retval; \
}
static SDL_vidpid_list SDL_allowed_gamepads = {
@ -2683,7 +2679,7 @@ SDL_Gamepad *SDL_OpenGamepad(SDL_JoystickID instance_id)
SDL_UnlockJoysticks();
return NULL;
}
gamepad->magic = &gamepad_magic;
SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, SDL_TRUE);
gamepad->joystick = SDL_OpenJoystick(instance_id);
if (!gamepad->joystick) {
@ -3612,7 +3608,7 @@ void SDL_CloseGamepad(SDL_Gamepad *gamepad)
SDL_LockJoysticks();
if (!gamepad || gamepad->magic != &gamepad_magic) {
if (!SDL_ObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD)) {
SDL_UnlockJoysticks();
return;
}
@ -3641,7 +3637,7 @@ void SDL_CloseGamepad(SDL_Gamepad *gamepad)
gamepadlist = gamepadlist->next;
}
gamepad->magic = NULL;
SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, SDL_FALSE);
SDL_free(gamepad->bindings);
SDL_free(gamepad->last_match_axis);
SDL_free(gamepad->last_hat_mask);

View file

@ -121,7 +121,6 @@ static SDL_Joystick *SDL_joysticks SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
static int SDL_joystick_player_count SDL_GUARDED_BY(SDL_joystick_lock) = 0;
static SDL_JoystickID *SDL_joystick_players SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
static SDL_bool SDL_joystick_allows_background_events = SDL_FALSE;
char SDL_joystick_magic;
static Uint32 initial_arcadestick_devices[] = {
MAKE_VIDPID(0x0079, 0x181a), /* Venom Arcade Stick */
@ -415,11 +414,11 @@ static SDL_vidpid_list zero_centered_devices = {
SDL_FALSE
};
#define CHECK_JOYSTICK_MAGIC(joystick, retval) \
if (!joystick || joystick->magic != &SDL_joystick_magic) { \
SDL_InvalidParamError("joystick"); \
SDL_UnlockJoysticks(); \
return retval; \
#define CHECK_JOYSTICK_MAGIC(joystick, retval) \
if (!SDL_ObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK)) { \
SDL_InvalidParamError("joystick"); \
SDL_UnlockJoysticks(); \
return retval; \
}
SDL_bool SDL_JoysticksInitialized(void)
@ -1096,7 +1095,7 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id)
SDL_UnlockJoysticks();
return NULL;
}
joystick->magic = &SDL_joystick_magic;
SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_TRUE);
joystick->driver = driver;
joystick->instance_id = instance_id;
joystick->attached = SDL_TRUE;
@ -1104,6 +1103,7 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id)
joystick->battery_percent = -1;
if (driver->Open(joystick, device_index) < 0) {
SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_FALSE);
SDL_free(joystick);
SDL_UnlockJoysticks();
return NULL;
@ -1346,7 +1346,7 @@ int SDL_SendJoystickVirtualSensorData(SDL_Joystick *joystick, SDL_SensorType typ
SDL_bool SDL_IsJoystickValid(SDL_Joystick *joystick)
{
SDL_AssertJoysticksLocked();
return (joystick && joystick->magic == &SDL_joystick_magic);
return SDL_ObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK);
}
SDL_bool SDL_PrivateJoystickGetAutoGamepadMapping(SDL_JoystickID instance_id, SDL_GamepadMapping *out)
@ -1869,7 +1869,7 @@ void SDL_CloseJoystick(SDL_Joystick *joystick)
joystick->driver->Close(joystick);
joystick->hwdata = NULL;
joystick->magic = NULL;
SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_FALSE);
joysticklist = SDL_joysticks;
joysticklistprev = NULL;

View file

@ -33,7 +33,6 @@ extern "C" {
struct SDL_JoystickDriver;
struct SDL_SteamVirtualGamepadInfo;
extern char SDL_joystick_magic;
/* Initialization and shutdown functions */
extern int SDL_InitJoysticks(void);

View file

@ -76,8 +76,6 @@ typedef struct SDL_JoystickSensorInfo
struct SDL_Joystick
{
const void *magic _guarded;
SDL_JoystickID instance_id _guarded; /* Device instance, monotonically increasing from 0 */
char *name _guarded; /* Joystick name - system dependent */
char *path _guarded; /* Joystick path - system dependent */

View file

@ -91,7 +91,6 @@ static SDL_SpinLock SDL_HIDAPI_spinlock;
static SDL_bool SDL_HIDAPI_hints_changed = SDL_FALSE;
static Uint32 SDL_HIDAPI_change_count = 0;
static SDL_HIDAPI_Device *SDL_HIDAPI_devices SDL_GUARDED_BY(SDL_joystick_lock);
static char SDL_HIDAPI_device_magic;
static int SDL_HIDAPI_numjoysticks = 0;
static SDL_bool SDL_HIDAPI_combine_joycons = SDL_TRUE;
static SDL_bool initialized = SDL_FALSE;
@ -933,7 +932,7 @@ static SDL_HIDAPI_Device *HIDAPI_AddDevice(const struct SDL_hid_device_info *inf
if (!device) {
return NULL;
}
device->magic = &SDL_HIDAPI_device_magic;
SDL_SetObjectValid(device, SDL_OBJECT_TYPE_HIDAPI_JOYSTICK, SDL_TRUE);
device->path = SDL_strdup(info->path);
if (!device->path) {
SDL_free(device);
@ -1049,7 +1048,7 @@ static void HIDAPI_DelDevice(SDL_HIDAPI_Device *device)
device->children[i]->parent = NULL;
}
device->magic = NULL;
SDL_SetObjectValid(device, SDL_OBJECT_TYPE_HIDAPI_JOYSTICK, SDL_FALSE);
SDL_DestroyMutex(device->dev_lock);
SDL_free(device->manufacturer_string);
SDL_free(device->product_string);
@ -1547,7 +1546,7 @@ static SDL_bool HIDAPI_GetJoystickDevice(SDL_Joystick *joystick, SDL_HIDAPI_Devi
if (joystick && joystick->hwdata) {
*device = joystick->hwdata->device;
if (*device && (*device)->magic == &SDL_HIDAPI_device_magic && (*device)->driver != NULL) {
if (SDL_ObjectValid(*device, SDL_OBJECT_TYPE_HIDAPI_JOYSTICK) && (*device)->driver != NULL) {
return SDL_TRUE;
}
}

View file

@ -66,7 +66,6 @@ struct SDL_HIDAPI_DeviceDriver;
typedef struct SDL_HIDAPI_Device
{
const void *magic;
char *name;
char *manufacturer_string;
char *product_string;

View file

@ -41,7 +41,6 @@
#include <dirent.h>
#include <linux/joystick.h>
#include "../../SDL_utils_c.h"
#include "../../events/SDL_events_c.h"
#include "../../core/linux/SDL_evdev.h"
#include "../SDL_sysjoystick.h"
@ -2330,6 +2329,7 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
MAPPED_DPAD_ALL = 0xF,
};
unsigned int mapped;
SDL_bool result = SDL_FALSE;
SDL_AssertJoysticksLocked();
@ -2351,22 +2351,19 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
if (!joystick) {
return SDL_FALSE;
}
joystick->magic = &SDL_joystick_magic;
SDL_memcpy(&joystick->guid, &item->guid, sizeof(item->guid));
joystick->hwdata = (struct joystick_hwdata *)
SDL_calloc(1, sizeof(*joystick->hwdata));
joystick->hwdata = (struct joystick_hwdata *)SDL_calloc(1, sizeof(*joystick->hwdata));
if (!joystick->hwdata) {
SDL_free(joystick);
return SDL_FALSE;
}
SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_TRUE);
item->checked_mapping = SDL_TRUE;
if (PrepareJoystickHwdata(joystick, item, NULL) == -1) {
SDL_free(joystick->hwdata);
SDL_free(joystick);
return SDL_FALSE; /* SDL_SetError will already have been called */
if (PrepareJoystickHwdata(joystick, item, NULL) < 0) {
goto done; /* SDL_SetError will already have been called */
}
/* don't assign `item->hwdata` so it's not in any global state. */
@ -2375,9 +2372,7 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
if (!joystick->hwdata->has_key[BTN_GAMEPAD]) {
/* Not a gamepad according to the specs. */
LINUX_JoystickClose(joystick);
SDL_free(joystick);
return SDL_FALSE;
goto done;
}
/* We have a gamepad, start filling out the mappings */
@ -2773,9 +2768,6 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
}
}
LINUX_JoystickClose(joystick);
SDL_free(joystick);
/* Cache the mapping for later */
item->mapping = (SDL_GamepadMapping *)SDL_malloc(sizeof(*item->mapping));
if (item->mapping) {
@ -2784,8 +2776,14 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Generated mapping for device %d", device_index);
#endif
result = SDL_TRUE;
return SDL_TRUE;
done:
LINUX_JoystickClose(joystick);
SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_FALSE);
SDL_free(joystick);
return result;
}
SDL_JoystickDriver SDL_LINUX_JoystickDriver = {

View file

@ -46,10 +46,10 @@ this should probably be removed at some point in the future. --ryan. */
#define SDL_PROP_WINDOW_RENDERER_POINTER "SDL.internal.window.renderer"
#define SDL_PROP_TEXTURE_PARENT_POINTER "SDL.internal.texture.parent"
#define CHECK_RENDERER_MAGIC_BUT_NOT_DESTROYED_FLAG(renderer, retval) \
if (!(renderer) || (renderer)->magic != &SDL_renderer_magic) { \
SDL_InvalidParamError("renderer"); \
return retval; \
#define CHECK_RENDERER_MAGIC_BUT_NOT_DESTROYED_FLAG(renderer, retval) \
if (!SDL_ObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER)) { \
SDL_InvalidParamError("renderer"); \
return retval; \
}
#define CHECK_RENDERER_MAGIC(renderer, retval) \
@ -60,7 +60,7 @@ this should probably be removed at some point in the future. --ryan. */
}
#define CHECK_TEXTURE_MAGIC(texture, retval) \
if (!(texture) || (texture)->magic != &SDL_texture_magic) { \
if (!SDL_ObjectValid(texture, SDL_OBJECT_TYPE_TEXTURE)) { \
SDL_InvalidParamError("texture"); \
return retval; \
}
@ -133,9 +133,6 @@ static const SDL_RenderDriver *render_drivers[] = {
};
#endif /* !SDL_RENDER_DISABLED */
char SDL_renderer_magic;
char SDL_texture_magic;
int SDL_AddSupportedTextureFormat(SDL_Renderer *renderer, SDL_PixelFormatEnum format)
{
@ -946,7 +943,7 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
return NULL;
}
renderer->magic = &SDL_renderer_magic;
SDL_SetObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER, SDL_TRUE);
#ifdef SDL_PLATFORM_ANDROID
Android_ActivityMutex_Lock_Running();
@ -1007,7 +1004,6 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
break; // Yay, we got one!
}
SDL_zerop(renderer); // make sure we don't leave function pointers from a previous CreateRenderer() in this struct.
renderer->magic = &SDL_renderer_magic;
}
}
@ -1021,7 +1017,6 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
VerifyDrawQueueFunctions(renderer);
renderer->magic = &SDL_renderer_magic;
renderer->window = window;
renderer->target_mutex = SDL_CreateMutex();
if (surface) {
@ -1114,6 +1109,8 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
error:
SDL_SetObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER, SDL_FALSE);
#ifdef SDL_PLATFORM_ANDROID
Android_ActivityMutex_Unlock();
#endif
@ -1316,7 +1313,7 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
if (!texture) {
return NULL;
}
texture->magic = &SDL_texture_magic;
SDL_SetObjectValid(texture, SDL_OBJECT_TYPE_TEXTURE, SDL_TRUE);
texture->colorspace = (SDL_Colorspace)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, default_colorspace);
texture->format = format;
texture->access = access;
@ -4496,7 +4493,7 @@ static int SDL_DestroyTextureInternal(SDL_Texture *texture, SDL_bool is_destroyi
renderer->logical_target = NULL;
}
texture->magic = NULL;
SDL_SetObjectValid(texture, SDL_OBJECT_TYPE_TEXTURE, SDL_FALSE);
if (texture->next) {
texture->next->prev = texture->prev;
@ -4596,7 +4593,7 @@ void SDL_DestroyRenderer(SDL_Renderer *renderer)
// in either order.
if (!renderer->destroyed) {
SDL_DestroyRendererWithoutFreeing(renderer);
renderer->magic = NULL; // It's no longer magical...
SDL_SetObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER, SDL_FALSE); // It's no longer magical...
}
SDL_free((void *)renderer->info.texture_formats);

View file

@ -44,8 +44,6 @@ typedef struct SDL_DRect
/* The SDL 2D rendering system */
typedef struct SDL_RenderDriver SDL_RenderDriver;
extern char SDL_renderer_magic;
extern char SDL_texture_magic;
/* Rendering view state */
typedef struct SDL_RenderViewState
@ -62,7 +60,6 @@ typedef struct SDL_RenderViewState
/* Define the SDL texture structure */
struct SDL_Texture
{
const void *magic;
SDL_Colorspace colorspace; /**< The colorspace of the texture */
float SDR_white_point; /**< The SDR white point for this content */
float HDR_headroom; /**< The HDR headroom needed by this content */
@ -160,8 +157,6 @@ typedef enum
/* Define the SDL renderer structure */
struct SDL_Renderer
{
const void *magic;
void (*WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event);
int (*GetOutputSize)(SDL_Renderer *renderer, int *w, int *h);
SDL_bool (*SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode);

View file

@ -26,7 +26,6 @@
#include "../SDL_sysrender.h"
#include "SDL_shaders_gl.h"
#include "../../video/SDL_pixels_c.h"
#include "../../SDL_utils_c.h"
#ifdef SDL_PLATFORM_MACOS
#include <OpenGL/OpenGL.h>

View file

@ -56,13 +56,12 @@ static SDL_AtomicInt SDL_sensor_lock_pending;
static int SDL_sensors_locked;
static SDL_bool SDL_sensors_initialized;
static SDL_Sensor *SDL_sensors SDL_GUARDED_BY(SDL_sensor_lock) = NULL;
static char SDL_sensor_magic;
#define CHECK_SENSOR_MAGIC(sensor, retval) \
if (!sensor || sensor->magic != &SDL_sensor_magic) { \
SDL_InvalidParamError("sensor"); \
SDL_UnlockSensors(); \
return retval; \
#define CHECK_SENSOR_MAGIC(sensor, retval) \
if (!SDL_ObjectValid(sensor, SDL_OBJECT_TYPE_SENSOR)) { \
SDL_InvalidParamError("sensor"); \
SDL_UnlockSensors(); \
return retval; \
}
SDL_bool SDL_SensorsInitialized(void)
@ -327,13 +326,14 @@ SDL_Sensor *SDL_OpenSensor(SDL_SensorID instance_id)
SDL_UnlockSensors();
return NULL;
}
sensor->magic = &SDL_sensor_magic;
SDL_SetObjectValid(sensor, SDL_OBJECT_TYPE_SENSOR, SDL_TRUE);
sensor->driver = driver;
sensor->instance_id = instance_id;
sensor->type = driver->GetDeviceType(device_index);
sensor->non_portable_type = driver->GetDeviceNonPortableType(device_index);
if (driver->Open(sensor, device_index) < 0) {
SDL_SetObjectValid(sensor, SDL_OBJECT_TYPE_SENSOR, SDL_FALSE);
SDL_free(sensor);
SDL_UnlockSensors();
return NULL;
@ -508,6 +508,7 @@ void SDL_CloseSensor(SDL_Sensor *sensor)
sensor->driver->Close(sensor);
sensor->hwdata = NULL;
SDL_SetObjectValid(sensor, SDL_OBJECT_TYPE_SENSOR, SDL_FALSE);
sensorlist = SDL_sensors;
sensorlistprev = NULL;

View file

@ -32,8 +32,6 @@
/* The SDL sensor structure */
struct SDL_Sensor
{
const void *magic _guarded;
SDL_SensorID instance_id _guarded; /* Device instance, monotonically increasing from 0 */
char *name _guarded; /* Sensor name - system dependent */
SDL_SensorType type _guarded; /* Type of the sensor */

View file

@ -37,7 +37,6 @@ typedef struct SDL_WindowData SDL_WindowData;
/* Define the SDL window structure, corresponding to toplevel windows */
struct SDL_Window
{
const void *magic;
SDL_WindowID id;
char *title;
SDL_Surface *icon;
@ -371,7 +370,6 @@ struct SDL_VideoDevice
SDL_Rect desktop_bounds;
SDL_Window *windows;
SDL_Window *grabbed_window;
Uint8 window_magic;
Uint32 clipboard_sequence;
SDL_ClipboardDataCallback clipboard_callback;
SDL_ClipboardCleanupCallback clipboard_cleanup;

View file

@ -141,7 +141,7 @@ static VideoBootStrap *bootstrap[] = {
SDL_UninitializedVideo(); \
return retval; \
} \
if (!(window) || (window)->magic != &_this->window_magic) { \
if (!SDL_ObjectValid(window, SDL_OBJECT_TYPE_WINDOW)) { \
SDL_SetError("Invalid window"); \
return retval; \
}
@ -2118,7 +2118,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
}
}
if ((flags & SDL_WINDOW_MODAL) && (!parent || parent->magic != &_this->window_magic)) {
if ((flags & SDL_WINDOW_MODAL) && !SDL_ObjectValid(parent, SDL_OBJECT_TYPE_WINDOW)) {
SDL_SetError("Modal windows must specify a parent window");
return NULL;
}
@ -2130,7 +2130,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
}
/* Tooltip and popup menu window must specify a parent window */
if (!parent || parent->magic != &_this->window_magic) {
if (!SDL_ObjectValid(parent, SDL_OBJECT_TYPE_WINDOW)) {
SDL_SetError("Tooltip and popup menu windows must specify a parent window");
return NULL;
}
@ -2236,7 +2236,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
if (!window) {
return NULL;
}
window->magic = &_this->window_magic;
SDL_SetObjectValid(window, SDL_OBJECT_TYPE_WINDOW, SDL_TRUE);
window->id = SDL_GetNextObjectID();
window->floating.x = window->windowed.x = window->x = x;
window->floating.y = window->windowed.y = window->y = y;
@ -3920,7 +3920,7 @@ void SDL_DestroyWindow(SDL_Window *window)
}
/* Now invalidate magic */
window->magic = NULL;
SDL_SetObjectValid(window, SDL_OBJECT_TYPE_WINDOW, SDL_FALSE);
/* Free memory associated with the window */
SDL_free(window->title);

View file

@ -1252,7 +1252,7 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
} else if (window->max_aspect && aspect > window->max_aspect) {
wind->requested.pixel_width = SDL_roundf((float)wind->requested.pixel_height * window->max_aspect);
}
wind->requested.logical_width = PixelToPoint(window, wind->requested.pixel_width);
wind->requested.logical_height = PixelToPoint(window, wind->requested.pixel_height);
}
@ -1854,7 +1854,7 @@ static void Wayland_ReleasePopup(SDL_VideoDevice *_this, SDL_Window *popup)
SDL_WindowData *popupdata;
/* Basic sanity checks to weed out the weird popup closures */
if (!popup || popup->magic != &_this->window_magic) {
if (!SDL_ObjectValid(popup, SDL_OBJECT_TYPE_WINDOW)) {
return;
}
popupdata = popup->driverdata;

View file

@ -39,7 +39,6 @@
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_touch_c.h"
#include "../../core/linux/SDL_system_theme.h"
#include "../../SDL_utils_c.h"
#include "../SDL_sysvideo.h"
#include <stdio.h>

View file

@ -28,7 +28,6 @@
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_events_c.h"
#include "../../core/unix/SDL_appid.h"
#include "../../SDL_utils_c.h"
#include "SDL_x11video.h"
#include "SDL_x11mouse.h"