Stop uudecoding once the CAMEL_UUDECODE_STATE_END state bit gets set. Set

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.

svn path=/trunk/; revision=15349
This commit is contained in:
Jeffrey Stedfast
2002-01-17 19:21:11 +00:00
committed by Jeffrey Stedfast
parent bda8b73fe1
commit eea1e59abb
5 changed files with 93 additions and 73 deletions

View File

@ -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> 2002-01-16 Jeffrey Stedfast <fejj@ximian.com>
* camel-mime-filter-basic.c (filter): If we don't want to corrupt * camel-mime-filter-basic.c (filter): If we don't want to corrupt

View File

@ -54,7 +54,6 @@ camel_mime_filter_basic_init (CamelMimeFilterBasic *obj)
{ {
obj->state = 0; obj->state = 0;
obj->save = 0; obj->save = 0;
obj->uulen = 0;
} }
@ -82,9 +81,6 @@ reset(CamelMimeFilter *mf)
{ {
CamelMimeFilterBasic *f = (CamelMimeFilterBasic *)mf; CamelMimeFilterBasic *f = (CamelMimeFilterBasic *)mf;
f->uu_begin = FALSE;
f->uulen = 0;
switch(f->type) { switch(f->type) {
case CAMEL_MIME_FILTER_BASIC_QP_ENC: case CAMEL_MIME_FILTER_BASIC_QP_ENC:
f->state = -1; 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: case CAMEL_MIME_FILTER_BASIC_UU_ENC:
/* won't go to more than 2 * (x + 2) + 62 */ /* won't go to more than 2 * (x + 2) + 62 */
camel_mime_filter_set_size (mf, (len + 2) * 2 + 62, FALSE); camel_mime_filter_set_size (mf, (len + 2) * 2 + 62, FALSE);
newlen = uuencode_close (in, len, mf->outbuf, f->uubuf, &f->state, newlen = uuencode_close (in, len, mf->outbuf, f->uubuf, &f->state, &f->save);
&f->save, &f->uulen);
g_assert (newlen <= (len + 2) * 2 + 62); g_assert (newlen <= (len + 2) * 2 + 62);
break; break;
case CAMEL_MIME_FILTER_BASIC_BASE64_DEC: 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); g_assert(newlen <= len+2);
break; break;
case CAMEL_MIME_FILTER_BASIC_UU_DEC: 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 */ /* "begin <mode> <filename>\n" has been found, so we can now start decoding */
camel_mime_filter_set_size (mf, len + 3, FALSE); 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 { } else {
newlen = 0; 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: case CAMEL_MIME_FILTER_BASIC_UU_ENC:
/* won't go to more than 2 * (x + 2) + 62 */ /* won't go to more than 2 * (x + 2) + 62 */
camel_mime_filter_set_size (mf, (len + 2) * 2 + 62, FALSE); 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); g_assert (newlen <= (len + 2) * 2 + 62);
break; break;
case CAMEL_MIME_FILTER_BASIC_BASE64_DEC: 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); g_assert(newlen <= len + 2);
break; break;
case CAMEL_MIME_FILTER_BASIC_UU_DEC: case CAMEL_MIME_FILTER_BASIC_UU_DEC:
if (!f->uu_begin) { if (!(f->state & CAMEL_UUDECODE_STATE_BEGIN)) {
register char *inptr, *inend; register char *inptr, *inend;
size_t left; 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++); for (in = inptr; inptr < inend && *inptr != '\n'; inptr++);
if (inptr < inend) { if (inptr < inend) {
inptr++; inptr++;
f->uu_begin = TRUE; f->state |= CAMEL_UUDECODE_STATE_BEGIN;
/* we can start uudecoding... */ /* we can start uudecoding... */
in = inptr; in = inptr;
len = inend - in; 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 */ /* "begin <mode> <filename>\n" has been found, so we can now start decoding */
camel_mime_filter_set_size (mf, len + 3, FALSE); 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 { } else {
newlen = 0; newlen = 0;
} }

View File

@ -45,11 +45,9 @@ struct _CamelMimeFilterBasic {
CamelMimeFilterBasicType type; CamelMimeFilterBasicType type;
gboolean uu_begin;
unsigned char uubuf[60]; unsigned char uubuf[60];
int state; int state;
int save; int save;
char uulen;
}; };
struct _CamelMimeFilterBasicClass { struct _CamelMimeFilterBasicClass {

View File

@ -417,32 +417,32 @@ base64_decode_simple (char *data, size_t len)
* @uubuf: temporary buffer of 60 bytes * @uubuf: temporary buffer of 60 bytes
* @state: holds the number of bits that are stored in @save * @state: holds the number of bits that are stored in @save
* @save: leftover bits that have not yet been encoded * @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 * Returns the number of bytes encoded. Call this when finished
* encoding data with uuencode_step to flush off the last little * encoding data with uuencode_step to flush off the last little
* bit. * bit.
**/ **/
size_t 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 unsigned char *outptr, *bufptr;
register guint32 saved; register guint32 saved;
int i; int uulen, i;
outptr = out; outptr = out;
if (len > 0) 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; saved = *save;
i = *state; i = *state & 0xff;
uulen = (*state >> 8) & 0xff;
bufptr = uubuf + ((uulen / 3) * 4);
if (i > 0) { if (i > 0) {
while (i < 3) { while (i < 3) {
saved <<= 8 | 0; saved <<= 8;
i++; 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 (((b0 << 4) | ((b1 >> 4) & 0xf)) & 0x3f);
*bufptr++ = CAMEL_UUENCODE_CHAR (((b1 << 2) | ((b2 >> 6) & 0x3)) & 0x3f); *bufptr++ = CAMEL_UUENCODE_CHAR (((b1 << 2) | ((b2 >> 6) & 0x3)) & 0x3f);
*bufptr++ = CAMEL_UUENCODE_CHAR (b2 & 0x3f); *bufptr++ = CAMEL_UUENCODE_CHAR (b2 & 0x3f);
i = 0;
saved = 0;
uulen += 3;
} }
} }
if (*uulen || *state) { if (uulen > 0) {
int cplen = (((*uulen + (*state ? 3 : 0)) / 3) * 4); int cplen = ((uulen / 3) * 4);
*outptr++ = CAMEL_UUENCODE_CHAR (*uulen + *state); *outptr++ = CAMEL_UUENCODE_CHAR (uulen & 0xff);
memcpy (outptr, uubuf, cplen); memcpy (outptr, uubuf, cplen);
outptr += cplen; outptr += cplen;
*outptr++ = '\n'; *outptr++ = '\n';
*uulen = 0; uulen = 0;
} }
*outptr++ = CAMEL_UUENCODE_CHAR (*uulen); *outptr++ = CAMEL_UUENCODE_CHAR (uulen & 0xff);
*outptr++ = '\n'; *outptr++ = '\n';
*save = 0; *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 * @uubuf: temporary buffer of 60 bytes
* @state: holds the number of bits that are stored in @save * @state: holds the number of bits that are stored in @save
* @save: leftover bits that have not yet been encoded * @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', * Returns the number of bytes encoded. Performs an 'encode step',
* only encodes blocks of 45 characters to the output at a time, saves * 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). * invocation).
**/ **/
size_t 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; register unsigned char *inptr, *outptr, *bufptr;
unsigned char *inend; unsigned char *inend;
register guint32 saved; register guint32 saved;
int i; int uulen, i;
if (*uulen <= 0) saved = *save;
*uulen = 0; i = *state & 0xff;
uulen = (*state >> 8) & 0xff;
inptr = in; inptr = in;
inend = in + len; inend = in + len;
outptr = out; outptr = out;
bufptr = uubuf + ((*uulen / 3) * 4); bufptr = uubuf + ((uulen / 3) * 4);
saved = *save;
i = *state;
while (inptr < inend) { while (inptr < inend) {
while (*uulen < 45 && inptr < inend) { while (uulen < 45 && inptr < inend) {
while (i < 3 && inptr < inend) { while (i < 3 && inptr < inend) {
saved = (saved << 8) | *inptr++; saved = (saved << 8) | *inptr++;
i++; i++;
@ -540,22 +540,22 @@ uuencode_step (unsigned char *in, size_t len, unsigned char *out, unsigned char
i = 0; i = 0;
saved = 0; saved = 0;
*uulen += 3; uulen += 3;
} }
} }
if (*uulen >= 45) { if (uulen >= 45) {
*outptr++ = CAMEL_UUENCODE_CHAR (*uulen); *outptr++ = CAMEL_UUENCODE_CHAR (uulen & 0xff);
memcpy (outptr, uubuf, ((*uulen / 3) * 4)); memcpy (outptr, uubuf, ((uulen / 3) * 4));
outptr += ((*uulen / 3) * 4); outptr += ((uulen / 3) * 4);
*outptr++ = '\n'; *outptr++ = '\n';
*uulen = 0; uulen = 0;
bufptr = uubuf; bufptr = uubuf;
} }
} }
*save = saved; *save = saved;
*state = i; *state = ((uulen & 0xff) << 8) | (i & 0xff);
return outptr - out; return outptr - out;
} }
@ -568,37 +568,44 @@ uuencode_step (unsigned char *in, size_t len, unsigned char *out, unsigned char
* @out: output stream * @out: output stream
* @state: holds the number of bits that are stored in @save * @state: holds the number of bits that are stored in @save
* @save: leftover bits that have not yet been decoded * @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 * Returns the number of bytes decoded. Performs a 'decode step' on
* a chunk of uuencoded data. Assumes the "begin <mode> <file name>" * a chunk of uuencoded data. Assumes the "begin <mode> <file name>"
* line has been stripped off. * line has been stripped off.
**/ **/
size_t 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; register unsigned char *inptr, *outptr;
unsigned char *inend, ch; unsigned char *inend, ch;
register guint32 saved; register guint32 saved;
gboolean last_was_eoln; gboolean last_was_eoln;
int i; int uulen, i;
if (*uulen <= 0) if (*state & CAMEL_UUDECODE_STATE_END)
return 0;
saved = *save;
i = *state & 0xff;
uulen = (*state >> 8) & 0xff;
if (uulen == 0)
last_was_eoln = TRUE; last_was_eoln = TRUE;
else else
last_was_eoln = FALSE; last_was_eoln = FALSE;
inend = in + len; inend = in + len;
outptr = out; outptr = out;
saved = *save;
i = *state;
inptr = in; inptr = in;
while (inptr < inend && *inptr) { while (inptr < inend) {
if (*inptr == '\n' || last_was_eoln) { if (*inptr == '\n' || last_was_eoln) {
if (last_was_eoln) { if (last_was_eoln && *inptr != '\n') {
*uulen = CAMEL_UUDECODE_CHAR (*inptr); uulen = CAMEL_UUDECODE_CHAR (*inptr);
last_was_eoln = FALSE; last_was_eoln = FALSE;
if (uulen == 0) {
*state |= CAMEL_UUDECODE_STATE_END;
break;
}
} else { } else {
last_was_eoln = TRUE; last_was_eoln = TRUE;
} }
@ -609,7 +616,7 @@ uudecode_step (unsigned char *in, size_t len, unsigned char *out, int *state, gu
ch = *inptr++; ch = *inptr++;
if (*uulen > 0) { if (uulen > 0) {
/* save the byte */ /* save the byte */
saved = (saved << 8) | ch; saved = (saved << 8) | ch;
i++; i++;
@ -622,22 +629,22 @@ uudecode_step (unsigned char *in, size_t len, unsigned char *out, int *state, gu
b2 = saved >> 8 & 0xff; b2 = saved >> 8 & 0xff;
b3 = saved & 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 (b0) << 2 | CAMEL_UUDECODE_CHAR (b1) >> 4;
*outptr++ = CAMEL_UUDECODE_CHAR (b1) << 4 | CAMEL_UUDECODE_CHAR (b2) >> 2; *outptr++ = CAMEL_UUDECODE_CHAR (b1) << 4 | CAMEL_UUDECODE_CHAR (b2) >> 2;
*outptr++ = CAMEL_UUDECODE_CHAR (b2) << 6 | CAMEL_UUDECODE_CHAR (b3); *outptr++ = CAMEL_UUDECODE_CHAR (b2) << 6 | CAMEL_UUDECODE_CHAR (b3);
} else { } else {
if (*uulen >= 1) { if (uulen >= 1) {
*outptr++ = CAMEL_UUDECODE_CHAR (b0) << 2 | CAMEL_UUDECODE_CHAR (b1) >> 4; *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; *outptr++ = CAMEL_UUDECODE_CHAR (b1) << 4 | CAMEL_UUDECODE_CHAR (b2) >> 2;
} }
} }
i = 0; i = 0;
saved = 0; saved = 0;
*uulen -= 3; uulen -= 3;
} }
} else { } else {
break; break;
@ -645,7 +652,7 @@ uudecode_step (unsigned char *in, size_t len, unsigned char *out, int *state, gu
} }
*save = saved; *save = saved;
*state = i; *state = (*state & CAMEL_UUDECODE_STATE_MASK) | ((uulen & 0xff) << 8) | (i & 0xff);
return outptr - out; return outptr - out;
} }

View File

@ -28,6 +28,11 @@
/* maximum size of a line from header_fold() */ /* maximum size of a line from header_fold() */
#define CAMEL_FOLD_SIZE (77) #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 */ /* a list of references for this message */
struct _header_references { struct _header_references {
struct _header_references *next; 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_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 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, 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, 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); size_t quoted_decode_step(unsigned char *in, size_t len, unsigned char *out, int *savestate, int *saveme);