Browse Source

modifications for memoryhole and main texts in attachments

pull/2/merge
Krista Grothoff 6 years ago
parent
commit
27bab78968
5 changed files with 257 additions and 186 deletions
  1. +0
    -1
      build-windows/build_headers.list
  2. +65
    -19
      src/low-level/imf/mailimf.c
  3. +188
    -166
      src/low-level/mime/mailmime_content.c
  4. +3
    -0
      src/low-level/mime/mailmime_types.c
  5. +1
    -0
      src/low-level/mime/mailmime_types.h

+ 0
- 1
build-windows/build_headers.list View File

@ -129,7 +129,6 @@ src\low-level\mh\mailmh.h
src\low-level\mime\mailmime.h
src\low-level\mime\mailmime_content.h
src\low-level\mime\mailmime_decode.h
src\low-level\mime\mailmime_encode.h
src\low-level\mime\mailmime_disposition.h
src\low-level\mime\mailmime_types.h
src\low-level\mime\mailmime_types_helper.h


+ 65
- 19
src/low-level/imf/mailimf.c View File

@ -574,15 +574,15 @@ mailimf_struct_multiple_parse(const char * message, size_t length,
r = parser(message, length, &cur_token, &value);
if (r != MAILIMF_NO_ERROR) {
if (r == MAILIMF_ERROR_PARSE)
break;
break;
else {
res = r;
goto free;
res = r;
goto free;
}
}
r = clist_append(struct_list, value);
if (r < 0) {
(* destructor)(value);
(*destructor)(value);
res = MAILIMF_ERROR_MEMORY;
goto free;
}
@ -7529,30 +7529,26 @@ int mailimf_envelope_fields_parse(const char * message, size_t length,
}
while (1) {
struct mailimf_field * elt;
struct mailimf_field *elt;
r = mailimf_envelope_field_parse(message, length, &cur_token, &elt);
if (r == MAILIMF_NO_ERROR) {
r = clist_append(list, elt);
if (r < 0) {
res = MAILIMF_ERROR_MEMORY;
goto free;
res = MAILIMF_ERROR_MEMORY;
goto free;
}
}
else if (r == MAILIMF_ERROR_PARSE) {
} else if (r == MAILIMF_ERROR_PARSE) {
r = mailimf_ignore_field_parse(message, length, &cur_token);
if (r == MAILIMF_NO_ERROR) {
/* do nothing */
}
else if (r == MAILIMF_ERROR_PARSE) {
break;
}
else {
res = r;
goto free;
/* do nothing */
} else if (r == MAILIMF_ERROR_PARSE) {
break;
} else {
res = r;
goto free;
}
}
else {
} else {
res = r;
goto free;
}
@ -7776,3 +7772,53 @@ mailimf_optional_fields_parse(const char * message, size_t length,
err:
return res;
}
LIBETPAN_EXPORT
int
mailimf_memoryhole_fields_parse(const char * message, size_t length,
size_t * indx,
struct mailimf_fields ** result)
{
size_t cur_token;
clist * list;
struct mailimf_fields * fields;
int r = MAILIMF_ERROR_PARSE;
int res;
cur_token = * indx;
list = NULL;
const char* rfc822_header_string = "Content-Type: text/rfc822-headers;";
const size_t rfc822_header_strlen = 34;
const char* cur_char = message + cur_token;
if ((cur_token + rfc822_header_strlen) <= length &&
strncmp(cur_char, rfc822_header_string, rfc822_header_strlen) == 0) {
r = mailimf_envelope_fields_parse(message, length, &cur_token,
result);
}
switch (r) {
case MAILIMF_NO_ERROR:
/* do nothing */
break;
default:
res = r;
goto err;
}
* indx = cur_token;
return MAILIMF_NO_ERROR;
free:
if (list != NULL) {
clist_foreach(list, (clist_func) mailimf_field_free, NULL);
clist_free(list);
}
err:
return res;
}

+ 188
- 166
src/low-level/mime/mailmime_content.c View File

@ -790,35 +790,35 @@ int mailmime_multipart_next_parse(const char * message, size_t length,
if (cur_token >= length)
return MAILIMF_ERROR_PARSE;
switch(state) {
switch (state) {
case MULTIPART_NEXT_STATE_0:
switch (message[cur_token]) {
case ' ':
state = MULTIPART_NEXT_STATE_0;
break;
state = MULTIPART_NEXT_STATE_0;
break;
case '\t':
state = MULTIPART_NEXT_STATE_0;
break;
state = MULTIPART_NEXT_STATE_0;
break;
case '\r':
state = MULTIPART_NEXT_STATE_1;
break;
state = MULTIPART_NEXT_STATE_1;
break;
case '\n':
state = MULTIPART_NEXT_STATE_2;
break;
state = MULTIPART_NEXT_STATE_2;
break;
default:
return MAILIMF_ERROR_PARSE;
return MAILIMF_ERROR_PARSE;
}
break;
case MULTIPART_NEXT_STATE_1:
switch (message[cur_token]) {
case '\n':
state = MULTIPART_NEXT_STATE_2;
break;
state = MULTIPART_NEXT_STATE_2;
break;
default:
return MAILIMF_ERROR_PARSE;
return MAILIMF_ERROR_PARSE;
}
break;
}
@ -831,6 +831,7 @@ int mailmime_multipart_next_parse(const char * message, size_t length,
return MAILIMF_NO_ERROR;
}
/* N.B. Modified to allow add enigmail memoryhole Subject header to fields. */
static int
mailmime_multipart_body_parse(const char * message, size_t length,
size_t * indx, char * boundary,
@ -911,13 +912,14 @@ mailmime_multipart_body_parse(const char * message, size_t length,
preamble_length = preamble_end - preamble_begin;
part_begin = cur_token;
while (1) {
r = mailmime_lwsp_parse(message, length, &cur_token);
if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
res = r;
goto err;
}
r = mailimf_crlf_parse(message, length, &cur_token);
if (r == MAILIMF_NO_ERROR) {
part_begin = cur_token;
@ -941,7 +943,10 @@ mailmime_multipart_body_parse(const char * message, size_t length,
}
final_part = 0;
/* Go through the whole block of parts corresponding to this boundary,
parse each by consuming each one and going back to the top of
the loop */
while (!final_part) {
size_t bp_token;
struct mailmime * mime_bp;
@ -949,7 +954,7 @@ mailmime_multipart_body_parse(const char * message, size_t length,
size_t data_size;
struct mailimf_fields * fields;
struct mailmime_fields * mime_fields;
r = mailmime_body_part_dash2_transport_crlf_parse(message, length,
&cur_token, boundary, &data_str, &data_size);
if (r == MAILIMF_ERROR_PARSE) {
@ -962,29 +967,44 @@ mailmime_multipart_body_parse(const char * message, size_t length,
if (r == MAILIMF_NO_ERROR) {
bp_token = 0;
r = mailimf_optional_fields_parse(data_str, data_size,
struct mailimf_fields * envelope_fields = NULL;
int is_memoryhole_part = 0;
r = mailimf_memoryhole_fields_parse(data_str, data_size,
&bp_token, &fields);
if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
res = r;
goto free;
}
r = mailimf_crlf_parse(data_str, data_size, &bp_token);
if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
mailimf_fields_free(fields);
res = r;
goto free;
}
if (r == MAILIMF_NO_ERROR) {
is_memoryhole_part = 1;
}
else {
r = mailimf_optional_fields_parse(data_str, data_size,
&bp_token, &fields);
if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
res = r;
goto free;
}
r = mailimf_crlf_parse(data_str, data_size, &bp_token);
if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
mailimf_fields_free(fields);
res = r;
goto free;
}
}
mime_fields = NULL;
r = mailmime_fields_parse(fields, &mime_fields);
mailimf_fields_free(fields);
/* mailimf_fields_free(fields); */ /* we don't do this now to preserve for memoryhole */
if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
res = r;
goto free;
}
r = mailmime_parse_with_default(data_str, data_size,
&bp_token, default_subtype, NULL,
mime_fields, &mime_bp);
@ -1006,6 +1026,8 @@ mailmime_multipart_body_parse(const char * message, size_t length,
goto free;
}
mime_bp->mm_imf_fields = fields;
r = mailmime_multipart_next_parse(message, length, &cur_token);
if (r == MAILIMF_NO_ERROR) {
/* do nothing */
@ -1089,7 +1111,8 @@ mailmime_multipart_body_parse(const char * message, size_t length,
enum {
MAILMIME_DEFAULT_TYPE_TEXT_PLAIN,
MAILMIME_DEFAULT_TYPE_MESSAGE
MAILMIME_DEFAULT_TYPE_MESSAGE,
MAILMIME_DEFAULT_TYPE_RFC2822_EXTRA_HEADERS
};
@ -1240,29 +1263,28 @@ static void remove_unparsed_mime_headers(struct mailimf_fields * fields)
}
}
static int mailmime_parse_with_default(const char * message, size_t length,
size_t * indx, int default_type,
struct mailmime_content * content_type,
struct mailmime_fields * mime_fields,
struct mailmime ** result)
{
static int mailmime_parse_with_default(const char *message, size_t length,
size_t *indx, int default_type,
struct mailmime_content *content_type,
struct mailmime_fields *mime_fields,
struct mailmime **result) {
size_t cur_token;
int body_type;
int encoding;
struct mailmime_data * body;
char * boundary;
struct mailimf_fields * fields;
clist * list;
struct mailmime * msg_mime;
struct mailmime_data *body;
char *boundary;
struct mailimf_fields *fields;
clist *list;
struct mailmime *msg_mime;
struct mailmime * mime;
struct mailmime *mime;
int r;
int res;
struct mailmime_data * preamble;
struct mailmime_data * epilogue;
struct mailmime_data *preamble;
struct mailmime_data *epilogue;
/*
note that when this function is called, content type is always detached,
@ -1271,23 +1293,23 @@ static int mailmime_parse_with_default(const char * message, size_t length,
preamble = NULL;
epilogue = NULL;
cur_token = * indx;
cur_token = *indx;
/* get content type */
if (content_type == NULL) {
if (mime_fields != NULL) {
clistiter * cur;
for(cur = clist_begin(mime_fields->fld_list) ; cur != NULL ;
cur = clist_next(cur)) {
struct mailmime_field * field;
clistiter *cur;
for (cur = clist_begin(mime_fields->fld_list); cur != NULL;
cur = clist_next(cur)) {
struct mailmime_field *field;
field = clist_content(cur);
if (field->fld_type == MAILMIME_FIELD_TYPE) {
content_type = field->fld_data.fld_content;
/* detach content type from list */
field->fld_data.fld_content = NULL;
clist_delete(mime_fields->fld_list, cur);
@ -1309,17 +1331,16 @@ static int mailmime_parse_with_default(const char * message, size_t length,
if (default_type == MAILMIME_DEFAULT_TYPE_TEXT_PLAIN) {
content_type = mailmime_get_content_text();
if (content_type == NULL) {
res = MAILIMF_ERROR_MEMORY;
goto err;
res = MAILIMF_ERROR_MEMORY;
goto err;
}
}
else /* message */ {
} else /* message */ {
body_type = MAILMIME_MESSAGE;
content_type = mailmime_get_content_message();
if (content_type == NULL) {
res = MAILIMF_ERROR_MEMORY;
goto err;
res = MAILIMF_ERROR_MEMORY;
goto err;
}
}
}
@ -1333,19 +1354,19 @@ static int mailmime_parse_with_default(const char * message, size_t length,
switch (content_type->ct_type->tp_data.tp_composite_type->ct_type) {
case MAILMIME_COMPOSITE_TYPE_MULTIPART:
boundary = mailmime_extract_boundary(content_type);
if (boundary == NULL)
body_type = MAILMIME_SINGLE;
body_type = MAILMIME_SINGLE;
else
body_type = MAILMIME_MULTIPLE;
body_type = MAILMIME_MULTIPLE;
break;
case MAILMIME_COMPOSITE_TYPE_MESSAGE:
if (strcasecmp(content_type->ct_subtype, "rfc822") == 0)
body_type = MAILMIME_MESSAGE;
body_type = MAILMIME_MESSAGE;
else
body_type = MAILMIME_SINGLE;
body_type = MAILMIME_SINGLE;
break;
default:
@ -1365,20 +1386,19 @@ static int mailmime_parse_with_default(const char * message, size_t length,
encoding = mailmime_transfer_encoding_get(mime_fields);
else
encoding = MAILMIME_MECHANISM_8BIT;
if (body_type == MAILMIME_MESSAGE) {
switch (encoding) {
case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
case MAILMIME_MECHANISM_BASE64:
body_type = MAILMIME_SINGLE;
break;
case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
case MAILMIME_MECHANISM_BASE64:
body_type = MAILMIME_SINGLE;
break;
}
}
cur_token = * indx;
body = mailmime_data_new(MAILMIME_DATA_TEXT, encoding, 1,
message + cur_token, length - cur_token,
NULL);
cur_token = *indx;
body = mailmime_data_new(MAILMIME_DATA_TEXT, encoding, 1, message + cur_token,
length - cur_token, NULL);
if (body == NULL) {
free(boundary);
res = MAILIMF_ERROR_MEMORY;
@ -1392,107 +1412,109 @@ static int mailmime_parse_with_default(const char * message, size_t length,
fields = NULL;
switch (body_type) {
case MAILMIME_MESSAGE:
{
struct mailmime_fields * submime_fields;
r = mailimf_envelope_and_optional_fields_parse(message, length,
&cur_token, &fields);
if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
res = r;
goto free_content;
}
r = mailimf_crlf_parse(message, length, &cur_token);
if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
mailimf_fields_free(fields);
res = r;
case MAILMIME_MESSAGE: {
struct mailmime_fields *submime_fields;
r = mailimf_envelope_and_optional_fields_parse(message, length, &cur_token,
&fields);
if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
res = r;
goto free_content;
}
r = mailimf_crlf_parse(message, length, &cur_token);
if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
mailimf_fields_free(fields);
res = r;
goto free_content;
}
submime_fields = NULL;
r = mailmime_fields_parse(fields, &submime_fields);
if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
mailimf_fields_free(fields);
res = r;
goto free_content;
}
remove_unparsed_mime_headers(fields);
r = mailmime_parse_with_default(message, length, &cur_token,
MAILMIME_DEFAULT_TYPE_TEXT_PLAIN, NULL,
submime_fields, &msg_mime);
if (r == MAILIMF_NO_ERROR) {
/* do nothing */
} else if (r == MAILIMF_ERROR_PARSE) {
mailmime_fields_free(mime_fields);
msg_mime = NULL;
} else {
mailmime_fields_free(mime_fields);
res = r;
goto free_content;
}
}
break;
case MAILMIME_MULTIPLE: {
int default_subtype;
default_subtype = MAILMIME_DEFAULT_TYPE_TEXT_PLAIN;
if (content_type != NULL)
if (strcasecmp(content_type->ct_subtype, "digest") == 0)
default_subtype = MAILMIME_DEFAULT_TYPE_MESSAGE;
cur_token = *indx;
r = mailmime_multipart_body_parse(message, length, &cur_token, boundary,
default_subtype, &list, &preamble,
&epilogue);
if (r == MAILIMF_NO_ERROR) {
/* do nothing */
} else if (r == MAILIMF_ERROR_PARSE) {
list = clist_new();
if (list == NULL) {
res = MAILIMF_ERROR_MEMORY;
goto free_content;
}
submime_fields = NULL;
r = mailmime_fields_parse(fields, &submime_fields);
} else {
res = r;
goto free_content;
}
free(boundary);
} break;
default: /* MAILMIME_SINGLE */
if (strcasecmp(content_type->ct_subtype, "rfc822-headers") == 0) {
// default_subtype = MAILMIME_DEFAULT_TYPE_RFC2822_EXTRA_HEADERS;
struct mailmime_fields *submime_fields;
r = mailimf_envelope_and_optional_fields_parse(message, length,
&cur_token, &fields);
if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
mailimf_fields_free(fields);
res = r;
goto free_content;
}
remove_unparsed_mime_headers(fields);
r = mailmime_parse_with_default(message, length,
&cur_token, MAILMIME_DEFAULT_TYPE_TEXT_PLAIN,
NULL, submime_fields, &msg_mime);
if (r == MAILIMF_NO_ERROR) {
/* do nothing */
}
else if (r == MAILIMF_ERROR_PARSE) {
mailmime_fields_free(mime_fields);
msg_mime = NULL;
}
else {
mailmime_fields_free(mime_fields);
res = r;
goto free_content;
}
}
break;
case MAILMIME_MULTIPLE:
{
int default_subtype;
default_subtype = MAILMIME_DEFAULT_TYPE_TEXT_PLAIN;
if (content_type != NULL)
if (strcasecmp(content_type->ct_subtype, "digest") == 0)
default_subtype = MAILMIME_DEFAULT_TYPE_MESSAGE;
cur_token = * indx;
r = mailmime_multipart_body_parse(message, length,
&cur_token, boundary,
default_subtype,
&list, &preamble, &epilogue);
if (r == MAILIMF_NO_ERROR) {
/* do nothing */
}
else if (r == MAILIMF_ERROR_PARSE) {
list = clist_new();
if (list == NULL) {
res = MAILIMF_ERROR_MEMORY;
goto free_content;
}
}
else {
res = r;
goto free_content;
}
free(boundary);
}
break;
default: /* MAILMIME_SINGLE */
/* do nothing */
/* else do nothing */
break;
}
mime = mailmime_new(body_type, message, length,
mime_fields, content_type,
body, preamble, /* preamble */
epilogue, /* epilogue */
list, fields, msg_mime);
mime = mailmime_new(body_type, message, length, mime_fields, content_type,
body, preamble, /* preamble */
epilogue, /* epilogue */
list, fields, msg_mime);
if (mime == NULL) {
res = MAILIMF_ERROR_MEMORY;
goto free;
}
* result = mime;
* indx = length;
*result = mime;
*indx = length;
return MAILIMF_NO_ERROR;
free:
free:
if (epilogue != NULL)
mailmime_data_free(epilogue);
if (preamble != NULL)
@ -1500,12 +1522,12 @@ static int mailmime_parse_with_default(const char * message, size_t length,
if (msg_mime != NULL)
mailmime_free(msg_mime);
if (list != NULL) {
clist_foreach(list, (clist_func) mailmime_free, NULL);
clist_foreach(list, (clist_func)mailmime_free, NULL);
clist_free(list);
}
free_content:
free_content:
mailmime_content_free(content_type);
err:
err:
return res;
}


+ 3
- 0
src/low-level/mime/mailmime_types.c View File

@ -436,6 +436,7 @@ struct mailmime * mailmime_new(int mm_type,
mime->mm_mime_fields = mm_mime_fields;
mime->mm_content_type = mm_content_type;
mime->mm_imf_fields = NULL;
mime->mm_body = mm_body;
switch (mm_type) {
@ -505,6 +506,8 @@ void mailmime_free(struct mailmime * mime)
if (mime->mm_mime_fields != NULL)
mailmime_fields_free(mime->mm_mime_fields);
if (mime->mm_imf_fields != NULL)
mailimf_fields_free(mime->mm_imf_fields);
if (mime->mm_content_type != NULL)
mailmime_content_free(mime->mm_content_type);
free(mime);


+ 1
- 0
src/low-level/mime/mailmime_types.h View File

@ -322,6 +322,7 @@ struct mailmime {
struct mailmime_fields * mm_mime_fields;
struct mailmime_content * mm_content_type;
struct mailimf_fields * mm_imf_fields; /* preserves the whole set of fields from a part for memoryhole */
struct mailmime_data * mm_body;
union {


Loading…
Cancel
Save