aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-mime-filter-basic.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/camel-mime-filter-basic.c')
-rw-r--r--camel/camel-mime-filter-basic.c62
1 files changed, 54 insertions, 8 deletions
diff --git a/camel/camel-mime-filter-basic.c b/camel/camel-mime-filter-basic.c
index b1edd06f4b..ff21ad9609 100644
--- a/camel/camel-mime-filter-basic.c
+++ b/camel/camel-mime-filter-basic.c
@@ -21,6 +21,7 @@
#include "camel-mime-filter-basic.h"
#include "camel-mime-utils.h"
+#include <string.h>
static void reset(CamelMimeFilter *mf);
static void complete(CamelMimeFilter *mf, char *in, size_t len,
@@ -78,7 +79,9 @@ static void
reset(CamelMimeFilter *mf)
{
CamelMimeFilterBasic *f = (CamelMimeFilterBasic *)mf;
-
+
+ f->uu_begin = FALSE;
+
switch(f->type) {
case CAMEL_MIME_FILTER_BASIC_QP_ENC:
f->state = -1;
@@ -94,7 +97,7 @@ complete(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out,
{
CamelMimeFilterBasic *f = (CamelMimeFilterBasic *)mf;
int newlen;
-
+
switch(f->type) {
case CAMEL_MIME_FILTER_BASIC_BASE64_ENC:
/* wont go to more than 2x size (overly conservative) */
@@ -128,9 +131,13 @@ complete(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out,
g_assert(newlen <= len+2);
break;
case CAMEL_MIME_FILTER_BASIC_UU_DEC:
- /* output can't possibly exceed the input size */
- camel_mime_filter_set_size (mf, len, FALSE);
- newlen = uudecode_step (in, len, mf->outbuf, &f->state, &f->save, &f->uulen);
+ if (f->uu_begin) {
+ /* "begin <mode> <filename>\n" has been found, so we can now start decoding */
+ camel_mime_filter_set_size (mf, len + 3, FALSE);
+ newlen = uudecode_step (in, len, mf->outbuf, &f->state, &f->save, &f->uulen);
+ } else {
+ newlen = 0;
+ }
break;
default:
g_warning("unknown type %d in CamelMimeFilterBasic", f->type);
@@ -186,9 +193,48 @@ filter(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, s
g_assert(newlen <= len);
break;
case CAMEL_MIME_FILTER_BASIC_UU_DEC:
- /* output can't possibly exceed the input size */
- camel_mime_filter_set_size (mf, len, FALSE);
- newlen = uudecode_step (in, len, mf->outbuf, &f->state, &f->save, &f->uulen);
+ if (!f->uu_begin) {
+ register char *inptr, *inend;
+ size_t left;
+
+ inptr = in;
+ inend = inptr + len;
+
+ while (inptr < inend) {
+ left = inend - inptr;
+ if (left < 6) {
+ if (!strncmp (inptr, "begin ", left))
+ camel_mime_filter_backup (mf, inptr, left);
+ break;
+ } else if (!strncmp (inptr, "begin ", 6)) {
+ for (in = inptr; inptr < inend && *inptr != '\n'; inptr++);
+ if (inptr < inend) {
+ inptr++;
+ f->uu_begin = TRUE;
+ /* we can start uudecoding... */
+ in = inptr;
+ len = inend - in;
+ } else {
+ camel_mime_filter_backup (mf, in, left);
+ }
+ break;
+ }
+
+ /* go to the next line */
+ for (inptr++; inptr < inend && *inptr != '\n'; inptr++);
+
+ if (inptr < inend)
+ inptr++;
+ }
+ }
+
+ if (f->uu_begin) {
+ /* "begin <mode> <filename>\n" has been found, so we can now start decoding */
+ camel_mime_filter_set_size (mf, len + 3, FALSE);
+ newlen = uudecode_step (in, len, mf->outbuf, &f->state, &f->save, &f->uulen);
+ } else {
+ newlen = 0;
+ }
break;
default:
g_warning("unknown type %d in CamelMimeFilterBasic", f->type);