[client] fixes #135, double free crash

This commit is contained in:
Geoffrey McRae 2019-02-25 05:43:18 +11:00
parent dbd09a431a
commit 4f8fa6e7aa

View File

@ -40,6 +40,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "KVMFR.h" #include "KVMFR.h"
#include "spice/spice.h" #include "spice/spice.h"
#include "kb.h" #include "kb.h"
#include "ll.h"
#include "lg-renderers.h" #include "lg-renderers.h"
#include "lg-clipboards.h" #include "lg-clipboards.h"
@ -65,8 +66,7 @@ struct AppState
const LG_Clipboard * lgc; const LG_Clipboard * lgc;
SpiceDataType cbType; SpiceDataType cbType;
LG_ClipboardReplyFn cbReplyFn; struct ll * cbRequestList;
void * cbReplyData;
SDL_Window * window; SDL_Window * window;
int shmFD; int shmFD;
@ -150,6 +150,13 @@ struct AppParams params =
.forceRenderer = false .forceRenderer = false
}; };
struct CBRequest
{
SpiceDataType type;
LG_ClipboardReplyFn replyFn;
void * opaque;
};
static void updatePositionInfo() static void updatePositionInfo()
{ {
if (state.haveSrcSize) if (state.haveSrcSize)
@ -546,15 +553,21 @@ void clipboardData(const LG_ClipboardData type, uint8_t * data, size_t size)
if (type == LG_CLIPBOARD_DATA_TEXT) if (type == LG_CLIPBOARD_DATA_TEXT)
{ {
// TODO: make this more memory efficent // TODO: make this more memory efficent
size_t newSize = 0;
buffer = malloc(size * 2); buffer = malloc(size * 2);
uint8_t * p = buffer; uint8_t * p = buffer;
for(uint32_t i = 0; i < size; ++i) for(uint32_t i = 0; i < size; ++i)
{ {
uint8_t c = data[i]; uint8_t c = data[i];
if (c == '\n') if (c == '\n')
{
*p++ = '\r'; *p++ = '\r';
*p++ = c; ++newSize;
} }
*p++ = c;
++newSize;
}
size = newSize;
} }
spice_clipboard_data(clipboard_type_to_spice_type(type), buffer, (uint32_t)size); spice_clipboard_data(clipboard_type_to_spice_type(type), buffer, (uint32_t)size);
@ -564,8 +577,12 @@ void clipboardData(const LG_ClipboardData type, uint8_t * data, size_t size)
void clipboardRequest(const LG_ClipboardReplyFn replyFn, void * opaque) void clipboardRequest(const LG_ClipboardReplyFn replyFn, void * opaque)
{ {
state.cbReplyData = opaque; struct CBRequest * cbr = (struct CBRequest *)malloc(sizeof(struct CBRequest()));
state.cbReplyFn = replyFn;
cbr->type = state.cbType;
cbr->replyFn = replyFn;
cbr->opaque = opaque;
ll_push(state.cbRequestList, cbr);
spice_clipboard_request(state.cbType); spice_clipboard_request(state.cbType);
} }
@ -585,15 +602,26 @@ void spiceClipboardData(const SpiceDataType type, uint8_t * buffer, uint32_t siz
{ {
// dos2unix // dos2unix
uint8_t * p = buffer; uint8_t * p = buffer;
uint32_t newSize = size;
for(uint32_t i = 0; i < size; ++i) for(uint32_t i = 0; i < size; ++i)
{ {
uint8_t c = buffer[i]; uint8_t c = buffer[i];
if (c != '\r') if (c == '\r')
{
--newSize;
continue;
}
*p++ = c; *p++ = c;
} }
size = newSize;
} }
state.cbReplyFn(state.cbReplyData, type, buffer, size); struct CBRequest * cbr;
if (ll_shift(state.cbRequestList, (void **)&cbr))
{
cbr->replyFn(cbr->opaque, type, buffer, size);
free(cbr);
}
} }
void spiceClipboardRelease() void spiceClipboardRelease()
@ -1057,6 +1085,8 @@ int run()
DEBUG_WARN("Failed to initialize the clipboard interface, continuing anyway"); DEBUG_WARN("Failed to initialize the clipboard interface, continuing anyway");
state.lgc = NULL; state.lgc = NULL;
} }
state.cbRequestList = ll_new();
} }
SDL_Cursor *cursor = NULL; SDL_Cursor *cursor = NULL;
@ -1228,8 +1258,15 @@ int run()
state.lgr->deinitialize(state.lgrData); state.lgr->deinitialize(state.lgrData);
if (state.lgc) if (state.lgc)
{
state.lgc->free(); state.lgc->free();
struct CBRequest *cbr;
while(ll_shift(state.cbRequestList, (void **)&cbr))
free(cbr);
ll_free(state.cbRequestList);
}
if (state.window) if (state.window)
SDL_DestroyWindow(state.window); SDL_DestroyWindow(state.window);