From 661ecf42c3780aef85b18aee3a659dcd10ffb540 Mon Sep 17 00:00:00 2001 From: nfore Date: Sat, 1 Apr 2023 12:11:35 -0500 Subject: [PATCH] Avoid malloc & memcpy in retro_serialize --- libretro.cpp | 22 +++++++++++++--------- mednafen/state.c | 11 ++++++++++- mednafen/state.h | 1 + 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/libretro.cpp b/libretro.cpp index 005e2c4..6613c5c 100644 --- a/libretro.cpp +++ b/libretro.cpp @@ -2529,6 +2529,7 @@ size_t retro_serialize_size(void) StateMem st; st.data = NULL; + st.data_frontend = NULL; st.loc = 0; st.len = 0; st.malloced = 0; @@ -2546,22 +2547,24 @@ bool retro_serialize(void *data, size_t size) { StateMem st; bool ret = false; - uint8_t *_dat = (uint8_t*)malloc(size); - if (!_dat) - return false; - - /* Mednafen can realloc the buffer so we need to ensure this is safe. */ - st.data = _dat; + st.data_frontend = (uint8_t *)data; + st.data = st.data_frontend; st.loc = 0; st.len = 0; st.malloced = size; st.initial_malloc = 0; + /* MDFNSS_SaveSM will malloc separate memory for st.data to complete + * the save if the passed-in size is too small */ ret = MDFNSS_SaveSM(&st, 0, 0, NULL, NULL, NULL); - memcpy(data, st.data, size); - free(st.data); + if (st.data != st.data_frontend) + { + log_cb(RETRO_LOG_WARN, "Save state size has increased\n"); + free(st.data); + ret = false; + } return ret; } @@ -2570,7 +2573,8 @@ bool retro_unserialize(const void *data, size_t size) { StateMem st; - st.data = (uint8_t*)data; + st.data_frontend = (uint8_t *)data; + st.data = st.data_frontend; st.loc = 0; st.len = size; st.malloced = 0; diff --git a/mednafen/state.c b/mednafen/state.c index 110446d..e471761 100644 --- a/mednafen/state.c +++ b/mednafen/state.c @@ -54,7 +54,16 @@ static int32_t smem_write(StateMem *st, void *buffer, uint32_t len) while(newsize < (len + st->loc)) newsize *= 2; - st->data = (uint8_t *)realloc(st->data, newsize); + + /* Don't realloc data_frontend memory */ + if (st->data == st->data_frontend && st->data != NULL ) + { + st->data = (uint8_t *)malloc(newsize); + memcpy(st->data, st->data_frontend, st->malloced); + } + else + st->data = (uint8_t *)realloc(st->data, newsize); + st->malloced = newsize; } memcpy(st->data + st->loc, buffer, len); diff --git a/mednafen/state.h b/mednafen/state.h index eca11b2..49689ad 100644 --- a/mednafen/state.h +++ b/mednafen/state.h @@ -17,6 +17,7 @@ typedef struct { uint8_t *data; + uint8_t *data_frontend; /* never realloc'd */ uint32_t loc; uint32_t len; uint32_t malloced;