Skip to content

Commit c0f6fc4

Browse files
committed
tasks/autodetect: replace needless strdup of device_info.name with stack buffer
input_autoconfigure_connect_handler has a block that temporarily overwrites autoconfig_handle->device_info.name with a fallback-driver name (e.g. 'XInput Controller' / 'Standard Gamepad'), re-runs the scan, then restores the original. It saved the original name via char *name_backup = strdup(autoconfig_handle->device_info.name); and free()d it after the restore. Two problems with that: 1. device_info.name is a fixed-size char[128] ivar on input_device_info_t (input/input_driver.h:334), not a heap pointer. Heap allocation and free are unnecessary; a stack buffer sized from sizeof(device_info.name) does the job with zero allocator traffic. 2. strdup returning NULL was not checked. If the malloc failed, the subsequent strlcpy(device_info.name, name_backup, ...) would call strlcpy with src=NULL, which is undefined behaviour and on glibc / Bionic / musl will segfault inside strlen. Fix: declare 'char name_backup[sizeof(autoconfig_handle->device_info.name)]' on the stack right where the old strdup was, copy into it with strlcpy, and drop the manual free / NULL-assign at the end of the block. No heap allocation, no OOM failure mode. Thread-safety: unchanged. input_autoconfigure_connect_handler runs on the task worker thread; device_info is owned by autoconfig_handle which is the task's state struct. The name_backup buffer is a short-lived local; nothing else accesses it. Scope: this runs once per input device connection (low frequency event), so the fix is correctness-focused, not a performance improvement. Same pattern as the savestate-thumbnail fixes in 93449d3 / 741ead4 (needless strdup of fixed-size char[] ivars).
1 parent aeaaa23 commit c0f6fc4

1 file changed

Lines changed: 12 additions & 4 deletions

File tree

tasks/task_autodetect.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,18 @@ static void input_autoconfigure_connect_handler(retro_task_t *task)
756756
&& !string_is_equal(autoconfig_handle->device_info.name,
757757
fallback_device_name))
758758
{
759-
char *name_backup = strdup(autoconfig_handle->device_info.name);
759+
/* Save/restore device_info.name around the fallback-name
760+
* autoconfig scan. device_info.name is a fixed-size
761+
* char[128] ivar, not a heap pointer, so the previous
762+
* strdup + free was unnecessary heap traffic, and carried
763+
* a NULL-deref-on-OOM failure mode (strdup returning NULL
764+
* was not checked before strlcpy(name, name_backup, ...)
765+
* below). A stack buffer of matching size sidesteps both
766+
* issues. */
767+
char name_backup[sizeof(autoconfig_handle->device_info.name)];
768+
769+
strlcpy(name_backup, autoconfig_handle->device_info.name,
770+
sizeof(name_backup));
760771

761772
strlcpy(autoconfig_handle->device_info.name,
762773
fallback_device_name,
@@ -771,9 +782,6 @@ static void input_autoconfigure_connect_handler(retro_task_t *task)
771782
strlcpy(autoconfig_handle->device_info.name,
772783
name_backup,
773784
sizeof(autoconfig_handle->device_info.name));
774-
775-
free(name_backup);
776-
name_backup = NULL;
777785
}
778786
}
779787

0 commit comments

Comments
 (0)