mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 12:35:58 +00:00
fix for bug #119964. implement yEnc decoding.
note, we have no plans to support yEnc encoding. thanks to ducarroz for the patch. r/sr=sspitzer
This commit is contained in:
parent
4c694bf157
commit
985e9ef0d6
@ -124,6 +124,8 @@ MimeEncrypted_parse_begin (MimeObject *obj)
|
||||
!nsCRT::strcasecmp(obj->encoding, ENCODING_UUENCODE3) ||
|
||||
!nsCRT::strcasecmp(obj->encoding, ENCODING_UUENCODE4))
|
||||
fn = &MimeUUDecoderInit;
|
||||
else if (!nsCRT::strcasecmp(obj->encoding, ENCODING_YENCODE))
|
||||
fn = &MimeYDecoderInit;
|
||||
if (fn)
|
||||
{
|
||||
enc->decoder_data =
|
||||
|
@ -781,7 +781,7 @@ mime_insert_all_headers(char **body,
|
||||
char *c2 = 0;
|
||||
|
||||
// Hack for BSD Mailbox delimiter.
|
||||
if (i == 0 && head[0] == 'F' && !nsCRT::strncmp(head, "From ", 5))
|
||||
if (i == 0 && head[0] == 'F' && !strncmp(head, "From ", 5))
|
||||
{
|
||||
colon = head + 4;
|
||||
contents = colon + 1;
|
||||
@ -1961,6 +1961,8 @@ mime_decompose_file_init_fn ( void *stream_closure, MimeHeaders *headers )
|
||||
!nsCRT::strcasecmp(newAttachment->encoding, ENCODING_UUENCODE3) ||
|
||||
!nsCRT::strcasecmp(newAttachment->encoding, ENCODING_UUENCODE4))
|
||||
fn = &MimeUUDecoderInit;
|
||||
else if (!nsCRT::strcasecmp(newAttachment->encoding, ENCODING_YENCODE))
|
||||
fn = &MimeYDecoderInit;
|
||||
|
||||
if (fn)
|
||||
{
|
||||
|
@ -44,12 +44,12 @@
|
||||
#include "prprf.h"
|
||||
|
||||
typedef enum mime_encoding {
|
||||
mime_Base64, mime_QuotedPrintable, mime_uuencode
|
||||
mime_Base64, mime_QuotedPrintable, mime_uuencode, mime_yencode
|
||||
} mime_encoding;
|
||||
|
||||
typedef enum mime_uue_state {
|
||||
UUE_BEGIN, UUE_BODY, UUE_END
|
||||
} mime_uue_state;
|
||||
typedef enum mime_decoder_state {
|
||||
DS_BEGIN, DS_BODY, DS_END
|
||||
} mime_decoder_state;
|
||||
|
||||
struct MimeDecoderData {
|
||||
mime_encoding encoding; /* Which encoding to use */
|
||||
@ -58,9 +58,10 @@ struct MimeDecoderData {
|
||||
char token[4];
|
||||
int token_size;
|
||||
|
||||
/* State and read-buffer used for uudecode. */
|
||||
mime_uue_state uue_state;
|
||||
char uue_line_buffer [128];
|
||||
/* State and read-buffer used for uudecode and yencode. */
|
||||
mime_decoder_state ds_state;
|
||||
char *line_buffer;
|
||||
int line_buffer_size;
|
||||
|
||||
/* Where to write the decoded data */
|
||||
nsresult (*write_buffer) (const char *buf, PRInt32 size, void *closure);
|
||||
@ -324,22 +325,31 @@ static int
|
||||
mime_decode_uue_buffer (MimeDecoderData *data,
|
||||
const char *input_buffer, PRInt32 input_length)
|
||||
{
|
||||
/* First, copy input_buffer into state->uue_line_buffer until we have
|
||||
/* First, copy input_buffer into state->line_buffer until we have
|
||||
a complete line.
|
||||
|
||||
Then decode that line in place (in the uue_line_buffer) and write
|
||||
Then decode that line in place (in the line_buffer) and write
|
||||
it out.
|
||||
|
||||
Then pull the next line into uue_line_buffer and continue.
|
||||
Then pull the next line into line_buffer and continue.
|
||||
*/
|
||||
if (!data->line_buffer)
|
||||
{
|
||||
data->line_buffer_size = 128;
|
||||
data->line_buffer = (char *)PR_MALLOC(data->line_buffer_size);
|
||||
if (!data->line_buffer)
|
||||
return -1;
|
||||
data->line_buffer[0] = 0;
|
||||
}
|
||||
|
||||
int status = 0;
|
||||
char *line = data->uue_line_buffer;
|
||||
char *line_end = data->uue_line_buffer + sizeof (data->uue_line_buffer) - 1;
|
||||
char *line = data->line_buffer;
|
||||
char *line_end = data->line_buffer + data->line_buffer_size - 1;
|
||||
|
||||
NS_ASSERTION(data->encoding == mime_uuencode, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
|
||||
if (data->encoding != mime_uuencode) return -1;
|
||||
|
||||
if (data->uue_state == UUE_END)
|
||||
if (data->ds_state == DS_END)
|
||||
{
|
||||
status = 0;
|
||||
goto DONE;
|
||||
@ -410,7 +420,7 @@ mime_decode_uue_buffer (MimeDecoderData *data,
|
||||
*/
|
||||
|
||||
|
||||
if (data->uue_state == UUE_BODY &&
|
||||
if (data->ds_state == DS_BODY &&
|
||||
line[0] == 'e' &&
|
||||
line[1] == 'n' &&
|
||||
line[2] == 'd' &&
|
||||
@ -418,25 +428,25 @@ mime_decode_uue_buffer (MimeDecoderData *data,
|
||||
line[3] == nsCRT::LF))
|
||||
{
|
||||
/* done! */
|
||||
data->uue_state = UUE_END;
|
||||
data->ds_state = DS_END;
|
||||
*line = 0;
|
||||
break;
|
||||
}
|
||||
else if (data->uue_state == UUE_BEGIN)
|
||||
else if (data->ds_state == DS_BEGIN)
|
||||
{
|
||||
if (!nsCRT::strncmp (line, "begin ", 6))
|
||||
data->uue_state = UUE_BODY;
|
||||
if (!strncmp (line, "begin ", 6))
|
||||
data->ds_state = DS_BODY;
|
||||
*line = 0;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We're in UUE_BODY. Decode the line. */
|
||||
/* We're in DS_BODY. Decode the line. */
|
||||
char *in, *out;
|
||||
PRInt32 i;
|
||||
long lost;
|
||||
|
||||
NS_ASSERTION (data->uue_state == UUE_BODY, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
|
||||
NS_ASSERTION (data->ds_state == DS_BODY, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
|
||||
|
||||
/* We map down `line', reading four bytes and writing three.
|
||||
That means that `out' always stays safely behind `in'.
|
||||
@ -544,6 +554,198 @@ mime_decode_uue_buffer (MimeDecoderData *data,
|
||||
return status;
|
||||
}
|
||||
|
||||
static int
|
||||
mime_decode_yenc_buffer (MimeDecoderData *data,
|
||||
const char *input_buffer, PRInt32 input_length)
|
||||
{
|
||||
/* First, copy input_buffer into state->line_buffer until we have
|
||||
a complete line.
|
||||
|
||||
Then decode that line in place (in the line_buffer) and write
|
||||
it out.
|
||||
|
||||
Then pull the next line into line_buffer and continue.
|
||||
*/
|
||||
if (!data->line_buffer)
|
||||
{
|
||||
data->line_buffer_size = 1000; // let make sure we have plenty of space for the header line
|
||||
data->line_buffer = (char *)PR_MALLOC(data->line_buffer_size);
|
||||
if (!data->line_buffer)
|
||||
return -1;
|
||||
data->line_buffer[0] = 0;
|
||||
}
|
||||
|
||||
int status = 0;
|
||||
char *line = data->line_buffer;
|
||||
char *line_end = data->line_buffer + data->line_buffer_size - 1;
|
||||
|
||||
NS_ASSERTION(data->encoding == mime_yencode, "wrong decoder!");
|
||||
if (data->encoding != mime_yencode) return -1;
|
||||
|
||||
if (data->ds_state == DS_END)
|
||||
return 0;
|
||||
|
||||
while (input_length > 0)
|
||||
{
|
||||
/* Copy data from input_buffer to `line' until we have a complete line,
|
||||
or until we've run out of input.
|
||||
|
||||
(line may have data in it already if the last time we were called,
|
||||
we weren't called with a buffer that ended on a line boundary.)
|
||||
*/
|
||||
{
|
||||
char *out = line + strlen(line);
|
||||
while (input_length > 0 && out < line_end)
|
||||
{
|
||||
*out++ = *input_buffer++;
|
||||
input_length--;
|
||||
|
||||
if (out[-1] == nsCRT::CR || out[-1] == nsCRT::LF)
|
||||
{
|
||||
/* If we just copied a CR, and an LF is waiting, grab it too. */
|
||||
if (out[-1] == nsCRT::CR &&
|
||||
input_length > 0 &&
|
||||
*input_buffer == nsCRT::LF)
|
||||
input_buffer++, input_length--;
|
||||
|
||||
/* We have a line. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
*out = 0;
|
||||
|
||||
/* Ignore blank lines. */
|
||||
if (*line == nsCRT::CR || *line == nsCRT::LF)
|
||||
{
|
||||
*line = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If this line was bigger than our buffer, truncate it.
|
||||
(This means the data was way corrupted, and there's basically
|
||||
no chance of decoding it properly, but give it a shot anyway.)
|
||||
*/
|
||||
if (out == line_end)
|
||||
{
|
||||
out--;
|
||||
out[-1] = nsCRT::CR;
|
||||
out[0] = 0;
|
||||
}
|
||||
|
||||
/* If we didn't get a complete line, simply return; we'll be called
|
||||
with the rest of this line next time.
|
||||
*/
|
||||
if (out[-1] != nsCRT::CR && out[-1] != nsCRT::LF)
|
||||
{
|
||||
NS_ASSERTION (input_length == 0, "empty buffer!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Now we have a complete line. Deal with it.
|
||||
*/
|
||||
const char * endOfLine = line + strlen(line);
|
||||
|
||||
if (data->ds_state == DS_BEGIN)
|
||||
{
|
||||
int new_line_size = 0;
|
||||
/* this yenc decoder does not support yenc v2 or multipart yenc.
|
||||
Therefore, we are looking first for "=ybegin line="
|
||||
*/
|
||||
if ((endOfLine - line) >= 13 && !strncmp (line, "=ybegin line=", 13))
|
||||
{
|
||||
/* ...then couple digits. */
|
||||
for (line += 13; line < endOfLine; line ++)
|
||||
{
|
||||
if (*line < '0' || *line > '9')
|
||||
break;
|
||||
new_line_size = (new_line_size * 10) + *line - '0';
|
||||
}
|
||||
|
||||
/* ...next, look for <space>size= */
|
||||
if ((endOfLine - line) >= 6 && !strncmp (line, " size=", 6))
|
||||
{
|
||||
/* ...then couple digits. */
|
||||
for (line += 6; line < endOfLine; line ++)
|
||||
if (*line < '0' || *line > '9')
|
||||
break;
|
||||
|
||||
/* ...next, look for <space>name= */
|
||||
if ((endOfLine - line) >= 6 && !strncmp (line, " name=", 6))
|
||||
{
|
||||
/* we have found the yenc header line.
|
||||
Now check if we need to grow our buffer line
|
||||
*/
|
||||
data->ds_state = DS_BODY;
|
||||
if (new_line_size > data->line_buffer_size && new_line_size <= 997) /* don't let bad value hurt us! */
|
||||
{
|
||||
PR_Free(data->line_buffer);
|
||||
data->line_buffer_size = new_line_size + 4; //extra chars for line ending and potential escape char
|
||||
data->line_buffer = (char *)PR_MALLOC(data->line_buffer_size);
|
||||
if (!data->line_buffer)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
*data->line_buffer = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (data->ds_state == DS_BODY && line[0] == '=')
|
||||
{
|
||||
/* look if this this the final line */
|
||||
if (!strncmp (line, "=yend size=", 11))
|
||||
{
|
||||
/* done! */
|
||||
data->ds_state = DS_END;
|
||||
*line = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We're in DS_BODY. Decode the line in place. */
|
||||
{
|
||||
char *src = line;
|
||||
char *dest = src;
|
||||
char c;
|
||||
for (; src < line_end; src ++)
|
||||
{
|
||||
c = *src;
|
||||
if (!c || c == nsCRT::CR || c == nsCRT::LF)
|
||||
break;
|
||||
|
||||
if (c == '=')
|
||||
{
|
||||
src++;
|
||||
c = *src;
|
||||
if (c == 0)
|
||||
return -1; /* last character cannot be escape char */
|
||||
c -= 64;
|
||||
}
|
||||
c -= 42;
|
||||
*dest = c;
|
||||
dest ++;
|
||||
}
|
||||
|
||||
/* Now write out what we decoded for this line. */
|
||||
NS_ASSERTION(dest >= line && dest < src, "nothing to write!");
|
||||
if (dest > line)
|
||||
{
|
||||
status = data->write_buffer (line, dest - line, data->closure);
|
||||
if (status < 0) /* abort */
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Reset the line so that we don't think it's partial next time. */
|
||||
*line = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
MimeDecoderDestroy (MimeDecoderData *data, PRBool abort_p)
|
||||
@ -562,6 +764,8 @@ MimeDecoderDestroy (MimeDecoderData *data, PRBool abort_p)
|
||||
data->closure);
|
||||
}
|
||||
|
||||
if (data->line_buffer)
|
||||
PR_Free(data->line_buffer);
|
||||
PR_Free (data);
|
||||
return status;
|
||||
}
|
||||
@ -578,6 +782,9 @@ mime_decoder_init (mime_encoding which,
|
||||
data->encoding = which;
|
||||
data->write_buffer = output_fn;
|
||||
data->closure = closure;
|
||||
data->line_buffer_size = 0;
|
||||
data->line_buffer = nsnull;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -602,6 +809,13 @@ MimeUUDecoderInit (nsresult (*output_fn) (const char *, PRInt32, void *),
|
||||
return mime_decoder_init (mime_uuencode, output_fn, closure);
|
||||
}
|
||||
|
||||
MimeDecoderData *
|
||||
MimeYDecoderInit (nsresult (*output_fn) (const char *, PRInt32, void *),
|
||||
void *closure)
|
||||
{
|
||||
return mime_decoder_init (mime_yencode, output_fn, closure);
|
||||
}
|
||||
|
||||
int
|
||||
MimeDecoderWrite (MimeDecoderData *data, const char *buffer, PRInt32 size)
|
||||
{
|
||||
@ -615,6 +829,8 @@ MimeDecoderWrite (MimeDecoderData *data, const char *buffer, PRInt32 size)
|
||||
return mime_decode_qp_buffer (data, buffer, size);
|
||||
case mime_uuencode:
|
||||
return mime_decode_uue_buffer (data, buffer, size);
|
||||
case mime_yencode:
|
||||
return mime_decode_yenc_buffer (data, buffer, size);
|
||||
default:
|
||||
NS_ASSERTION(0, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
|
||||
return -1;
|
||||
|
@ -372,7 +372,7 @@ MimeHeaders_get (MimeHeaders *hdrs, const char *header_name,
|
||||
if (!head) continue;
|
||||
|
||||
/* Quick hack to skip over BSD Mailbox delimiter. */
|
||||
if (i == 0 && head[0] == 'F' && !nsCRT::strncmp(head, "From ", 5))
|
||||
if (i == 0 && head[0] == 'F' && !strncmp(head, "From ", 5))
|
||||
continue;
|
||||
|
||||
/* Find the colon. */
|
||||
@ -732,7 +732,7 @@ MimeHeaders_write_all_headers (MimeHeaders *hdrs, MimeDisplayOptions *opt, PRBoo
|
||||
hdr_value = 0;
|
||||
|
||||
/* Hack for BSD Mailbox delimiter. */
|
||||
if (i == 0 && head[0] == 'F' && !nsCRT::strncmp(head, "From ", 5))
|
||||
if (i == 0 && head[0] == 'F' && !strncmp(head, "From ", 5))
|
||||
{
|
||||
/* For now, we don't really want this header to be output so
|
||||
we are going to just continue */
|
||||
|
@ -128,6 +128,8 @@ MimeLeaf_parse_begin (MimeObject *obj)
|
||||
!nsCRT::strcasecmp(obj->encoding, ENCODING_UUENCODE3) ||
|
||||
!nsCRT::strcasecmp(obj->encoding, ENCODING_UUENCODE4))
|
||||
fn = &MimeUUDecoderInit;
|
||||
else if (!nsCRT::strcasecmp(obj->encoding, ENCODING_YENCODE))
|
||||
fn = &MimeYDecoderInit;
|
||||
|
||||
if (fn)
|
||||
{
|
||||
|
@ -1577,8 +1577,8 @@ mime_bridge_create_display_stream(
|
||||
}
|
||||
|
||||
if (msd->options->headers == MimeHeadersMicro &&
|
||||
(msd->url_name == NULL || (nsCRT::strncmp(msd->url_name, "news:", 5) != 0 &&
|
||||
nsCRT::strncmp(msd->url_name, "snews:", 6) != 0)) )
|
||||
(msd->url_name == NULL || (strncmp(msd->url_name, "news:", 5) != 0 &&
|
||||
strncmp(msd->url_name, "snews:", 6) != 0)) )
|
||||
msd->options->headers = MimeHeadersMicroPlus;
|
||||
|
||||
msd->options->url = msd->url_name;
|
||||
|
@ -401,6 +401,8 @@ MimeMultipartSigned_parse_line (char *line, PRInt32 length, MimeObject *obj)
|
||||
!nsCRT::strcasecmp(encoding.get(), ENCODING_UUENCODE3) ||
|
||||
!nsCRT::strcasecmp(encoding.get(), ENCODING_UUENCODE4))
|
||||
fn = &MimeUUDecoderInit;
|
||||
else if (!nsCRT::strcasecmp(encoding.get(), ENCODING_YENCODE))
|
||||
fn = &MimeYDecoderInit;
|
||||
if (fn)
|
||||
{
|
||||
sig->sig_decoder_data =
|
||||
|
@ -369,7 +369,7 @@ MimeMultipart_check_boundary(MimeObject *obj, const char *line, PRInt32 length)
|
||||
if (term_p)
|
||||
length -= 2;
|
||||
|
||||
if (blen == length-2 && !nsCRT::strncmp(line+2, mult->boundary, length-2))
|
||||
if (blen == length-2 && !strncmp(line+2, mult->boundary, length-2))
|
||||
return (term_p
|
||||
? MimeMultipartBoundaryTypeTerminator
|
||||
: MimeMultipartBoundaryTypeSeparator);
|
||||
|
@ -221,7 +221,7 @@ MimeObject_parse_begin (MimeObject *obj)
|
||||
if (mime_typep(obj->parent, (MimeObjectClass*) &mimeMessageClass) ||
|
||||
mime_typep(obj->parent, (MimeObjectClass*) &mimeMultipartAppleDoubleClass))
|
||||
{
|
||||
obj->output_p = !nsCRT::strncmp((const char*)id, (const char*)obj->options->part_to_load,
|
||||
obj->output_p = !strncmp((const char*)id, (const char*)obj->options->part_to_load,
|
||||
(unsigned int)strlen(obj->options->part_to_load));
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,12 @@ static PRBool MimeUntypedText_uu_begin_line_p(const char *line, PRInt32 length,
|
||||
char **name_ret);
|
||||
static PRBool MimeUntypedText_uu_end_line_p(const char *line, PRInt32 length);
|
||||
|
||||
static PRBool MimeUntypedText_yenc_begin_line_p(const char *line, PRInt32 length,
|
||||
MimeDisplayOptions *opt,
|
||||
char **type_ret,
|
||||
char **name_ret);
|
||||
static PRBool MimeUntypedText_yenc_end_line_p(const char *line, PRInt32 length);
|
||||
|
||||
static PRBool MimeUntypedText_binhex_begin_line_p(const char *line,
|
||||
PRInt32 length,
|
||||
MimeDisplayOptions *opt);
|
||||
@ -154,6 +160,21 @@ MimeUntypedText_parse_line (char *line, PRInt32 length, MimeObject *obj)
|
||||
begin_line_p = PR_TRUE;
|
||||
}
|
||||
|
||||
else if (line[0] == '=' &&
|
||||
MimeUntypedText_yenc_begin_line_p(line, length, obj->options,
|
||||
&type, &name))
|
||||
{
|
||||
/* Close the old part and open a new one. */
|
||||
status = MimeUntypedText_open_subpart (obj,
|
||||
MimeUntypedTextSubpartTypeYEnc,
|
||||
type, ENCODING_YENCODE,
|
||||
name, NULL);
|
||||
PR_FREEIF(name);
|
||||
PR_FREEIF(type);
|
||||
if (status < 0) return status;
|
||||
begin_line_p = PR_TRUE;
|
||||
}
|
||||
|
||||
else if (line[0] == '(' && line[1] == 'T' &&
|
||||
MimeUntypedText_binhex_begin_line_p(line, length, obj->options))
|
||||
{
|
||||
@ -202,14 +223,22 @@ MimeUntypedText_parse_line (char *line, PRInt32 length, MimeObject *obj)
|
||||
{
|
||||
status = MimeUntypedText_close_subpart (obj);
|
||||
if (status < 0) return status;
|
||||
PR_ASSERT(!uty->open_subpart);
|
||||
NS_ASSERTION(!uty->open_subpart, "no open subpart");
|
||||
}
|
||||
else if (line[0] == '=' &&
|
||||
uty->type == MimeUntypedTextSubpartTypeYEnc &&
|
||||
MimeUntypedText_yenc_end_line_p(line, length))
|
||||
{
|
||||
status = MimeUntypedText_close_subpart (obj);
|
||||
if (status < 0) return status;
|
||||
NS_ASSERTION(!uty->open_subpart, "no open subpart");
|
||||
}
|
||||
else if (uty->type == MimeUntypedTextSubpartTypeBinhex &&
|
||||
MimeUntypedText_binhex_end_line_p(line, length))
|
||||
{
|
||||
status = MimeUntypedText_close_subpart (obj);
|
||||
if (status < 0) return status;
|
||||
PR_ASSERT(!uty->open_subpart);
|
||||
NS_ASSERTION(!uty->open_subpart, "no open subpart");
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -274,8 +303,8 @@ MimeUntypedText_open_subpart (MimeObject *obj,
|
||||
status = MimeUntypedText_close_subpart (obj);
|
||||
if (status < 0) return status;
|
||||
}
|
||||
PR_ASSERT(!uty->open_subpart);
|
||||
PR_ASSERT(!uty->open_hdrs);
|
||||
NS_ASSERTION(!uty->open_subpart, "no open subpart");
|
||||
NS_ASSERTION(!uty->open_hdrs, "no open headers");
|
||||
|
||||
/* To make one of these implicitly-typed sub-objects, we make up a fake
|
||||
header block, containing only the minimum number of MIME headers needed.
|
||||
@ -400,7 +429,7 @@ MimeUntypedText_uu_begin_line_p(const char *line, PRInt32 length,
|
||||
if (type_ret) *type_ret = 0;
|
||||
if (name_ret) *name_ret = 0;
|
||||
|
||||
if (nsCRT::strncmp (line, "begin ", 6)) return PR_FALSE;
|
||||
if (strncmp (line, "begin ", 6)) return PR_FALSE;
|
||||
/* ...then three or four octal digits. */
|
||||
s = line + 6;
|
||||
if (*s < '0' || *s > '7') return PR_FALSE;
|
||||
@ -482,6 +511,78 @@ MimeUntypedText_uu_end_line_p(const char *line, PRInt32 length)
|
||||
#endif
|
||||
}
|
||||
|
||||
static PRBool
|
||||
MimeUntypedText_yenc_begin_line_p(const char *line, PRInt32 length,
|
||||
MimeDisplayOptions *opt,
|
||||
char **type_ret, char **name_ret)
|
||||
{
|
||||
const char *s;
|
||||
const char *endofline = line + length;
|
||||
char *name = 0;
|
||||
char *type = 0;
|
||||
|
||||
if (type_ret) *type_ret = 0;
|
||||
if (name_ret) *name_ret = 0;
|
||||
|
||||
/* we don't support yenc V2 neither multipart yencode,
|
||||
therefore the second parameter should always be "line="*/
|
||||
if (length < 13 || strncmp (line, "=ybegin line=", 13)) return PR_FALSE;
|
||||
|
||||
/* ...then couple digits. */
|
||||
for (s = line + 13; s < endofline; s ++)
|
||||
if (*s < '0' || *s > '9')
|
||||
break;
|
||||
|
||||
/* ...next, look for <space>size= */
|
||||
if ((endofline - s) < 6 || strncmp (s, " size=", 6)) return PR_FALSE;
|
||||
|
||||
/* ...then couple digits. */
|
||||
for (s += 6; s < endofline; s ++)
|
||||
if (*s < '0' || *s > '9')
|
||||
break;
|
||||
|
||||
/* ...next, look for <space>name= */
|
||||
if ((endofline - s) < 6 || strncmp (s, " name=", 6)) return PR_FALSE;
|
||||
|
||||
/* anything left is the file name */
|
||||
s += 6;
|
||||
name = (char *) PR_MALLOC((endofline-s) + 1);
|
||||
if (!name) return PR_FALSE; /* grr... */
|
||||
memcpy(name, s, endofline-s);
|
||||
name[endofline-s] = 0;
|
||||
|
||||
/* take off newline. */
|
||||
if (name[strlen(name)-1] == nsCRT::LF) name[strlen(name)-1] = 0;
|
||||
if (name[strlen(name)-1] == nsCRT::CR) name[strlen(name)-1] = 0;
|
||||
|
||||
/* Now try and figure out a type.
|
||||
*/
|
||||
if (opt && opt->file_type_fn)
|
||||
type = opt->file_type_fn(name, opt->stream_closure);
|
||||
else
|
||||
type = 0;
|
||||
|
||||
if (name_ret)
|
||||
*name_ret = name;
|
||||
else
|
||||
PR_FREEIF(name);
|
||||
|
||||
if (type_ret)
|
||||
*type_ret = type;
|
||||
else
|
||||
PR_FREEIF(type);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
MimeUntypedText_yenc_end_line_p(const char *line, PRInt32 length)
|
||||
{
|
||||
if (length < 11 || strncmp (line, "=yend size=", 11)) return PR_FALSE;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
#define BINHEX_MAGIC "(This file must be converted with BinHex 4.0)"
|
||||
#define BINHEX_MAGIC_LEN 45
|
||||
@ -499,7 +600,7 @@ MimeUntypedText_binhex_begin_line_p(const char *line, PRInt32 length,
|
||||
if (length != BINHEX_MAGIC_LEN)
|
||||
return PR_FALSE;
|
||||
|
||||
if (!nsCRT::strncmp(line, BINHEX_MAGIC, BINHEX_MAGIC_LEN))
|
||||
if (!strncmp(line, BINHEX_MAGIC, BINHEX_MAGIC_LEN))
|
||||
return PR_TRUE;
|
||||
else
|
||||
return PR_FALSE;
|
||||
|
@ -85,6 +85,7 @@ extern MimeUntypedTextClass mimeUntypedTextClass;
|
||||
typedef enum {
|
||||
MimeUntypedTextSubpartTypeText, /* text/plain */
|
||||
MimeUntypedTextSubpartTypeUUE, /* uuencoded data */
|
||||
MimeUntypedTextSubpartTypeYEnc, /* yencoded data */
|
||||
MimeUntypedTextSubpartTypeBinhex /* Mac BinHex data */
|
||||
} MimeUntypedTextSubpartType;
|
||||
|
||||
|
@ -71,6 +71,10 @@ MimeDecoderData *MimeUUDecoderInit (nsresult (*output_fn) (const char *buf,
|
||||
PRInt32 size,
|
||||
void *closure),
|
||||
void *closure);
|
||||
MimeDecoderData *MimeYDecoderInit (nsresult (*output_fn) (const char *buf,
|
||||
PRInt32 size,
|
||||
void *closure),
|
||||
void *closure);
|
||||
|
||||
MimeEncoderData *MimeB64EncoderInit(nsresult (*output_fn) (const char *buf,
|
||||
PRInt32 size,
|
||||
|
@ -170,6 +170,7 @@
|
||||
#define ENCODING_UUENCODE2 "x-uue"
|
||||
#define ENCODING_UUENCODE3 "uuencode"
|
||||
#define ENCODING_UUENCODE4 "uue"
|
||||
#define ENCODING_YENCODE "x-yencode"
|
||||
|
||||
/* Some names of parameters that various MIME headers include.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user