[evolution-data-server] Bug 628977 - crash in imapx_parse_uids() (Make stream buf grow automatically)
- From: David Woodhouse <dwmw2 src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug 628977 - crash in imapx_parse_uids() (Make stream buf grow automatically)
- Date: Wed, 8 Sep 2010 09:59:34 +0000 (UTC)
commit de5bdc315907225f61bce95937ba16d23b028691
Author: David Woodhouse <David Woodhouse intel com>
Date: Wed Sep 8 10:43:28 2010 +0100
Bug 628977 - crash in imapx_parse_uids() (Make stream buf grow automatically)
Instead of bailing out when we need a larger buffer, just grow it.
Start with a 4-byte buffer, to ensure we exercise the reallocation code.
After a little while (and before the release) we can bump that up to something
more sensible like 4KiB.
camel/providers/imapx/camel-imapx-stream.c | 91 ++++++++++++++++-----------
camel/providers/imapx/camel-imapx-stream.h | 1 +
2 files changed, 55 insertions(+), 37 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-stream.c b/camel/providers/imapx/camel-imapx-stream.c
index 905c5a1..65d5359 100644
--- a/camel/providers/imapx/camel-imapx-stream.c
+++ b/camel/providers/imapx/camel-imapx-stream.c
@@ -37,8 +37,6 @@
#define t(x) camel_imapx_debug(token, x)
#define io(x) camel_imapx_debug(io, x)
-#define CAMEL_IMAPX_STREAM_SIZE (8192)
-#define CAMEL_IMAPX_STREAM_TOKEN (8192) /* maximum token size */
G_DEFINE_TYPE (CamelIMAPXStream, camel_imapx_stream, CAMEL_TYPE_STREAM)
@@ -55,7 +53,7 @@ imapx_stream_fill (CamelIMAPXStream *is,
is->ptr = is->buf;
left = camel_stream_read (
is->source, (gchar *) is->end,
- CAMEL_IMAPX_STREAM_SIZE - (is->end - is->buf), error);
+ is->bufsize - (is->end - is->buf), error);
if (left > 0) {
is->end += left;
io(printf("camel_imapx_read: buffer is '%.*s'\n", (gint)(is->end - is->ptr), is->ptr));
@@ -207,8 +205,35 @@ static void
camel_imapx_stream_init (CamelIMAPXStream *is)
{
/* +1 is room for appending a 0 if we need to for a token */
- is->ptr = is->end = is->buf = g_malloc(CAMEL_IMAPX_STREAM_SIZE+1);
- is->tokenbuf = g_malloc(CAMEL_IMAPX_STREAM_SIZE+1);
+ is->bufsize = 4;
+ is->ptr = is->end = is->buf = g_malloc (is->bufsize + 1);
+ is->tokenbuf = g_malloc (is->bufsize + 1);
+}
+
+static void camel_imapx_stream_grow (CamelIMAPXStream *is, guint len, guchar **bufptr, guchar **tokptr)
+{
+ guchar *oldtok = is->tokenbuf;
+ guchar *oldbuf = is->buf;
+
+ do {
+ is->bufsize <<= 1;
+ } while (is->bufsize <= len);
+
+ io(printf("Grow imapx buffers to %d bytes\n", is->bufsize));
+
+ is->tokenbuf = g_realloc (is->tokenbuf, is->bufsize + 1);
+ if (tokptr)
+ *tokptr = is->tokenbuf + (*tokptr - oldtok);
+ if (is->unget)
+ is->unget_token = is->tokenbuf + (is->unget_token - oldtok);
+
+ //io(printf("buf was %p, ptr %p end %p\n", is->buf, is->ptr, is->end));
+ is->buf = g_realloc (is->buf, is->bufsize + 1);
+ is->ptr = is->buf + (is->ptr - oldbuf);
+ is->end = is->buf + (is->end - oldbuf);
+ //io(printf("buf now %p, ptr %p end %p\n", is->buf, is->ptr, is->end));
+ if (bufptr)
+ *bufptr = is->buf + (*bufptr - oldbuf);
}
/**
@@ -317,12 +342,8 @@ camel_imapx_stream_astring(CamelIMAPXStream *is, guchar **data, GError **error)
case IMAPX_TOK_STRING:
return 0;
case IMAPX_TOK_LITERAL:
- /* FIXME: just grow buffer */
- if (len >= CAMEL_IMAPX_STREAM_TOKEN) {
- g_set_error (error, CAMEL_IMAPX_ERROR, 1, "astring: literal too long");
- io(printf("astring too long\n"));
- return IMAPX_TOK_PROTOCOL;
- }
+ if (len >= is->bufsize)
+ camel_imapx_stream_grow(is, len, NULL, NULL);
p = is->tokenbuf;
camel_imapx_stream_set_literal(is, len);
do {
@@ -357,11 +378,8 @@ camel_imapx_stream_nstring(CamelIMAPXStream *is, guchar **data, GError **error)
case IMAPX_TOK_STRING:
return 0;
case IMAPX_TOK_LITERAL:
- /* FIXME: just grow buffer */
- if (len >= CAMEL_IMAPX_STREAM_TOKEN) {
- g_set_error (error, CAMEL_IMAPX_ERROR, 1, "nstring: literal too long");
- return IMAPX_TOK_PROTOCOL;
- }
+ if (len >= is->bufsize)
+ camel_imapx_stream_grow(is, len, NULL, NULL);
p = is->tokenbuf;
camel_imapx_stream_set_literal(is, len);
do {
@@ -491,8 +509,8 @@ camel_imapx_token_t
/* throws IO,PARSE exception */
camel_imapx_stream_token(CamelIMAPXStream *is, guchar **data, guint *len, GError **error)
{
- register guchar c, *p, *o, *oe;
- guchar *e;
+ register guchar c, *oe;
+ guchar *o, *p, *e;
guint literal;
gint digits;
@@ -570,7 +588,7 @@ camel_imapx_stream_token(CamelIMAPXStream *is, guchar **data, guint *len, GError
}
} else if (c == '"') {
o = is->tokenbuf;
- oe = is->tokenbuf + CAMEL_IMAPX_STREAM_TOKEN - 1;
+ oe = is->tokenbuf + is->bufsize - 1;
while (1) {
while (p < e) {
c = *p++;
@@ -591,19 +609,16 @@ camel_imapx_stream_token(CamelIMAPXStream *is, guchar **data, guint *len, GError
t(printf("token STRING '%s'\n", is->tokenbuf));
return IMAPX_TOK_STRING;
}
-
- if (c == '\n' || c == '\r' || o>=oe) {
- if (o >= oe) {
- io(printf("Protocol error: string too long\n"));
-
- } else {
- io(printf("Protocol error: truncated string\n"));
- }
-
+ if (c == '\n' || c == '\r') {
+ io(printf("Protocol error: truncated string\n"));
goto protocol_error;
- } else {
- *o++ = c;
}
+ if (o >= oe) {
+ camel_imapx_stream_grow(is, 0, &p, &o);
+ oe = is->tokenbuf + is->bufsize - 1;
+ e = is->end;
+ }
+ *o++ = c;
}
is->ptr = p;
if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR)
@@ -613,7 +628,7 @@ camel_imapx_stream_token(CamelIMAPXStream *is, guchar **data, guint *len, GError
}
} else {
o = is->tokenbuf;
- oe = is->tokenbuf + CAMEL_IMAPX_STREAM_TOKEN - 1;
+ oe = is->tokenbuf + is->bufsize - 1;
digits = isdigit(c);
*o++ = c;
while (1) {
@@ -630,13 +645,15 @@ camel_imapx_stream_token(CamelIMAPXStream *is, guchar **data, guint *len, GError
*len = o - is->tokenbuf;
t(printf("token TOKEN '%s'\n", is->tokenbuf));
return digits?IMAPX_TOK_INT:IMAPX_TOK_TOKEN;
- } else if (o < oe) {
- digits &= isdigit(c);
- *o++ = c;
- } else {
- io(printf("Protocol error: token too long\n"));
- goto protocol_error;
}
+
+ if (o >= oe) {
+ camel_imapx_stream_grow(is, 0, &p, &o);
+ oe = is->tokenbuf + is->bufsize - 1;
+ e = is->end;
+ }
+ digits &= isdigit(c);
+ *o++ = c;
}
is->ptr = p;
if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR)
diff --git a/camel/providers/imapx/camel-imapx-stream.h b/camel/providers/imapx/camel-imapx-stream.h
index 334ed7e..aa9a40b 100644
--- a/camel/providers/imapx/camel-imapx-stream.h
+++ b/camel/providers/imapx/camel-imapx-stream.h
@@ -74,6 +74,7 @@ struct _CamelIMAPXStream {
guint unget_len;
guchar *tokenbuf;
+ guint bufsize;
};
struct _CamelIMAPXStreamClass {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]