Skip to content

Commit

Permalink
Fix some memory leaks and premature transfer closure
Browse files Browse the repository at this point in the history
  • Loading branch information
rufferson committed Jan 30, 2020
1 parent 34779d7 commit fbbd4b1
Showing 1 changed file with 58 additions and 42 deletions.
100 changes: 58 additions & 42 deletions src/jabber_http_file_upload.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ typedef struct {
gchar *passwd;
} PurpleHttpURL;


static inline PurpleHttpURL *purple_http_url_parse(const gchar *url) {
PurpleHttpURL *ret = g_new0(PurpleHttpURL, 1);
purple_url_parse(url, &(ret->host), &(ret->port), &(ret->path), &(ret->user), &(ret->passwd));
Expand All @@ -56,24 +55,41 @@ static inline void purple_http_url_free(PurpleHttpURL *phl) { g_free(phl->host);

static void jabber_hfu_http_read(gpointer user_data, PurpleSslConnection *ssl_connection, PurpleInputCondition cond)
{
gchar buf[1024];
PurpleXfer *xfer = user_data;
gchar buf[1024] = {0};

//Read the server buffer
size_t rl = purple_ssl_read(ssl_connection, buf, 1024);
purple_debug_info("jabber_http_upload", "Server file send response was %ld bytes: %s\n", rl, buf);

if(rl == (size_t)-1)
return;

//Flush the server buffer
purple_ssl_read(ssl_connection, buf, 1024);
purple_debug_info("jabber_http_upload", "Server file send response was %s\n", buf);
if ((purple_xfer_get_bytes_sent(xfer)) >= purple_xfer_get_size(xfer)) {
// Looking for HTTP/1.1 201
if(rl > 12 && g_str_has_prefix(buf, "HTTP/1.") && g_str_has_prefix(buf+8, " 20")) {
// 20x statuses are good, should be 201 but who knows those servers
purple_xfer_set_completed(xfer, TRUE);
purple_xfer_end(xfer);
return;
}
}
// We've read everything it seems but didn't understand a word
purple_xfer_cancel_remote(xfer);
g_return_if_reached();
}

static void jabber_hfu_http_send_connect_cb(gpointer data, PurpleSslConnection *ssl_connection, PurpleInputCondition cond)
{
PurpleHttpURL *httpurl;
gchar *headers, *host, *path, *auth = NULL, *expire = NULL, *cookie = NULL;
g_autofree gchar *headers, *auth = NULL, *expire = NULL, *cookie = NULL;

PurpleXfer *xfer = data;
HFUXfer *hfux = purple_xfer_get_protocol_data(xfer);
HFUJabberStreamData *js_data = hfux->js_data;
g_autofree char *filemime = file_get_mime(purple_xfer_get_local_filename(xfer));

httpurl = purple_http_url_parse(hfux->put_url);
path = purple_http_url_get_path(httpurl);

if (str_equal(js_data->ns, NS_HTTP_FILE_UPLOAD_V0)) {
char *a = g_hash_table_lookup(hfux->put_headers, "Authorisation");
Expand All @@ -86,35 +102,30 @@ static void jabber_hfu_http_send_connect_cb(gpointer data, PurpleSslConnection *
if(e)
expire = g_strdup_printf("Expires: %s\r\n", e);
}
host = purple_http_url_get_host(httpurl);


headers = g_strdup_printf("PUT /%s HTTP/1.0\r\n"
"Connection: close\r\n"
"Host: %s\r\n"
"Content-Length: %" G_GSIZE_FORMAT "\r\n"
"Content-Type: application/octet-stream\r\n"
"Content-Type: %s\r\n"
"User-Agent: libpurple\r\n"
"%s%s%s\r\n",
path, host, (gsize) purple_xfer_get_size(xfer),
purple_http_url_get_path(httpurl),
purple_http_url_get_host(httpurl),
(gsize) purple_xfer_get_size(xfer),
(filemime?:"application/octet-stream"),
(auth?:""), (expire?:""), (cookie?:""));

g_free(auth);
g_free(expire);
g_free(cookie);

purple_ssl_write(ssl_connection, headers, strlen(headers));

hfux->ssl_conn = ssl_connection;
purple_ssl_input_add(ssl_connection, jabber_hfu_http_read, xfer);

purple_ssl_write(ssl_connection, headers, strlen(headers));

purple_xfer_ref(xfer);
purple_xfer_start(xfer, ssl_connection->fd, NULL, 0);

purple_xfer_prpl_ready(xfer);

g_free(headers);

purple_http_url_free(httpurl);
}

static void jabber_hfu_http_error_connect_cb(PurpleSslConnection *ssl_connection, PurpleSslErrorType *error_type, gpointer data)
Expand All @@ -129,13 +140,13 @@ static void jabber_hfu_request_cb(JabberStream *js, const char *from,
PurpleAccount *account;
xmlnode *slot, *put, *get, *header = NULL;
PurpleHttpURL *put_httpurl;
gchar *put_host;

PurpleXfer *xfer = data;
HFUXfer *hfux = purple_xfer_get_protocol_data(xfer);
HFUJabberStreamData *js_data = hfux->js_data;
account = purple_connection_get_account(js->gc);


if(!(slot = xmlnode_get_child_with_namespace(packet, "slot", js_data->ns)))
{
purple_xfer_cancel_remote(xfer);
Expand All @@ -151,7 +162,7 @@ static void jabber_hfu_request_cb(JabberStream *js, const char *from,
for (header = xmlnode_get_child(put, "header") ; header;
header = xmlnode_get_next_twin(header))
{
g_hash_table_insert(hfux->put_headers, g_strdup(xmlnode_get_attrib(header, "name")), g_strdup(xmlnode_get_data(header)));
g_hash_table_insert(hfux->put_headers, g_strdup(xmlnode_get_attrib(header, "name")), xmlnode_get_data(header));
}

hfux->put_url = g_strdup(xmlnode_get_attrib(put, "url"));
Expand All @@ -164,9 +175,10 @@ static void jabber_hfu_request_cb(JabberStream *js, const char *from,
}

put_httpurl = purple_http_url_parse(hfux->put_url);
put_host = purple_http_url_get_host(put_httpurl);

purple_ssl_connect(account, put_host, purple_http_url_get_port(put_httpurl), jabber_hfu_http_send_connect_cb, (PurpleSslErrorFunction)jabber_hfu_http_error_connect_cb, xfer);
g_debug("Connecting to %s:%d for %s", purple_http_url_get_host(put_httpurl), purple_http_url_get_port(put_httpurl), hfux->put_url);
purple_ssl_connect(account, purple_http_url_get_host(put_httpurl), purple_http_url_get_port(put_httpurl),
jabber_hfu_http_send_connect_cb, (PurpleSslErrorFunction)jabber_hfu_http_error_connect_cb, xfer);

purple_http_url_free(put_httpurl);
}
Expand All @@ -177,15 +189,11 @@ static void jabber_hfu_xfer_free(PurpleXfer *xfer)

g_return_if_fail(hfux != NULL);

if (hfux->put_url)
{
g_free(hfux->put_url);
}
g_free(hfux->put_url);
g_free(hfux->get_url);

if (hfux->get_url)
{
g_free(hfux->get_url);
}
if(hfux->put_headers)
g_hash_table_destroy(hfux->put_headers);

if (hfux->ssl_conn)
{
Expand Down Expand Up @@ -261,7 +269,8 @@ jabber_hfu_xmlnode_send_cb(PurpleConnection *gc, xmlnode **packet, gpointer null
if (g_strcmp0 ((*packet)->name, "message") == 0) {
xmlnode *node_body = xmlnode_get_child (*packet, "body");
if (node_body) {
HFUXfer *hfux = g_hash_table_lookup(ht_hfu_sending, xmlnode_get_data(node_body));
g_autofree char *url = xmlnode_get_data(node_body);
HFUXfer *hfux = g_hash_table_lookup(ht_hfu_sending, url);
if(hfux) {
xmlnode *x, *url;
x = xmlnode_new_child (*packet, "x");
Expand Down Expand Up @@ -313,6 +322,7 @@ static void jabber_hfu_send_url_to_conv(PurpleXfer *xfer)

static void jabber_hfu_xfer_end(PurpleXfer *xfer)
{
g_debug("This is the end.");
jabber_hfu_send_url_to_conv(xfer);

jabber_hfu_xfer_free(xfer);
Expand All @@ -336,21 +346,22 @@ static gssize jabber_hfu_xfer_write(const guchar *buffer, size_t len, PurpleXfer

if (tlen == -1)
{
if (purple_xfer_get_bytes_sent(xfer) >= purple_xfer_get_size(xfer))
purple_xfer_set_completed(xfer, TRUE);

if ((errno != EAGAIN) && (errno != EINTR))
return -1;

return 0;
}

if ((purple_xfer_get_bytes_sent(xfer) + tlen) >= purple_xfer_get_size(xfer))
purple_xfer_set_completed(xfer, TRUE);
} else if ((purple_xfer_get_bytes_sent(xfer)+tlen) >= purple_xfer_get_size(xfer))
xfer->status = PURPLE_XFER_STATUS_DONE; // sneaky cheat

return tlen;
}

static void jabber_hfu_xfer_ack(PurpleXfer *xfer, const guchar *buffer, size_t len)
{
if (purple_xfer_is_completed(xfer))
xfer->status = PURPLE_XFER_STATUS_STARTED; // hideous uncheat
}

static void jabber_hfu_xfer_init(PurpleXfer *xfer)
{
HFUXfer *hfux = purple_xfer_get_protocol_data(xfer);
Expand Down Expand Up @@ -386,7 +397,6 @@ static void jabber_hfu_xfer_init(PurpleXfer *xfer)
}



PurpleXfer *jabber_hfu_new_xfer(PurpleConnection *gc, const char *who)
{
JabberStream *js;
Expand All @@ -403,8 +413,9 @@ PurpleXfer *jabber_hfu_new_xfer(PurpleConnection *gc, const char *who)

purple_xfer_set_init_fnc(xfer, jabber_hfu_xfer_init);
purple_xfer_set_cancel_send_fnc(xfer, jabber_hfu_xfer_cancel_send);
purple_xfer_set_end_fnc(xfer, jabber_hfu_xfer_end);
purple_xfer_set_write_fnc(xfer, jabber_hfu_xfer_write);
purple_xfer_set_ack_fnc(xfer, jabber_hfu_xfer_ack);
purple_xfer_set_end_fnc(xfer, jabber_hfu_xfer_end);

return xfer;
}
Expand Down Expand Up @@ -498,6 +509,11 @@ static GList *jabber_hfu_blist_node_menu(PurpleBlistNode *node)

gboolean plugin_unload(PurplePlugin *plugin)
{
PurplePlugin *jabber_plugin = purple_plugins_find_with_id(JABBER_PLUGIN_ID);

PurplePluginProtocolInfo *jabber_protocol_info = PURPLE_PLUGIN_PROTOCOL_INFO(jabber_plugin);
jabber_protocol_info->blist_node_menu = old_blist_node_menu;

purple_signals_disconnect_by_handle(plugin);
g_hash_table_destroy(ht_hfu_sending);
g_hash_table_destroy(HFUJabberStreamDataTable);
Expand Down

0 comments on commit fbbd4b1

Please sign in to comment.