diff options
-rw-r--r-- | camel/ChangeLog | 15 | ||||
-rw-r--r-- | camel/camel-mime-filter-basic.c | 21 | ||||
-rw-r--r-- | camel/camel-mime-filter-basic.h | 2 | ||||
-rw-r--r-- | camel/camel-mime-utils.c | 117 | ||||
-rw-r--r-- | camel/camel-mime-utils.h | 11 |
5 files changed, 93 insertions, 73 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 011388a8b9..a1e671678d 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,18 @@ +2002-01-17 Jeffrey Stedfast <fejj@ximian.com> + + * camel-mime-filter-basic.c (filter): Stop uudecoding once the + CAMEL_UUDECODE_STATE_END state bit gets set. Set the + CAMEL_UUDECODE_STATE_BEGIN state bit once we find the begin line. + (reset): No longer have uu_begin or uulen state variables, these + are now stuffed into a single state variable. + + * camel-mime-utils.c (uudecode_step): No longer needs a uulen + argument and also keeps track of whether or not the end of the + encoded data has been found in 'state'. + (uuencode_step): Now stuffs uulen into state so that the uulen + argument is no longer needed. + (uuencode_close): Same. + 2002-01-16 Jeffrey Stedfast <fejj@ximian.com> * camel-mime-filter-basic.c (filter): If we don't want to corrupt diff --git a/camel/camel-mime-filter-basic.c b/camel/camel-mime-filter-basic.c index 5e2b9f5107..efb9b9818e 100644 --- a/camel/camel-mime-filter-basic.c +++ b/camel/camel-mime-filter-basic.c @@ -54,7 +54,6 @@ camel_mime_filter_basic_init (CamelMimeFilterBasic *obj) { obj->state = 0; obj->save = 0; - obj->uulen = 0; } @@ -82,9 +81,6 @@ reset(CamelMimeFilter *mf) { CamelMimeFilterBasic *f = (CamelMimeFilterBasic *)mf; - f->uu_begin = FALSE; - f->uulen = 0; - switch(f->type) { case CAMEL_MIME_FILTER_BASIC_QP_ENC: f->state = -1; @@ -117,8 +113,7 @@ complete(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, case CAMEL_MIME_FILTER_BASIC_UU_ENC: /* won't go to more than 2 * (x + 2) + 62 */ camel_mime_filter_set_size (mf, (len + 2) * 2 + 62, FALSE); - newlen = uuencode_close (in, len, mf->outbuf, f->uubuf, &f->state, - &f->save, &f->uulen); + newlen = uuencode_close (in, len, mf->outbuf, f->uubuf, &f->state, &f->save); g_assert (newlen <= (len + 2) * 2 + 62); break; case CAMEL_MIME_FILTER_BASIC_BASE64_DEC: @@ -134,10 +129,10 @@ 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: - if (f->uu_begin) { + if ((f->state & CAMEL_UUDECODE_STATE_BEGIN) && !(f->state & CAMEL_UUDECODE_STATE_END)) { /* "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); + newlen = uudecode_step (in, len, mf->outbuf, &f->state, &f->save); } else { newlen = 0; } @@ -181,7 +176,7 @@ filter(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, s case CAMEL_MIME_FILTER_BASIC_UU_ENC: /* won't go to more than 2 * (x + 2) + 62 */ camel_mime_filter_set_size (mf, (len + 2) * 2 + 62, FALSE); - newlen = uuencode_step (in, len, mf->outbuf, f->uubuf, &f->state, &f->save, &f->uulen); + newlen = uuencode_step (in, len, mf->outbuf, f->uubuf, &f->state, &f->save); g_assert (newlen <= (len + 2) * 2 + 62); break; case CAMEL_MIME_FILTER_BASIC_BASE64_DEC: @@ -197,7 +192,7 @@ filter(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, s g_assert(newlen <= len + 2); break; case CAMEL_MIME_FILTER_BASIC_UU_DEC: - if (!f->uu_begin) { + if (!(f->state & CAMEL_UUDECODE_STATE_BEGIN)) { register char *inptr, *inend; size_t left; @@ -214,7 +209,7 @@ filter(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, s for (in = inptr; inptr < inend && *inptr != '\n'; inptr++); if (inptr < inend) { inptr++; - f->uu_begin = TRUE; + f->state |= CAMEL_UUDECODE_STATE_BEGIN; /* we can start uudecoding... */ in = inptr; len = inend - in; @@ -232,10 +227,10 @@ filter(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, s } } - if (f->uu_begin) { + if ((f->state & CAMEL_UUDECODE_STATE_BEGIN) && !(f->state & CAMEL_UUDECODE_STATE_END)) { /* "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); + newlen = uudecode_step (in, len, mf->outbuf, &f->state, &f->save); } else { newlen = 0; } diff --git a/camel/camel-mime-filter-basic.h b/camel/camel-mime-filter-basic.h index 939da6c190..1ec5f2ec17 100644 --- a/camel/camel-mime-filter-basic.h +++ b/camel/camel-mime-filter-basic.h @@ -45,11 +45,9 @@ struct _CamelMimeFilterBasic { CamelMimeFilterBasicType type; - gboolean uu_begin; unsigned char uubuf[60]; int state; int save; - char uulen; }; struct _CamelMimeFilterBasicClass { diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c index f00c5d21a8..5066e8fd1e 100644 --- a/camel/camel-mime-utils.c +++ b/camel/camel-mime-utils.c @@ -417,32 +417,32 @@ base64_decode_simple (char *data, size_t len) * @uubuf: temporary buffer of 60 bytes * @state: holds the number of bits that are stored in @save * @save: leftover bits that have not yet been encoded - * @uulen: holds the value of the length-char which is used to calculate - * how many more chars need to be decoded for that 'line' * * Returns the number of bytes encoded. Call this when finished * encoding data with uuencode_step to flush off the last little * bit. **/ size_t -uuencode_close (unsigned char *in, size_t len, unsigned char *out, unsigned char *uubuf, int *state, guint32 *save, char *uulen) +uuencode_close (unsigned char *in, size_t len, unsigned char *out, unsigned char *uubuf, int *state, guint32 *save) { register unsigned char *outptr, *bufptr; register guint32 saved; - int i; + int uulen, i; outptr = out; if (len > 0) - outptr += uuencode_step (in, len, out, uubuf, state, save, uulen); + outptr += uuencode_step (in, len, out, uubuf, state, save); - bufptr = uubuf + ((*uulen / 3) * 4); saved = *save; - i = *state; + i = *state & 0xff; + uulen = (*state >> 8) & 0xff; + + bufptr = uubuf + ((uulen / 3) * 4); if (i > 0) { while (i < 3) { - saved <<= 8 | 0; + saved <<= 8; i++; } @@ -458,20 +458,24 @@ uuencode_close (unsigned char *in, size_t len, unsigned char *out, unsigned char *bufptr++ = CAMEL_UUENCODE_CHAR (((b0 << 4) | ((b1 >> 4) & 0xf)) & 0x3f); *bufptr++ = CAMEL_UUENCODE_CHAR (((b1 << 2) | ((b2 >> 6) & 0x3)) & 0x3f); *bufptr++ = CAMEL_UUENCODE_CHAR (b2 & 0x3f); + + i = 0; + saved = 0; + uulen += 3; } } - if (*uulen || *state) { - int cplen = (((*uulen + (*state ? 3 : 0)) / 3) * 4); + if (uulen > 0) { + int cplen = ((uulen / 3) * 4); - *outptr++ = CAMEL_UUENCODE_CHAR (*uulen + *state); + *outptr++ = CAMEL_UUENCODE_CHAR (uulen & 0xff); memcpy (outptr, uubuf, cplen); outptr += cplen; *outptr++ = '\n'; - *uulen = 0; + uulen = 0; } - *outptr++ = CAMEL_UUENCODE_CHAR (*uulen); + *outptr++ = CAMEL_UUENCODE_CHAR (uulen & 0xff); *outptr++ = '\n'; *save = 0; @@ -489,8 +493,6 @@ uuencode_close (unsigned char *in, size_t len, unsigned char *out, unsigned char * @uubuf: temporary buffer of 60 bytes * @state: holds the number of bits that are stored in @save * @save: leftover bits that have not yet been encoded - * @uulen: holds the value of the length-char which is used to calculate - * how many more chars need to be decoded for that 'line' * * Returns the number of bytes encoded. Performs an 'encode step', * only encodes blocks of 45 characters to the output at a time, saves @@ -498,28 +500,26 @@ uuencode_close (unsigned char *in, size_t len, unsigned char *out, unsigned char * invocation). **/ size_t -uuencode_step (unsigned char *in, size_t len, unsigned char *out, unsigned char *uubuf, int *state, guint32 *save, char *uulen) +uuencode_step (unsigned char *in, size_t len, unsigned char *out, unsigned char *uubuf, int *state, guint32 *save) { register unsigned char *inptr, *outptr, *bufptr; unsigned char *inend; register guint32 saved; - int i; + int uulen, i; - if (*uulen <= 0) - *uulen = 0; + saved = *save; + i = *state & 0xff; + uulen = (*state >> 8) & 0xff; inptr = in; inend = in + len; outptr = out; - bufptr = uubuf + ((*uulen / 3) * 4); - - saved = *save; - i = *state; + bufptr = uubuf + ((uulen / 3) * 4); while (inptr < inend) { - while (*uulen < 45 && inptr < inend) { + while (uulen < 45 && inptr < inend) { while (i < 3 && inptr < inend) { saved = (saved << 8) | *inptr++; i++; @@ -540,22 +540,22 @@ uuencode_step (unsigned char *in, size_t len, unsigned char *out, unsigned char i = 0; saved = 0; - *uulen += 3; + uulen += 3; } } - if (*uulen >= 45) { - *outptr++ = CAMEL_UUENCODE_CHAR (*uulen); - memcpy (outptr, uubuf, ((*uulen / 3) * 4)); - outptr += ((*uulen / 3) * 4); + if (uulen >= 45) { + *outptr++ = CAMEL_UUENCODE_CHAR (uulen & 0xff); + memcpy (outptr, uubuf, ((uulen / 3) * 4)); + outptr += ((uulen / 3) * 4); *outptr++ = '\n'; - *uulen = 0; + uulen = 0; bufptr = uubuf; } } *save = saved; - *state = i; + *state = ((uulen & 0xff) << 8) | (i & 0xff); return outptr - out; } @@ -568,85 +568,92 @@ uuencode_step (unsigned char *in, size_t len, unsigned char *out, unsigned char * @out: output stream * @state: holds the number of bits that are stored in @save * @save: leftover bits that have not yet been decoded - * @uulen: holds the value of the length-char which is used to calculate - * how many more chars need to be decoded for that 'line' * * Returns the number of bytes decoded. Performs a 'decode step' on * a chunk of uuencoded data. Assumes the "begin <mode> <file name>" * line has been stripped off. **/ size_t -uudecode_step (unsigned char *in, size_t len, unsigned char *out, int *state, guint32 *save, char *uulen) +uudecode_step (unsigned char *in, size_t len, unsigned char *out, int *state, guint32 *save) { register unsigned char *inptr, *outptr; unsigned char *inend, ch; register guint32 saved; gboolean last_was_eoln; - int i; - - if (*uulen <= 0) + int uulen, i; + + if (*state & CAMEL_UUDECODE_STATE_END) + return 0; + + saved = *save; + i = *state & 0xff; + uulen = (*state >> 8) & 0xff; + if (uulen == 0) last_was_eoln = TRUE; else last_was_eoln = FALSE; inend = in + len; outptr = out; - saved = *save; - i = *state; + inptr = in; - while (inptr < inend && *inptr) { + while (inptr < inend) { if (*inptr == '\n' || last_was_eoln) { - if (last_was_eoln) { - *uulen = CAMEL_UUDECODE_CHAR (*inptr); + if (last_was_eoln && *inptr != '\n') { + uulen = CAMEL_UUDECODE_CHAR (*inptr); last_was_eoln = FALSE; + if (uulen == 0) { + *state |= CAMEL_UUDECODE_STATE_END; + break; + } } else { last_was_eoln = TRUE; } - + inptr++; continue; } - + ch = *inptr++; - if (*uulen > 0) { + if (uulen > 0) { /* save the byte */ saved = (saved << 8) | ch; i++; if (i == 4) { /* convert 4 uuencoded bytes to 3 normal bytes */ unsigned char b0, b1, b2, b3; - + b0 = saved >> 24; b1 = saved >> 16 & 0xff; b2 = saved >> 8 & 0xff; b3 = saved & 0xff; - - if (*uulen >= 3) { + + if (uulen >= 3) { *outptr++ = CAMEL_UUDECODE_CHAR (b0) << 2 | CAMEL_UUDECODE_CHAR (b1) >> 4; *outptr++ = CAMEL_UUDECODE_CHAR (b1) << 4 | CAMEL_UUDECODE_CHAR (b2) >> 2; *outptr++ = CAMEL_UUDECODE_CHAR (b2) << 6 | CAMEL_UUDECODE_CHAR (b3); } else { - if (*uulen >= 1) { + if (uulen >= 1) { *outptr++ = CAMEL_UUDECODE_CHAR (b0) << 2 | CAMEL_UUDECODE_CHAR (b1) >> 4; } - if (*uulen >= 2) { + if (uulen >= 2) { *outptr++ = CAMEL_UUDECODE_CHAR (b1) << 4 | CAMEL_UUDECODE_CHAR (b2) >> 2; } } - + i = 0; saved = 0; - *uulen -= 3; + uulen -= 3; } } else { break; } } - + *save = saved; - *state = i; - + *state = (*state & CAMEL_UUDECODE_STATE_MASK) | ((uulen & 0xff) << 8) | (i & 0xff); + return outptr - out; } diff --git a/camel/camel-mime-utils.h b/camel/camel-mime-utils.h index fcd1a06fa5..8bd9c81993 100644 --- a/camel/camel-mime-utils.h +++ b/camel/camel-mime-utils.h @@ -28,6 +28,11 @@ /* maximum size of a line from header_fold() */ #define CAMEL_FOLD_SIZE (77) +#define CAMEL_UUDECODE_STATE_INIT (0) +#define CAMEL_UUDECODE_STATE_BEGIN (1 << 16) +#define CAMEL_UUDECODE_STATE_END (1 << 17) +#define CAMEL_UUDECODE_STATE_MASK (CAMEL_UUDECODE_STATE_BEGIN | CAMEL_UUDECODE_STATE_END) + /* a list of references for this message */ struct _header_references { struct _header_references *next; @@ -191,12 +196,12 @@ size_t base64_decode_step(unsigned char *in, size_t len, unsigned char *out, int size_t base64_encode_step(unsigned char *in, size_t len, gboolean break_lines, unsigned char *out, int *state, int *save); size_t base64_encode_close(unsigned char *in, size_t len, gboolean break_lines, unsigned char *out, int *state, int *save); -size_t uudecode_step (unsigned char *in, size_t len, unsigned char *out, int *state, guint32 *save, char *uulen); +size_t uudecode_step (unsigned char *in, size_t len, unsigned char *out, int *state, guint32 *save); size_t uuencode_step (unsigned char *in, size_t len, unsigned char *out, unsigned char *uubuf, int *state, - guint32 *save, char *uulen); + guint32 *save); size_t uuencode_close (unsigned char *in, size_t len, unsigned char *out, unsigned char *uubuf, int *state, - guint32 *save, char *uulen); + guint32 *save); size_t quoted_decode_step(unsigned char *in, size_t len, unsigned char *out, int *savestate, int *saveme); |