Skip to content

Commit 6e17be0

Browse files
committed
task_save_handler improvements:
1. Division by zero: early return when size <= 0 or data is NULL, avoiding the divide and handling the degenerate case cleanly 2. Separated cancellation from write failure: cancel just cleans up silently, write failure still reports the error — these are different situations 3. Eliminated unnecessary allocations: the old code did strdup into msg, then conditionally passed it to task_set_title, then freed it if unused. Now strdup only happens inside the !MUTE branch, so every allocation is consumed by task_set_title directly 4. Stack buffers scoped tighter: char msg[128] only lives in the blocks that need it, not across the whole trailing portion of the function 5. Removed dead write path: the old code skipped the intfstream_write when data was NULL but still checked written != remaining, which would always trigger the error path with written=0. Now that case is handled by the early return
1 parent 9dc9d16 commit 6e17be0

File tree

1 file changed

+38
-34
lines changed

1 file changed

+38
-34
lines changed

tasks/task_save.c

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,6 @@ static void task_save_handler(retro_task_t *task)
518518
state->file = intfstream_open_file(
519519
state->path, RETRO_VFS_FILE_ACCESS_WRITE,
520520
RETRO_VFS_FILE_ACCESS_HINT_NONE);
521-
522521
if (!state->file)
523522
return;
524523
}
@@ -530,23 +529,34 @@ static void task_save_handler(retro_task_t *task)
530529
state->size = (ssize_t)_len;
531530
}
532531

533-
remaining = MIN(state->size - state->written, SAVE_STATE_CHUNK);
534-
535-
if (state->data)
532+
/* Nothing to write - finish immediately */
533+
if (state->size <= 0 || !state->data)
536534
{
537-
written = (int)intfstream_write(state->file,
538-
(uint8_t*)state->data + state->written, remaining);
539-
state->written += written;
535+
task_set_progress(task, 100);
536+
task_save_handler_finished(task, state);
537+
return;
540538
}
541539

540+
remaining = MIN(state->size - state->written, SAVE_STATE_CHUNK);
541+
written = (int)intfstream_write(state->file,
542+
(uint8_t*)state->data + state->written, remaining);
543+
state->written += written;
544+
542545
task_set_progress(task, (state->written / (float)state->size) * 100);
543546

544547
flg = task_get_flags(task);
545548

546-
if (((flg & RETRO_TASK_FLG_CANCELLED) > 0) || written != remaining)
549+
if ((flg & RETRO_TASK_FLG_CANCELLED) > 0)
547550
{
548-
char msg[128];
551+
/* Cancellation - no error message, just clean up */
552+
task_save_handler_finished(task, state);
553+
return;
554+
}
549555

556+
if (written != remaining)
557+
{
558+
/* Write failure */
559+
char msg[128];
550560
if (state->flags & SAVE_TASK_FLAG_UNDO_SAVE)
551561
{
552562
const char *failed_undo_str = msg_hash_to_str(
@@ -564,39 +574,33 @@ static void task_save_handler(retro_task_t *task)
564574
msg[++_len] = '\0';
565575
strlcpy(msg + _len, state->path, sizeof(msg) - _len);
566576
}
567-
568577
task_set_error(task, strdup(msg));
569578
task_save_handler_finished(task, state);
579+
return;
570580
}
571-
else if (state->written == state->size)
572-
{
573-
char *msg = NULL;
574581

582+
if (state->written == state->size)
583+
{
584+
/* Save complete - set title directly, no intermediate allocation */
575585
task_free_title(task);
576-
577-
if (state->flags & SAVE_TASK_FLAG_UNDO_SAVE)
578-
msg = strdup(msg_hash_to_str(MSG_RESTORED_OLD_SAVE_STATE));
579-
else if (state->state_slot < 0)
580-
msg = strdup(msg_hash_to_str(MSG_SAVED_STATE_TO_SLOT_AUTO));
581-
else
582-
{
583-
char new_msg[128];
584-
snprintf(new_msg, sizeof(new_msg),
585-
msg_hash_to_str(MSG_SAVED_STATE_TO_SLOT),
586-
state->state_slot);
587-
msg = strdup(new_msg);
588-
}
589-
590-
if (!((flg & RETRO_TASK_FLG_MUTE) > 0) && msg)
586+
if (!((flg & RETRO_TASK_FLG_MUTE) > 0))
591587
{
592-
task_set_title(task, msg);
593-
msg = NULL;
588+
if (state->flags & SAVE_TASK_FLAG_UNDO_SAVE)
589+
task_set_title(task, strdup(msg_hash_to_str(
590+
MSG_RESTORED_OLD_SAVE_STATE)));
591+
else if (state->state_slot < 0)
592+
task_set_title(task, strdup(msg_hash_to_str(
593+
MSG_SAVED_STATE_TO_SLOT_AUTO)));
594+
else
595+
{
596+
char msg[128];
597+
snprintf(msg, sizeof(msg),
598+
msg_hash_to_str(MSG_SAVED_STATE_TO_SLOT),
599+
state->state_slot);
600+
task_set_title(task, strdup(msg));
601+
}
594602
}
595-
596603
task_save_handler_finished(task, state);
597-
598-
if (!string_is_empty(msg))
599-
free(msg);
600604
}
601605
}
602606

0 commit comments

Comments
 (0)