dovecot-1.1: pop3: Prevent clients from looping forever trying t...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Jan 14 18:12:20 EET 2009
details: http://hg.dovecot.org/dovecot-1.1/rev/48c279fcb9e3
changeset: 8094:48c279fcb9e3
user: Timo Sirainen <tss at iki.fi>
date: Wed Jan 14 11:12:03 2009 -0500
description:
pop3: Prevent clients from looping forever trying to fetch an expunged message.
diffstat:
2 files changed, 22 insertions(+), 8 deletions(-)
src/pop3/client.h | 1 +
src/pop3/commands.c | 29 +++++++++++++++++++++--------
diffs (88 lines):
diff -r 874bf3a4bbdc -r 48c279fcb9e3 src/pop3/client.h
--- a/src/pop3/client.h Wed Jan 14 10:47:47 2009 -0500
+++ b/src/pop3/client.h Wed Jan 14 11:12:03 2009 -0500
@@ -22,6 +22,7 @@ struct client {
time_t last_input, last_output;
unsigned int bad_counter;
+ unsigned int highest_expunged_fetch_msgnum;
unsigned int uid_validity;
unsigned int messages_count;
diff -r 874bf3a4bbdc -r 48c279fcb9e3 src/pop3/commands.c
--- a/src/pop3/commands.c Wed Jan 14 10:47:47 2009 -0500
+++ b/src/pop3/commands.c Wed Jan 14 11:12:03 2009 -0500
@@ -365,9 +365,23 @@ static void fetch_callback(struct client
client->cmd = NULL;
}
-static void fetch(struct client *client, unsigned int msgnum, uoff_t body_lines)
+static int client_reply_msg_expunged(struct client *client, unsigned int msgnum)
+{
+ client_send_line(client, "-ERR Message %u expunged.", msgnum + 1);
+ if (msgnum <= client->highest_expunged_fetch_msgnum) {
+ /* client tried to fetch an expunged message again.
+ treat this as error so we'll eventually disconnect the
+ client instead of letting it loop forever. */
+ return -1;
+ }
+ client->highest_expunged_fetch_msgnum = msgnum;
+ return 1;
+}
+
+static int fetch(struct client *client, unsigned int msgnum, uoff_t body_lines)
{
struct fetch_context *ctx;
+ int ret;
ctx = i_new(struct fetch_context, 1);
@@ -382,9 +396,9 @@ static void fetch(struct client *client,
if (mailbox_search_next(ctx->search_ctx, ctx->mail) <= 0 ||
mail_get_stream(ctx->mail, NULL, NULL, &ctx->stream) < 0) {
- client_send_line(client, "-ERR Message not found.");
+ ret = client_reply_msg_expunged(client, msgnum);
fetch_deinit(ctx);
- return;
+ return ret;
}
if (body_lines == (uoff_t)-1 && !no_flag_updates) {
@@ -407,6 +421,7 @@ static void fetch(struct client *client,
client->cmd = fetch_callback;
client->cmd_context = ctx;
fetch_callback(client);
+ return 1;
}
static int cmd_retr(struct client *client, const char *args)
@@ -423,8 +438,7 @@ static int cmd_retr(struct client *clien
client->byte_counter = &client->retr_bytes;
client->byte_counter_offset = client->output->offset;
- fetch(client, msgnum, (uoff_t)-1);
- return 1;
+ return fetch(client, msgnum, (uoff_t)-1);
}
static int cmd_rset(struct client *client, const char *args ATTR_UNUSED)
@@ -493,8 +507,7 @@ static int cmd_top(struct client *client
client->byte_counter = &client->top_bytes;
client->byte_counter_offset = client->output->offset;
- fetch(client, msgnum, max_lines);
- return 1;
+ return fetch(client, msgnum, max_lines);
}
struct cmd_uidl_context {
@@ -659,7 +672,7 @@ static int cmd_uidl(struct client *clien
ctx = cmd_uidl_init(client, msgnum+1);
if (!list_uids_iter(client, ctx))
- client_send_line(client, "-ERR Message not found.");
+ return client_reply_msg_expunged(client, msgnum);
}
return 1;
More information about the dovecot-cvs
mailing list