mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
1008: Call and reset conn->done when freeing conn->info.
In the places that set conn->info without freeing the original value, assert that both conn->info and conn->done are NULL.
This commit is contained in:
parent
2256a8c94a
commit
291a913d1e
@ -452,6 +452,15 @@ free_connection_data(struct connection *conn)
|
||||
shutdown_connection_stream(conn);
|
||||
|
||||
mem_free_set(&conn->info, NULL);
|
||||
/* If conn->done is not NULL, it probably points to a function
|
||||
* that expects conn->info to be a specific kind of structure.
|
||||
* Such a function should not be called if a different pointer
|
||||
* is later assigned to conn->info. Actually though, each
|
||||
* free_connection_data() call seems to be soon followed by
|
||||
* done_connection() so that conn->done would not be called
|
||||
* again in any case. However, this assignment costs little
|
||||
* and may make things a bit safer. */
|
||||
conn->done = NULL;
|
||||
|
||||
kill_timer(&conn->timer);
|
||||
|
||||
|
@ -250,6 +250,7 @@ done_bittorrent_connection(struct connection *conn)
|
||||
struct bittorrent_peer_connection *peer, *next;
|
||||
|
||||
assert(bittorrent);
|
||||
assert(conn->done == done_bittorrent_connection);
|
||||
|
||||
/* We don't want the tracker to see the fetch. */
|
||||
if (bittorrent->fetch)
|
||||
@ -270,6 +271,7 @@ done_bittorrent_connection(struct connection *conn)
|
||||
free_list(bittorrent->peer_pool);
|
||||
|
||||
mem_free_set(&conn->info, NULL);
|
||||
conn->done = NULL;
|
||||
}
|
||||
|
||||
static struct bittorrent_connection *
|
||||
@ -277,12 +279,17 @@ init_bittorrent_connection(struct connection *conn)
|
||||
{
|
||||
struct bittorrent_connection *bittorrent;
|
||||
|
||||
assert(conn->info == NULL);
|
||||
assert(conn->done == NULL);
|
||||
if_assert_failed return NULL;
|
||||
|
||||
bittorrent = mem_calloc(1, sizeof(*bittorrent));
|
||||
if (!bittorrent) return NULL;
|
||||
|
||||
init_list(bittorrent->peers);
|
||||
init_list(bittorrent->peer_pool);
|
||||
|
||||
/* conn->info and conn->done were asserted as NULL above. */
|
||||
conn->info = bittorrent;
|
||||
conn->done = done_bittorrent_connection;
|
||||
|
||||
|
@ -678,6 +678,13 @@ add_file_cmd_to_str(struct connection *conn)
|
||||
goto ret;
|
||||
}
|
||||
|
||||
assert(conn->info == NULL);
|
||||
assert(conn->done == NULL);
|
||||
if_assert_failed {
|
||||
abort_connection(conn, S_INTERNAL);
|
||||
goto ret;
|
||||
}
|
||||
|
||||
/* This will be reallocated below when we know how long the
|
||||
* command string should be. Error handling could be
|
||||
* simplified a little by allocating this initial structure on
|
||||
@ -689,6 +696,7 @@ add_file_cmd_to_str(struct connection *conn)
|
||||
goto ret;
|
||||
}
|
||||
|
||||
/* conn->info and conn->done were asserted as NULL above. */
|
||||
conn->info = ftp; /* Freed when connection is destroyed. */
|
||||
|
||||
if (!init_string(&command)
|
||||
|
@ -310,6 +310,13 @@ init_gopher_connection_info(struct connection *conn)
|
||||
* wazzup! */
|
||||
assert(command.length >= 2);
|
||||
|
||||
assert(conn->info == NULL);
|
||||
assert(conn->done == NULL);
|
||||
if_assert_failed {
|
||||
done_string(&command);
|
||||
return S_INTERNAL;
|
||||
}
|
||||
|
||||
size = sizeof(*gopher) + command.length;
|
||||
gopher = mem_calloc(1, size);
|
||||
if (!gopher) {
|
||||
|
@ -523,6 +523,13 @@ init_http_connection_info(struct connection *conn, int major, int minor, int clo
|
||||
{
|
||||
struct http_connection_info *http;
|
||||
|
||||
assert(conn->info == NULL);
|
||||
assert(conn->done == NULL);
|
||||
if_assert_failed {
|
||||
http_end_request(conn, S_INTERNAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
http = mem_calloc(1, sizeof(*http));
|
||||
if (!http) {
|
||||
http_end_request(conn, S_OUT_OF_MEM, 0);
|
||||
@ -547,6 +554,10 @@ init_http_connection_info(struct connection *conn, int major, int minor, int clo
|
||||
|
||||
/* If called from HTTPS proxy connection the connection info might have
|
||||
* already been allocated. */
|
||||
if (conn->done) {
|
||||
conn->done(conn);
|
||||
conn->done = NULL;
|
||||
}
|
||||
mem_free_set(&conn->info, http);
|
||||
|
||||
return http;
|
||||
|
@ -103,6 +103,13 @@ init_nntp_connection_info(struct connection *conn)
|
||||
unsigned char *data;
|
||||
int datalen;
|
||||
|
||||
assert(conn->info == NULL);
|
||||
assert(conn->done == NULL);
|
||||
if_assert_failed {
|
||||
abort_connection(conn, S_INTERNAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nntp = mem_calloc(1, sizeof(*nntp));
|
||||
if (!nntp) {
|
||||
abort_connection(conn, S_OUT_OF_MEM);
|
||||
@ -194,6 +201,13 @@ nntp_quit(struct connection *conn)
|
||||
{
|
||||
struct nntp_connection_info *info;
|
||||
|
||||
assert(conn->info == NULL);
|
||||
assert(conn->done == NULL);
|
||||
if_assert_failed {
|
||||
abort_connection(conn, S_INTERNAL);
|
||||
return;
|
||||
}
|
||||
|
||||
info = mem_calloc(1, sizeof(*info));
|
||||
if (!info) {
|
||||
abort_connection(conn, S_OUT_OF_MEM);
|
||||
|
Loading…
Reference in New Issue
Block a user