Make sure we always copy the data returned using SDL_GetStringRule

This prevents race conditions where calling an API from one thread returns the data and it's freed by updates on another thread
This commit is contained in:
Sam Lantinga 2024-07-18 15:56:41 -07:00
parent ef884c8aa6
commit bb96320cc4
19 changed files with 66 additions and 71 deletions

View file

@ -296,6 +296,8 @@ extern int SDLCALL SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeout
extern int SDLCALL SDL_WaitConditionTimeoutNS(SDL_Condition *cond, SDL_Mutex *mutex, 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); extern SDL_bool SDLCALL SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS);
extern const char *SDL_CreateTemporaryString(const char *string);
/* Queue `memory` to be passed to SDL_free once the event queue is emptied. /* Queue `memory` to be passed to SDL_free once the event queue is emptied.
this manages the list of pointers to SDL_AllocateEventMemory, but you this manages the list of pointers to SDL_AllocateEventMemory, but you
can use it to queue pointers from other subsystems that can die at any can use it to queue pointers from other subsystems that can die at any

View file

@ -65,7 +65,7 @@ static void SDL_FreePropertyWithCleanup(const void *key, const void *value, void
} }
break; break;
case SDL_PROPERTY_TYPE_STRING: case SDL_PROPERTY_TYPE_STRING:
SDL_FreeLater(property->value.string_value); // this pointer might be given to the app by SDL_GetStringProperty. SDL_FreeLater(property->value.string_value); // SDL_GetStringProperty() returns this pointer
break; break;
default: default:
break; break;

View file

@ -544,8 +544,8 @@ static void DestroyPhysicalAudioDevice(SDL_AudioDevice *device)
SDL_DestroyMutex(device->lock); SDL_DestroyMutex(device->lock);
SDL_DestroyCondition(device->close_cond); SDL_DestroyCondition(device->close_cond);
SDL_free(device->work_buffer); SDL_free(device->work_buffer);
SDL_FreeLater(device->chmap); // this pointer is handed to the app during SDL_GetAudioDeviceChannelMap SDL_free(device->chmap);
SDL_FreeLater(device->name); // this pointer is handed to the app during SDL_GetAudioDeviceName SDL_free(device->name);
SDL_free(device); SDL_free(device);
} }
@ -1432,7 +1432,7 @@ const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
const char *retval = NULL; const char *retval = NULL;
SDL_AudioDevice *device = ObtainPhysicalAudioDevice(devid); SDL_AudioDevice *device = ObtainPhysicalAudioDevice(devid);
if (device) { if (device) {
retval = device->name; retval = SDL_CreateTemporaryString(device->name);
} }
ReleaseAudioDevice(device); ReleaseAudioDevice(device);
@ -1465,8 +1465,8 @@ const int *SDL_GetAudioDeviceChannelMap(SDL_AudioDeviceID devid, int *count)
int channels = 0; int channels = 0;
SDL_AudioDevice *device = ObtainPhysicalAudioDeviceDefaultAllowed(devid); SDL_AudioDevice *device = ObtainPhysicalAudioDeviceDefaultAllowed(devid);
if (device) { if (device) {
retval = device->chmap;
channels = device->spec.channels; channels = device->spec.channels;
retval = SDL_FreeLater(SDL_ChannelMapDup(device->chmap, channels));
} }
ReleaseAudioDevice(device); ReleaseAudioDevice(device);

View file

@ -565,7 +565,7 @@ int SDL_SetAudioStreamFormat(SDL_AudioStream *stream, const SDL_AudioSpec *src_s
if (src_spec) { if (src_spec) {
if (src_spec->channels != stream->src_spec.channels) { if (src_spec->channels != stream->src_spec.channels) {
SDL_FreeLater(stream->src_chmap); // this pointer is handed to the app during SDL_GetAudioStreamInputChannelMap SDL_free(stream->src_chmap);
stream->src_chmap = NULL; stream->src_chmap = NULL;
} }
SDL_copyp(&stream->src_spec, src_spec); SDL_copyp(&stream->src_spec, src_spec);
@ -573,7 +573,7 @@ int SDL_SetAudioStreamFormat(SDL_AudioStream *stream, const SDL_AudioSpec *src_s
if (dst_spec) { if (dst_spec) {
if (dst_spec->channels != stream->dst_spec.channels) { if (dst_spec->channels != stream->dst_spec.channels) {
SDL_FreeLater(stream->dst_chmap); // this pointer is handed to the app during SDL_GetAudioStreamInputChannelMap SDL_free(stream->dst_chmap);
stream->dst_chmap = NULL; stream->dst_chmap = NULL;
} }
SDL_copyp(&stream->dst_spec, dst_spec); SDL_copyp(&stream->dst_spec, dst_spec);
@ -613,11 +613,11 @@ static int SetAudioStreamChannelMap(SDL_AudioStream *stream, const SDL_AudioSpec
if (!dupmap) { if (!dupmap) {
retval = SDL_SetError("Invalid channel mapping"); retval = SDL_SetError("Invalid channel mapping");
} else { } else {
SDL_FreeLater(*stream_chmap); // this pointer is handed to the app during SDL_GetAudioStreamInputChannelMap SDL_free(*stream_chmap);
*stream_chmap = dupmap; *stream_chmap = dupmap;
} }
} else { } else {
SDL_FreeLater(*stream_chmap); // this pointer is handed to the app during SDL_GetAudioStreamInputChannelMap SDL_free(*stream_chmap);
*stream_chmap = NULL; *stream_chmap = NULL;
} }
} }
@ -642,8 +642,8 @@ const int *SDL_GetAudioStreamInputChannelMap(SDL_AudioStream *stream, int *count
int channels = 0; int channels = 0;
if (stream) { if (stream) {
SDL_LockMutex(stream->lock); SDL_LockMutex(stream->lock);
retval = stream->src_chmap;
channels = stream->src_spec.channels; channels = stream->src_spec.channels;
retval = SDL_FreeLater(SDL_ChannelMapDup(stream->src_chmap, channels));
SDL_UnlockMutex(stream->lock); SDL_UnlockMutex(stream->lock);
} }
@ -660,8 +660,8 @@ const int *SDL_GetAudioStreamOutputChannelMap(SDL_AudioStream *stream, int *coun
int channels = 0; int channels = 0;
if (stream) { if (stream) {
SDL_LockMutex(stream->lock); SDL_LockMutex(stream->lock);
retval = stream->dst_chmap;
channels = stream->dst_spec.channels; channels = stream->dst_spec.channels;
retval = SDL_FreeLater(SDL_ChannelMapDup(stream->dst_chmap, channels));
SDL_UnlockMutex(stream->lock); SDL_UnlockMutex(stream->lock);
} }

View file

@ -286,7 +286,7 @@ static void DestroyPhysicalCamera(SDL_Camera *device)
camera_driver.impl.FreeDeviceHandle(device); camera_driver.impl.FreeDeviceHandle(device);
SDL_DestroyMutex(device->lock); SDL_DestroyMutex(device->lock);
SDL_free(device->all_specs); SDL_free(device->all_specs);
SDL_FreeLater(device->name); // this is returned in SDL_GetCameraName. SDL_free(device->name);
SDL_free(device); SDL_free(device);
} }
} }
@ -674,10 +674,10 @@ int SDL_GetCameraFormat(SDL_Camera *camera, SDL_CameraSpec *spec)
const char *SDL_GetCameraName(SDL_CameraID instance_id) const char *SDL_GetCameraName(SDL_CameraID instance_id)
{ {
char *retval = NULL; const char *retval = NULL;
SDL_Camera *device = ObtainPhysicalCamera(instance_id); SDL_Camera *device = ObtainPhysicalCamera(instance_id);
if (device) { if (device) {
retval = device->name; retval = SDL_CreateTemporaryString(device->name);
ReleaseCamera(device); ReleaseCamera(device);
} }
return retval; return retval;

View file

@ -59,13 +59,13 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
event.type = evtype; event.type = evtype;
event.common.timestamp = 0; event.common.timestamp = 0;
if (source) { if (source) {
event.drop.source = SDL_AllocateEventString(source); event.drop.source = SDL_CreateTemporaryString(source);
if (!event.drop.source) { if (!event.drop.source) {
return 0; return 0;
} }
} }
if (data) { if (data) {
event.drop.data = SDL_AllocateEventString(data); event.drop.data = SDL_CreateTemporaryString(data);
if (!event.drop.data) { if (!event.drop.data) {
return 0; return 0;
} }

View file

@ -290,7 +290,7 @@ void *SDL_AllocateEventMemory(size_t size)
return SDL_FreeLater(SDL_malloc(size)); return SDL_FreeLater(SDL_malloc(size));
} }
const char *SDL_AllocateEventString(const char *string) const char *SDL_CreateTemporaryString(const char *string)
{ {
if (string) { if (string) {
return SDL_FreeLater(SDL_strdup(string)); return SDL_FreeLater(SDL_strdup(string));

View file

@ -40,8 +40,6 @@ extern int SDL_StartEventLoop(void);
extern void SDL_StopEventLoop(void); extern void SDL_StopEventLoop(void);
extern void SDL_QuitInterrupt(void); extern void SDL_QuitInterrupt(void);
extern const char *SDL_AllocateEventString(const char *string);
extern int SDL_SendAppEvent(SDL_EventType eventType); extern int SDL_SendAppEvent(SDL_EventType eventType);
extern int SDL_SendKeymapChangedEvent(void); extern int SDL_SendKeymapChangedEvent(void);
extern int SDL_SendLocaleChangedEvent(void); extern int SDL_SendLocaleChangedEvent(void);

View file

@ -156,7 +156,7 @@ void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID, SDL_bool send_event)
return; return;
} }
SDL_FreeLater(SDL_keyboards[keyboard_index].name); SDL_free(SDL_keyboards[keyboard_index].name);
if (keyboard_index != SDL_keyboard_count - 1) { if (keyboard_index != SDL_keyboard_count - 1) {
SDL_memcpy(&SDL_keyboards[keyboard_index], &SDL_keyboards[keyboard_index + 1], (SDL_keyboard_count - keyboard_index - 1) * sizeof(SDL_keyboards[keyboard_index])); SDL_memcpy(&SDL_keyboards[keyboard_index], &SDL_keyboards[keyboard_index + 1], (SDL_keyboard_count - keyboard_index - 1) * sizeof(SDL_keyboards[keyboard_index]));
@ -207,7 +207,7 @@ const char *SDL_GetKeyboardNameForID(SDL_KeyboardID instance_id)
if (keyboard_index < 0) { if (keyboard_index < 0) {
return NULL; return NULL;
} }
return SDL_keyboards[keyboard_index].name; return SDL_CreateTemporaryString(SDL_keyboards[keyboard_index].name);
} }
void SDL_ResetKeyboard(void) void SDL_ResetKeyboard(void)
@ -719,7 +719,7 @@ int SDL_SendKeyboardText(const char *text)
event.type = SDL_EVENT_TEXT_INPUT; event.type = SDL_EVENT_TEXT_INPUT;
event.common.timestamp = 0; event.common.timestamp = 0;
event.text.windowID = keyboard->focus ? keyboard->focus->id : 0; event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
event.text.text = SDL_AllocateEventString(text); event.text.text = SDL_CreateTemporaryString(text);
if (!event.text.text) { if (!event.text.text) {
return 0; return 0;
} }
@ -751,7 +751,7 @@ int SDL_SendEditingText(const char *text, int start, int length)
event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0; event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0;
event.edit.start = start; event.edit.start = start;
event.edit.length = length; event.edit.length = length;
event.edit.text = SDL_AllocateEventString(text); event.edit.text = SDL_CreateTemporaryString(text);
if (!event.edit.text) { if (!event.edit.text) {
return 0; return 0;
} }
@ -783,7 +783,7 @@ int SDL_SendEditingTextCandidates(char **candidates, int num_candidates, int sel
return 0; return 0;
} }
for (int i = 0; i < num_candidates; ++i) { for (int i = 0; i < num_candidates; ++i) {
event_candidates[i] = SDL_AllocateEventString(candidates[i]); event_candidates[i] = SDL_CreateTemporaryString(candidates[i]);
} }
event_candidates[num_candidates] = NULL; event_candidates[num_candidates] = NULL;
event.edit_candidates.candidates = event_candidates; event.edit_candidates.candidates = event_candidates;

View file

@ -1017,7 +1017,7 @@ const char *SDL_GetKeyName(SDL_Keycode key)
end = SDL_UCS4ToUTF8(key, name); end = SDL_UCS4ToUTF8(key, name);
*end = '\0'; *end = '\0';
return SDL_FreeLater(SDL_strdup(name)); return SDL_CreateTemporaryString(name);
} }
} }

View file

@ -312,7 +312,7 @@ void SDL_RemoveMouse(SDL_MouseID mouseID, SDL_bool send_event)
return; return;
} }
SDL_FreeLater(SDL_mice[mouse_index].name); // SDL_GetMouseNameForID returns this pointer. SDL_free(SDL_mice[mouse_index].name);
if (mouse_index != SDL_mouse_count - 1) { if (mouse_index != SDL_mouse_count - 1) {
SDL_memcpy(&SDL_mice[mouse_index], &SDL_mice[mouse_index + 1], (SDL_mouse_count - mouse_index - 1) * sizeof(SDL_mice[mouse_index])); SDL_memcpy(&SDL_mice[mouse_index], &SDL_mice[mouse_index + 1], (SDL_mouse_count - mouse_index - 1) * sizeof(SDL_mice[mouse_index]));
@ -376,7 +376,7 @@ const char *SDL_GetMouseNameForID(SDL_MouseID instance_id)
if (mouse_index < 0) { if (mouse_index < 0) {
return NULL; return NULL;
} }
return SDL_mice[mouse_index].name; return SDL_CreateTemporaryString(SDL_mice[mouse_index].name);
} }
void SDL_SetDefaultCursor(SDL_Cursor *cursor) void SDL_SetDefaultCursor(SDL_Cursor *cursor)

View file

@ -102,7 +102,10 @@ SDL_Touch *SDL_GetTouch(SDL_TouchID id)
const char *SDL_GetTouchDeviceName(SDL_TouchID id) const char *SDL_GetTouchDeviceName(SDL_TouchID id)
{ {
SDL_Touch *touch = SDL_GetTouch(id); SDL_Touch *touch = SDL_GetTouch(id);
return touch ? touch->name : NULL; if (!touch) {
return NULL;
}
return SDL_CreateTemporaryString(touch->name);
} }
SDL_TouchDeviceType SDL_GetTouchDeviceType(SDL_TouchID id) SDL_TouchDeviceType SDL_GetTouchDeviceType(SDL_TouchID id)
@ -493,7 +496,7 @@ void SDL_DelTouch(SDL_TouchID id)
SDL_free(touch->fingers[i]); SDL_free(touch->fingers[i]);
} }
SDL_free(touch->fingers); SDL_free(touch->fingers);
SDL_FreeLater(touch->name); // this pointer might be given to the app by SDL_GetTouchDeviceName. SDL_free(touch->name);
SDL_free(touch); SDL_free(touch);
SDL_num_touch--; SDL_num_touch--;

View file

@ -383,8 +383,7 @@ const char * const *SDL_InternalGlobDirectory(const char *path, const char *patt
SDL_free(folded); SDL_free(folded);
SDL_free(pathcpy); SDL_free(pathcpy);
SDL_FreeLater(retval); return SDL_FreeLater(retval);
return (const char * const *) retval;
} }
static int GlobDirectoryGetPathInfo(const char *path, SDL_PathInfo *info, void *userdata) static int GlobDirectoryGetPathInfo(const char *path, SDL_PathInfo *info, void *userdata)
@ -435,10 +434,7 @@ const char *SDL_GetUserFolder(SDL_Folder folder)
const char *SDL_GetPrefPath(const char *org, const char *app) const char *SDL_GetPrefPath(const char *org, const char *app)
{ {
char *path = SDL_SYS_GetPrefPath(org, app); char *path = SDL_SYS_GetPrefPath(org, app);
if (path) { return SDL_FreeLater(path);
SDL_FreeLater(path);
}
return path;
} }

View file

@ -100,7 +100,7 @@ const char *SDL_GetHapticNameForID(SDL_HapticID instance_id)
if (SDL_GetHapticIndex(instance_id, &device_index)) { if (SDL_GetHapticIndex(instance_id, &device_index)) {
name = SDL_SYS_HapticName(device_index); name = SDL_SYS_HapticName(device_index);
} }
return name ? SDL_FreeLater(SDL_strdup(name)) : NULL; return SDL_CreateTemporaryString(name);
} }
SDL_Haptic *SDL_OpenHaptic(SDL_HapticID instance_id) SDL_Haptic *SDL_OpenHaptic(SDL_HapticID instance_id)
@ -187,9 +187,9 @@ SDL_HapticID SDL_GetHapticID(SDL_Haptic *haptic)
const char *SDL_GetHapticName(SDL_Haptic *haptic) const char *SDL_GetHapticName(SDL_Haptic *haptic)
{ {
CHECK_HAPTIC_MAGIC(haptic, 0); CHECK_HAPTIC_MAGIC(haptic, NULL);
return haptic->name; return SDL_CreateTemporaryString(haptic->name);
} }
SDL_bool SDL_IsMouseHaptic(void) SDL_bool SDL_IsMouseHaptic(void)
@ -336,7 +336,7 @@ void SDL_CloseHaptic(SDL_Haptic *haptic)
} }
/* Free the data associated with this device */ /* Free the data associated with this device */
SDL_FreeLater(haptic->name); // this pointer is handed to the app in SDL_GetHapticName() SDL_free(haptic->name);
SDL_free(haptic); SDL_free(haptic);
} }

View file

@ -1600,7 +1600,7 @@ static GamepadMapping_t *SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, co
/* Only overwrite the mapping if the priority is the same or higher. */ /* Only overwrite the mapping if the priority is the same or higher. */
if (pGamepadMapping->priority <= priority) { if (pGamepadMapping->priority <= priority) {
/* Update existing mapping */ /* Update existing mapping */
SDL_FreeLater(pGamepadMapping->name); // this is returned in SDL_GetGamepadName. SDL_free(pGamepadMapping->name);
pGamepadMapping->name = pchName; pGamepadMapping->name = pchName;
SDL_free(pGamepadMapping->mapping); SDL_free(pGamepadMapping->mapping);
pGamepadMapping->mapping = pchMapping; pGamepadMapping->mapping = pchMapping;
@ -2198,8 +2198,7 @@ const char * const *SDL_GetGamepadMappings(int *count)
SDL_free(mappings); SDL_free(mappings);
} }
SDL_FreeLater(retval); return SDL_FreeLater(retval);
return (const char * const *) retval;
} }
/* /*
@ -2221,8 +2220,7 @@ const char *SDL_GetGamepadMappingForGUID(SDL_JoystickGUID guid)
} }
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
SDL_FreeLater(retval); return SDL_FreeLater(retval);
return retval;
} }
/* /*
@ -2240,8 +2238,7 @@ const char *SDL_GetGamepadMapping(SDL_Gamepad *gamepad)
} }
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
SDL_FreeLater(retval); return SDL_FreeLater(retval);
return retval;
} }
/* /*
@ -2434,7 +2431,7 @@ const char *SDL_GetGamepadNameForID(SDL_JoystickID instance_id)
if (SDL_strcmp(mapping->name, "*") == 0) { if (SDL_strcmp(mapping->name, "*") == 0) {
retval = SDL_GetJoystickNameForID(instance_id); retval = SDL_GetJoystickNameForID(instance_id);
} else { } else {
retval = mapping->name; retval = SDL_CreateTemporaryString(mapping->name);
} }
} }
} }
@ -2538,8 +2535,7 @@ const char *SDL_GetGamepadMappingForID(SDL_JoystickID instance_id)
} }
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
SDL_FreeLater(retval); return SDL_FreeLater(retval);
return retval;
} }
/* /*
@ -3314,7 +3310,7 @@ const char *SDL_GetGamepadName(SDL_Gamepad *gamepad)
gamepad->joystick->steam_handle != 0) { gamepad->joystick->steam_handle != 0) {
retval = SDL_GetJoystickName(gamepad->joystick); retval = SDL_GetJoystickName(gamepad->joystick);
} else { } else {
retval = gamepad->name; retval = SDL_CreateTemporaryString(gamepad->name);
} }
} }
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
@ -3707,7 +3703,7 @@ void SDL_QuitGamepadMappings(void)
while (s_pSupportedGamepads) { while (s_pSupportedGamepads) {
pGamepadMap = s_pSupportedGamepads; pGamepadMap = s_pSupportedGamepads;
s_pSupportedGamepads = s_pSupportedGamepads->next; s_pSupportedGamepads = s_pSupportedGamepads->next;
SDL_FreeLater(pGamepadMap->name); // this is returned in SDL_GetGamepadName. SDL_free(pGamepadMap->name);
SDL_free(pGamepadMap->mapping); SDL_free(pGamepadMap->mapping);
SDL_free(pGamepadMap); SDL_free(pGamepadMap);
} }

View file

@ -780,13 +780,13 @@ const char *SDL_GetJoystickNameForID(SDL_JoystickID instance_id)
SDL_LockJoysticks(); SDL_LockJoysticks();
info = SDL_GetJoystickVirtualGamepadInfoForID(instance_id); info = SDL_GetJoystickVirtualGamepadInfoForID(instance_id);
if (info) { if (info) {
name = info->name; name = SDL_CreateTemporaryString(info->name);
} else if (SDL_GetDriverAndJoystickIndex(instance_id, &driver, &device_index)) { } else if (SDL_GetDriverAndJoystickIndex(instance_id, &driver, &device_index)) {
name = driver->GetDeviceName(device_index); name = SDL_CreateTemporaryString(driver->GetDeviceName(device_index));
} }
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
return name ? SDL_FreeLater(SDL_strdup(name)) : NULL; return name;
} }
/* /*
@ -800,14 +800,14 @@ const char *SDL_GetJoystickPathForID(SDL_JoystickID instance_id)
SDL_LockJoysticks(); SDL_LockJoysticks();
if (SDL_GetDriverAndJoystickIndex(instance_id, &driver, &device_index)) { if (SDL_GetDriverAndJoystickIndex(instance_id, &driver, &device_index)) {
path = driver->GetDevicePath(device_index); path = SDL_CreateTemporaryString(driver->GetDevicePath(device_index));
} }
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
if (!path) { if (!path) {
SDL_Unsupported(); SDL_Unsupported();
} }
return path ? SDL_FreeLater(SDL_strdup(path)) : NULL; return path;
} }
/* /*
@ -1653,9 +1653,9 @@ const char *SDL_GetJoystickName(SDL_Joystick *joystick)
info = SDL_GetJoystickVirtualGamepadInfoForID(joystick->instance_id); info = SDL_GetJoystickVirtualGamepadInfoForID(joystick->instance_id);
if (info) { if (info) {
retval = info->name; retval = SDL_CreateTemporaryString(info->name);
} else { } else {
retval = joystick->name; retval = SDL_CreateTemporaryString(joystick->name);
} }
} }
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
@ -1675,7 +1675,7 @@ const char *SDL_GetJoystickPath(SDL_Joystick *joystick)
CHECK_JOYSTICK_MAGIC(joystick, NULL); CHECK_JOYSTICK_MAGIC(joystick, NULL);
if (joystick->path) { if (joystick->path) {
retval = joystick->path; retval = SDL_CreateTemporaryString(joystick->path);
} else { } else {
SDL_Unsupported(); SDL_Unsupported();
retval = NULL; retval = NULL;
@ -1884,9 +1884,9 @@ void SDL_CloseJoystick(SDL_Joystick *joystick)
} }
/* Free the data associated with this joystick */ /* Free the data associated with this joystick */
SDL_FreeLater(joystick->name); // SDL_GetJoystickName returns this pointer. SDL_free(joystick->name);
SDL_FreeLater(joystick->path); // SDL_GetJoystickPath returns this pointer. SDL_free(joystick->path);
SDL_FreeLater(joystick->serial); // SDL_GetJoystickSerial returns this pointer. SDL_free(joystick->serial);
SDL_free(joystick->axes); SDL_free(joystick->axes);
SDL_free(joystick->balls); SDL_free(joystick->balls);
SDL_free(joystick->hats); SDL_free(joystick->hats);
@ -3431,7 +3431,7 @@ const char *SDL_GetJoystickSerial(SDL_Joystick *joystick)
{ {
CHECK_JOYSTICK_MAGIC(joystick, NULL); CHECK_JOYSTICK_MAGIC(joystick, NULL);
retval = joystick->serial; retval = SDL_CreateTemporaryString(joystick->serial);
} }
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();

View file

@ -246,11 +246,11 @@ const char *SDL_GetSensorNameForID(SDL_SensorID instance_id)
SDL_LockSensors(); SDL_LockSensors();
if (SDL_GetDriverAndSensorIndex(instance_id, &driver, &device_index)) { if (SDL_GetDriverAndSensorIndex(instance_id, &driver, &device_index)) {
name = driver->GetDeviceName(device_index); name = SDL_CreateTemporaryString(driver->GetDeviceName(device_index));
} }
SDL_UnlockSensors(); SDL_UnlockSensors();
return name ? SDL_FreeLater(SDL_strdup(name)) : NULL; return name;
} }
SDL_SensorType SDL_GetSensorTypeForID(SDL_SensorID instance_id) SDL_SensorType SDL_GetSensorTypeForID(SDL_SensorID instance_id)
@ -407,7 +407,7 @@ const char *SDL_GetSensorName(SDL_Sensor *sensor)
{ {
CHECK_SENSOR_MAGIC(sensor, NULL); CHECK_SENSOR_MAGIC(sensor, NULL);
retval = sensor->name; retval = SDL_CreateTemporaryString(sensor->name);
} }
SDL_UnlockSensors(); SDL_UnlockSensors();
@ -526,7 +526,7 @@ void SDL_CloseSensor(SDL_Sensor *sensor)
} }
/* Free the data associated with this sensor */ /* Free the data associated with this sensor */
SDL_FreeLater(sensor->name); // this pointer gets handed to the app by SDL_GetSensorName(). SDL_free(sensor->name);
SDL_free(sensor); SDL_free(sensor);
} }
SDL_UnlockSensors(); SDL_UnlockSensors();

View file

@ -329,7 +329,7 @@ void SDL_RunThread(SDL_Thread *thread)
if (!SDL_AtomicCompareAndSwap(&thread->state, SDL_THREAD_STATE_ALIVE, SDL_THREAD_STATE_ZOMBIE)) { if (!SDL_AtomicCompareAndSwap(&thread->state, SDL_THREAD_STATE_ALIVE, SDL_THREAD_STATE_ZOMBIE)) {
/* Clean up if something already detached us. */ /* Clean up if something already detached us. */
if (SDL_AtomicCompareAndSwap(&thread->state, SDL_THREAD_STATE_DETACHED, SDL_THREAD_STATE_CLEANED)) { if (SDL_AtomicCompareAndSwap(&thread->state, SDL_THREAD_STATE_DETACHED, SDL_THREAD_STATE_CLEANED)) {
SDL_FreeLater(thread->name); SDL_free(thread->name); /* Can't free later, we've already cleaned up TLS */
SDL_free(thread); SDL_free(thread);
} }
} }

View file

@ -349,7 +349,7 @@ int SDL_SetPrimarySelectionText(const char *text)
return -1; return -1;
} }
} else { } else {
SDL_FreeLater(_this->primary_selection_text); // this pointer might be given to the app by SDL_GetPrimarySelectionText. SDL_FreeLater(_this->primary_selection_text); // SDL_GetPrimarySelectionText() returns this pointer.
_this->primary_selection_text = SDL_strdup(text); _this->primary_selection_text = SDL_strdup(text);
} }