Mon, 12 Sep 2016 08:55:35 -0500
gg: Protect against issues when closing while connecting
Since the GIOStream is cancelled when data is freed, any cancelled
callbacks are called after such data is freed. This patch guards against
cancelled calls by safely returning without accessing any freed data if
the connection has been cancelled (aka closed).
Futhermore, if GG tries to connect and is quickly disconnected,
ggp_tcpsocket_close() is never called. As far as I can tell, it's an
existing bug, but PurpleSockets both work differently when closing and
are closed by the connection if any leak. So the issue wasn't a major
problem. This patch lessens the issue by guarding against it, but it
should be fixed at some point.
| 8675 | 1 | /* |
| 2 | * nmrequest.c | |
| 3 | * | |
|
8933
0f1e8160581d
[gaim-migrate @ 9703]
Mike Stoddard <mistoddard@novell.com>
parents:
8684
diff
changeset
|
4 | * Copyright (c) 2004 Novell, Inc. All Rights Reserved. |
|
0f1e8160581d
[gaim-migrate @ 9703]
Mike Stoddard <mistoddard@novell.com>
parents:
8684
diff
changeset
|
5 | * |
|
0f1e8160581d
[gaim-migrate @ 9703]
Mike Stoddard <mistoddard@novell.com>
parents:
8684
diff
changeset
|
6 | * This program is free software; you can redistribute it and/or modify |
|
0f1e8160581d
[gaim-migrate @ 9703]
Mike Stoddard <mistoddard@novell.com>
parents:
8684
diff
changeset
|
7 | * it under the terms of the GNU General Public License as published by |
|
0f1e8160581d
[gaim-migrate @ 9703]
Mike Stoddard <mistoddard@novell.com>
parents:
8684
diff
changeset
|
8 | * the Free Software Foundation; version 2 of the License. |
| 8675 | 9 | * |
|
8933
0f1e8160581d
[gaim-migrate @ 9703]
Mike Stoddard <mistoddard@novell.com>
parents:
8684
diff
changeset
|
10 | * This program is distributed in the hope that it will be useful, |
|
0f1e8160581d
[gaim-migrate @ 9703]
Mike Stoddard <mistoddard@novell.com>
parents:
8684
diff
changeset
|
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
0f1e8160581d
[gaim-migrate @ 9703]
Mike Stoddard <mistoddard@novell.com>
parents:
8684
diff
changeset
|
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
0f1e8160581d
[gaim-migrate @ 9703]
Mike Stoddard <mistoddard@novell.com>
parents:
8684
diff
changeset
|
13 | * GNU General Public License for more details. |
|
8684
7ec649752daa
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
14 | * |
|
8933
0f1e8160581d
[gaim-migrate @ 9703]
Mike Stoddard <mistoddard@novell.com>
parents:
8684
diff
changeset
|
15 | * You should have received a copy of the GNU General Public License |
|
0f1e8160581d
[gaim-migrate @ 9703]
Mike Stoddard <mistoddard@novell.com>
parents:
8684
diff
changeset
|
16 | * along with this program; if not, write to the Free Software |
|
19859
71d37b57eff2
The FSF changed its address a while ago; our files were out of date.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
15884
diff
changeset
|
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
| 8675 | 18 | * |
| 19 | */ | |
| 20 | ||
| 21 | #include "nmrequest.h" | |
| 22 | ||
|
9360
c40bc951573a
[gaim-migrate @ 10168]
Mike Stoddard <mistoddard@novell.com>
parents:
8933
diff
changeset
|
23 | static int count = 0; |
|
c40bc951573a
[gaim-migrate @ 10168]
Mike Stoddard <mistoddard@novell.com>
parents:
8933
diff
changeset
|
24 | |
| 8675 | 25 | struct _NMRequest |
| 26 | { | |
| 27 | int trans_id; | |
| 28 | char *cmd; | |
| 29 | int gmt; | |
| 30 | gpointer data; | |
| 31 | gpointer user_define; | |
| 32 | nm_response_cb callback; | |
| 33 | int ref_count; | |
| 34 | NMERR_T ret_code; | |
| 35 | }; | |
| 36 | ||
|
9360
c40bc951573a
[gaim-migrate @ 10168]
Mike Stoddard <mistoddard@novell.com>
parents:
8933
diff
changeset
|
37 | NMRequest *nm_create_request(const char *cmd, int trans_id, int gmt, nm_response_cb cb, |
|
c40bc951573a
[gaim-migrate @ 10168]
Mike Stoddard <mistoddard@novell.com>
parents:
8933
diff
changeset
|
38 | gpointer resp_data, gpointer user_define) |
| 8675 | 39 | { |
| 40 | NMRequest *req; | |
| 41 | ||
| 42 | if (cmd == NULL) | |
| 43 | return NULL; | |
| 44 | ||
| 45 | req = g_new0(NMRequest, 1); | |
| 46 | req->cmd = g_strdup(cmd); | |
| 47 | req->trans_id = trans_id; | |
| 48 | req->gmt = gmt; | |
|
9360
c40bc951573a
[gaim-migrate @ 10168]
Mike Stoddard <mistoddard@novell.com>
parents:
8933
diff
changeset
|
49 | req->callback = cb; |
|
c40bc951573a
[gaim-migrate @ 10168]
Mike Stoddard <mistoddard@novell.com>
parents:
8933
diff
changeset
|
50 | req->data = resp_data; |
|
c40bc951573a
[gaim-migrate @ 10168]
Mike Stoddard <mistoddard@novell.com>
parents:
8933
diff
changeset
|
51 | req->user_define = user_define; |
| 8675 | 52 | req->ref_count = 1; |
| 53 | ||
| 15884 | 54 | purple_debug_info("novell", "Creating NMRequest instance, total=%d\n", ++count); |
|
9360
c40bc951573a
[gaim-migrate @ 10168]
Mike Stoddard <mistoddard@novell.com>
parents:
8933
diff
changeset
|
55 | |
| 8675 | 56 | return req; |
| 57 | } | |
| 58 | ||
| 59 | void | |
| 60 | nm_release_request(NMRequest * req) | |
| 61 | { | |
| 62 | if (req && (--req->ref_count == 0)) { | |
|
37425
5061721fd98f
Remove more NULL-checks before free()
Michael McConville <mmcco@mykolab.com>
parents:
19859
diff
changeset
|
63 | g_free(req->cmd); |
| 8675 | 64 | g_free(req); |
|
9360
c40bc951573a
[gaim-migrate @ 10168]
Mike Stoddard <mistoddard@novell.com>
parents:
8933
diff
changeset
|
65 | |
| 15884 | 66 | purple_debug_info("novell", |
|
9360
c40bc951573a
[gaim-migrate @ 10168]
Mike Stoddard <mistoddard@novell.com>
parents:
8933
diff
changeset
|
67 | "Releasing NMRequest instance, total=%d\n", --count); |
| 8675 | 68 | } |
|
9360
c40bc951573a
[gaim-migrate @ 10168]
Mike Stoddard <mistoddard@novell.com>
parents:
8933
diff
changeset
|
69 | |
| 8675 | 70 | } |
| 71 | ||
| 72 | void | |
| 73 | nm_request_add_ref(NMRequest * req) | |
| 74 | { | |
| 75 | if (req) | |
| 76 | req->ref_count++; | |
| 77 | } | |
| 78 | ||
| 79 | void | |
| 80 | nm_request_set_callback(NMRequest * req, nm_response_cb callback) | |
| 81 | { | |
| 82 | if (req) | |
| 83 | req->callback = callback; | |
| 84 | } | |
| 85 | ||
| 86 | void | |
| 87 | nm_request_set_data(NMRequest * req, gpointer data) | |
| 88 | { | |
| 89 | if (req) | |
| 90 | req->data = data; | |
| 91 | } | |
| 92 | ||
| 93 | void | |
| 94 | nm_request_set_user_define(NMRequest * req, gpointer user_define) | |
| 95 | { | |
| 96 | if (req) | |
| 97 | req->user_define = user_define; | |
| 98 | } | |
| 99 | ||
| 100 | int | |
| 101 | nm_request_get_trans_id(NMRequest * req) | |
| 102 | { | |
| 103 | if (req) | |
| 104 | return req->trans_id; | |
| 105 | else | |
| 106 | return -1; | |
| 107 | } | |
| 108 | ||
| 109 | const char * | |
| 110 | nm_request_get_cmd(NMRequest * req) | |
| 111 | { | |
| 112 | if (req == NULL) | |
| 113 | return NULL; | |
| 114 | ||
| 115 | return req->cmd; | |
| 116 | } | |
| 117 | ||
| 118 | gpointer | |
| 119 | nm_request_get_data(NMRequest * req) | |
| 120 | { | |
| 121 | if (req == NULL) | |
| 122 | return NULL; | |
| 123 | ||
| 124 | return req->data; | |
| 125 | } | |
| 126 | ||
| 127 | gpointer | |
| 128 | nm_request_get_user_define(NMRequest * req) | |
| 129 | { | |
| 130 | if (req == NULL) | |
| 131 | return NULL; | |
| 132 | ||
| 133 | return req->user_define; | |
| 134 | } | |
| 135 | ||
| 136 | nm_response_cb | |
| 137 | nm_request_get_callback(NMRequest * req) | |
| 138 | { | |
| 139 | if (req == NULL) | |
| 140 | return NULL; | |
| 141 | ||
| 142 | return req->callback; | |
| 143 | } | |
| 144 | ||
| 145 | ||
| 146 | void | |
| 147 | nm_request_set_ret_code(NMRequest * req, NMERR_T rc) | |
| 148 | { | |
| 149 | if (req) | |
| 150 | req->ret_code = rc; | |
| 151 | } | |
| 152 | ||
| 153 | NMERR_T | |
| 154 | nm_request_get_ret_code(NMRequest * req) | |
| 155 | { | |
| 156 | if (req) | |
| 157 | return req->ret_code; | |
| 158 | else | |
| 159 | return (NMERR_T) - 1; | |
| 160 | } |