diff options
Diffstat (limited to 'camel/camel-mime-filter-basic.c')
-rw-r--r-- | camel/camel-mime-filter-basic.c | 62 |
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); |