dovecot-2.2: lib-imap-urlauth: Fixed deinitialization of the URL...
dovecot at dovecot.org
dovecot at dovecot.org
Tue May 21 22:55:45 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/5a36736445e9
changeset: 16385:5a36736445e9
user: Stephan Bosch <stephan at rename-it.nl>
date: Tue May 21 22:55:23 2013 +0300
description:
lib-imap-urlauth: Fixed deinitialization of the URLAUTH fetch handler.
Added reference counting to make sure callbacks will not deinitialize the
handler prematurely.
diffstat:
src/imap/cmd-urlfetch.c | 1 -
src/lib-imap-urlauth/imap-urlauth-fetch.c | 57 +++++++++++++++++++++++++++---
src/lib-imap-urlauth/imap-urlauth-fetch.h | 5 +-
3 files changed, 52 insertions(+), 11 deletions(-)
diffs (192 lines):
diff -r 9dbcd10cac28 -r 5a36736445e9 src/imap/cmd-urlfetch.c
--- a/src/imap/cmd-urlfetch.c Tue May 21 22:55:17 2013 +0300
+++ b/src/imap/cmd-urlfetch.c Tue May 21 22:55:23 2013 +0300
@@ -284,7 +284,6 @@
if ((last && cmd->state == CLIENT_COMMAND_STATE_WAIT_EXTERNAL) ||
ret < 0) {
- ctx->ufetch = NULL;
cmd_urlfetch_finish(cmd);
client_command_free(&cmd);
}
diff -r 9dbcd10cac28 -r 5a36736445e9 src/lib-imap-urlauth/imap-urlauth-fetch.c
--- a/src/lib-imap-urlauth/imap-urlauth-fetch.c Tue May 21 22:55:17 2013 +0300
+++ b/src/lib-imap-urlauth/imap-urlauth-fetch.c Tue May 21 22:55:23 2013 +0300
@@ -22,6 +22,7 @@
};
struct imap_urlauth_fetch {
+ unsigned int refcount;
struct imap_urlauth_context *uctx;
imap_urlauth_fetch_callback_t *callback;
@@ -100,17 +101,28 @@
struct imap_urlauth_fetch *ufetch;
ufetch = i_new(struct imap_urlauth_fetch, 1);
+ ufetch->refcount = 1;
ufetch->uctx = uctx;
ufetch->callback = callback;
ufetch->context = context;
return ufetch;
}
-void imap_urlauth_fetch_deinit(struct imap_urlauth_fetch **_ufetch)
+static void imap_urlauth_fetch_ref(struct imap_urlauth_fetch *ufetch)
+{
+ i_assert(ufetch->refcount > 0);
+ ufetch->refcount++;
+}
+
+static void imap_urlauth_fetch_unref(struct imap_urlauth_fetch **_ufetch)
{
struct imap_urlauth_fetch *ufetch = *_ufetch;
+ i_assert(ufetch->refcount > 0);
+
*_ufetch = NULL;
+ if (--ufetch->refcount > 0)
+ return;
imap_urlauth_fetch_abort(ufetch);
@@ -120,6 +132,11 @@
i_free(ufetch);
}
+void imap_urlauth_fetch_deinit(struct imap_urlauth_fetch **_ufetch)
+{
+ imap_urlauth_fetch_unref(_ufetch);
+}
+
static void
imap_urlauth_fetch_error(struct imap_urlauth_fetch *ufetch, const char *url,
enum imap_urlauth_fetch_flags url_flags,
@@ -232,6 +249,8 @@
}
if (!success && ret < 0) {
+ if (mpurl != NULL)
+ imap_msgpart_url_free(&mpurl);
ufetch->pending_requests--;
(void)ufetch->callback(NULL, TRUE, ufetch->context);
imap_urlauth_fetch_fail(ufetch);
@@ -292,6 +311,8 @@
ufetch->waiting_local = FALSE;
ufetch->pending_requests--;
+ imap_urlauth_fetch_ref(ufetch);
+
if (!ufetch->failed) {
bool last = ufetch->pending_requests == 0 || reply == NULL;
ret = ufetch->callback(reply, last, ufetch->context);
@@ -305,8 +326,8 @@
} else if (ret == 0) {
ufetch->waiting_service = TRUE;
}
- if (ret != 0)
- imap_urlauth_fetch_deinit(&ufetch);
+
+ imap_urlauth_fetch_unref(&ufetch);
return ret;
}
@@ -319,6 +340,7 @@
struct mail_user *mail_user = uctx->user;
struct imap_url *imap_url;
const char *error, *errormsg;
+ int ret = 0;
/* parse the url */
if (imap_url_parse(url, NULL, url_parse_flags, &imap_url, &error) < 0) {
@@ -327,13 +349,17 @@
if (mail_user->mail_debug)
i_debug("%s", errormsg);
ufetch->pending_requests++;
+ imap_urlauth_fetch_ref(ufetch);
imap_urlauth_fetch_error(ufetch, url, url_flags, errormsg);
+ imap_urlauth_fetch_unref(&ufetch);
return 1;
}
ufetch->failed = FALSE;
ufetch->pending_requests++;
+ imap_urlauth_fetch_ref(ufetch);
+
/* if access user and target user match, handle fetch request locally */
if (imap_url->userid != NULL &&
strcmp(mail_user->username, imap_url->userid) == 0) {
@@ -364,17 +390,22 @@
/* create request for url */
if (imap_url != NULL && imap_url->userid != NULL) {
+ i_assert(uctx->conn != NULL);
(void)imap_urlauth_request_new(uctx->conn, imap_url->userid,
url, url_flags,
imap_urlauth_fetch_request_callback, ufetch);
i_assert(uctx->conn != NULL);
if (imap_urlauth_connection_connect(uctx->conn) < 0)
- return -1;
+ ret = -1;
}
- return (ufetch->pending_requests > 0 ? 0 : 1);
+ if (ret >= 0)
+ ret = (ufetch->pending_requests > 0 ? 0 : 1);
+
+ imap_urlauth_fetch_unref(&ufetch);
+ return ret;
}
-bool imap_urlauth_fetch_continue(struct imap_urlauth_fetch *ufetch)
+static bool imap_urlauth_fetch_do_continue(struct imap_urlauth_fetch *ufetch)
{
struct imap_urlauth_fetch_url *url, *url_next;
int ret;
@@ -390,7 +421,7 @@
ufetch->waiting_service = FALSE;
imap_urlauth_connection_continue(ufetch->uctx->conn);
return ufetch->pending_requests > 0;
- }
+ }
/* finished local request */
if (ufetch->local_url != NULL) {
@@ -457,3 +488,15 @@
return ufetch->pending_requests > 0;
}
+
+bool imap_urlauth_fetch_continue(struct imap_urlauth_fetch *ufetch)
+{
+ bool pending;
+
+ imap_urlauth_fetch_ref(ufetch);
+ pending = imap_urlauth_fetch_do_continue(ufetch);
+ imap_urlauth_fetch_unref(&ufetch);
+
+ return pending;
+}
+
diff -r 9dbcd10cac28 -r 5a36736445e9 src/lib-imap-urlauth/imap-urlauth-fetch.h
--- a/src/lib-imap-urlauth/imap-urlauth-fetch.h Tue May 21 22:55:17 2013 +0300
+++ b/src/lib-imap-urlauth/imap-urlauth-fetch.h Tue May 21 22:55:23 2013 +0300
@@ -33,8 +33,7 @@
for next reply, 0 if not all data was processed, and -1 for error. If a
callback returns 0, imap_urlauth_fetch_continue() must be called once
new replies may be processed. If this is the last request to yield a reply,
- argument last is TRUE. The callback must not call
- imap_urlauth_fetch_deinit(). */
+ argument last is TRUE. */
typedef int
imap_urlauth_fetch_callback_t(struct imap_urlauth_fetch_reply *reply,
bool last, void *context);
@@ -42,7 +41,7 @@
struct imap_urlauth_fetch *
imap_urlauth_fetch_init(struct imap_urlauth_context *uctx,
imap_urlauth_fetch_callback_t *callback, void *context);
-void imap_urlauth_fetch_deinit(struct imap_urlauth_fetch **_ufetch);
+void imap_urlauth_fetch_deinit(struct imap_urlauth_fetch **ufetch);
int imap_urlauth_fetch_url(struct imap_urlauth_fetch *ufetch, const char *url,
enum imap_urlauth_fetch_flags url_flags);
More information about the dovecot-cvs
mailing list