summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2005-05-13 09:38:56 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2005-05-13 09:38:56 +0000
commit9c1f689b6b0a987b67fee97288aaba5654ae96db (patch)
tree3b9829379432f86a26c06cf59911f6866aaff4f1
parent2de526cd873efd03973486e526668d150c1fc153 (diff)
downloadmailutils-9c1f689b6b0a987b67fee97288aaba5654ae96db.tar.gz
mailutils-9c1f689b6b0a987b67fee97288aaba5654ae96db.tar.bz2
(imap4d_fetch0): Reduce memory consumption within
the mailbox scanning loop. Break the loop when an invalid msgno is encountered or the message cannot be retrieved. (fetch_io): Check for integer overflow (IDEF0956). (fetch_full,fetch_rfc822_header,fetch_rfc822_text) (fetch_operation): Propagate return value back to the caller.
-rw-r--r--imap4d/fetch.c79
1 files changed, 48 insertions, 31 deletions
diff --git a/imap4d/fetch.c b/imap4d/fetch.c
index 937173b59..2f8d58b11 100644
--- a/imap4d/fetch.c
+++ b/imap4d/fetch.c
@@ -136,7 +136,7 @@ int
imap4d_fetch0 (char *arg, int isuid, char *resp, size_t resplen)
{
struct fetch_command *fcmd = NULL;
- int rc = RESP_NO;
+ int rc = RESP_OK;
char *sp = NULL;
char *msgset;
size_t *set = NULL;
@@ -159,25 +159,29 @@ imap4d_fetch0 (char *arg, int isuid, char *resp, size_t resplen)
return RESP_BAD;
}
- for (i = 0; i < n; i++)
+ /* Prepare status code. It will be replaced if an error occurs in the
+ loop below */
+ snprintf (resp, resplen, "Completed");
+
+ for (i = 0; i < n && rc == RESP_OK; i++)
{
- char item[32];
- char *items = strdup (sp);
- char *p = items;
- size_t msgno;
- int space = 0;
+ size_t msgno = (isuid) ? uid_to_msgno (set[i]) : set[i];
message_t msg = NULL;
- msgno = (isuid) ? uid_to_msgno (set[i]) : set[i];
if (msgno && mailbox_get_message (mbox, msgno, &msg) == 0)
{
+ char item[32];
+ char *items = strdup (sp);
+ char *p = items;
+ int space = 0;
+
fcmd = NULL;
util_send ("* %d FETCH (", msgno);
item[0] = '\0';
/* Server implementations MUST implicitly
- include the UID message data item as part of any FETCH response
- caused by a UID command, regardless of whether a UID was specified
- as a message data item to the FETCH. */
+ include the UID message data item as part of any FETCH
+ response caused by a UID command, regardless of whether
+ a UID was specified as a message data item to the FETCH. */
if (isuid)
{
fcmd = &fetch_command_table[F_UID];
@@ -190,7 +194,7 @@ imap4d_fetch0 (char *arg, int isuid, char *resp, size_t resplen)
util_token (item, sizeof (item), &items);
/* Do not send the UID again. */
if (isuid && strcasecmp (item, "UID") == 0)
- continue;
+ continue;
if (fcmd)
space = 1;
/* Search in the table. */
@@ -207,12 +211,18 @@ imap4d_fetch0 (char *arg, int isuid, char *resp, size_t resplen)
}
}
util_send (")\r\n");
+ free (p);
+ }
+ else
+ {
+ snprintf (resp, resplen,
+ "Bogus message set: message number out of range");
+ rc = RESP_BAD;
+ break;
}
- free (p);
}
free (set);
- snprintf (resp, resplen, "Completed");
- return RESP_OK;
+ return rc;
}
/* ALL:
@@ -240,8 +250,7 @@ fetch_full (struct fetch_command *command, char **arg)
fetch_all (command, arg);
util_send (" ");
c_body.msg = command->msg;
- fetch_body (&c_body, arg);
- return RESP_OK;
+ return fetch_body (&c_body, arg);
}
/* FAST:
@@ -372,8 +381,7 @@ fetch_rfc822_header (struct fetch_command *command, char **arg ARG_UNUSED)
char *p = buffer;
strcpy (buffer, ".PEEK[HEADER]");
- fetch_body (command, &p);
- return RESP_OK;
+ return fetch_body (command, &p);
}
/* RFC822.TEXT:
@@ -386,8 +394,7 @@ fetch_rfc822_text (struct fetch_command *command, char **arg ARG_UNUSED)
char *p = buffer;
strcpy (buffer, "[TEXT]");
- fetch_body (command, &p);
- return RESP_OK;
+ return fetch_body (command, &p);
}
/* The [RFC-822] size of the message. */
@@ -955,7 +962,8 @@ fetch_operation (message_t msg, char **arg, int silent)
unsigned long end = ULONG_MAX; /* No limit. */
char *section; /* Hold the section number string. */
char *partial = strchr (*arg, '<');
-
+ int rc;
+
/* Check for section specific offset. */
if (partial)
{
@@ -1009,13 +1017,15 @@ fetch_operation (message_t msg, char **arg, int silent)
else
section = calloc (1, 1);
+ rc = RESP_OK;
+
/* Choose the right fetch attribute. */
if (*section == '\0' && **arg == ']')
{
if (!silent)
util_send ("[]");
(*arg)++;
- fetch_message (msg, start, end);
+ rc = fetch_message (msg, start, end);
}
else if (strncasecmp (*arg, "HEADER]", 7) == 0)
{
@@ -1029,7 +1039,7 @@ fetch_operation (message_t msg, char **arg, int silent)
util_send ("[%sHEADER]", section);
}
(*arg) += 7;
- fetch_header (msg, start, end);
+ rc = fetch_header (msg, start, end);
}
else if (strncasecmp (*arg, "MIME]", 5) == 0)
{
@@ -1041,7 +1051,7 @@ fetch_operation (message_t msg, char **arg, int silent)
util_send ("[%s", *arg);
}
(*arg) += 5;
- fetch_header (msg, start, end);
+ rc = fetch_header (msg, start, end);
}
else if (strncasecmp (*arg, "HEADER.FIELDS.NOT", 17) == 0)
{
@@ -1052,7 +1062,7 @@ fetch_operation (message_t msg, char **arg, int silent)
else
util_send ("[");
(*arg) += 17;
- fetch_header_fields_not (msg, arg, start, end);
+ rc = fetch_header_fields_not (msg, arg, start, end);
}
else if (strncasecmp (*arg, "HEADER.FIELDS", 13) == 0)
{
@@ -1063,7 +1073,7 @@ fetch_operation (message_t msg, char **arg, int silent)
else
util_send ("[");
(*arg) += 13;
- fetch_header_fields (msg, arg, start, end);
+ rc = fetch_header_fields (msg, arg, start, end);
}
else if (strncasecmp (*arg, "TEXT]", 5) == 0)
@@ -1076,19 +1086,22 @@ fetch_operation (message_t msg, char **arg, int silent)
util_send ("[TEXT]");
}
(*arg) += 5;
- fetch_body_content (msg, start, end);
+ rc = fetch_body_content (msg, start, end);
}
else if (**arg == ']')
{
if (!silent)
util_send ("[%s]", section);
(*arg)++;
- fetch_body_content (msg, start, end);
+ rc = fetch_body_content (msg, start, end);
}
else
- util_send (" \"\"");/*FIXME: ERROR Message!*/
+ {
+ util_send (" \"\"");/*FIXME: ERROR Message!*/
+ rc = RESP_BAD;
+ }
free (section);
- return RESP_OK;
+ return rc;
}
static int
@@ -1156,6 +1169,10 @@ fetch_io (stream_t stream, unsigned long start, unsigned long end,
else
util_send (" \"\"");
}
+ else if (end + 2 < end) /* Check for integer overflow */
+ {
+ return RESP_BAD;
+ }
else
{
char *buffer, *p;

Return to:

Send suggestions and report system problems to the System administrator.