Skip to content

Commit 6452713

Browse files
committed
- improve discarding of empty MIME epilogue lines
- improve detectionn and handling of multipart/alternative and its exceptions for the applemail_hack - when the value for applemail_ua_header was empty (""), the header match strncasecmp returned true - after choosing a mime alternative, the end process didn't reinitialize two pointers to NULL, which could cause random issues
1 parent 26fa453 commit 6452713

File tree

1 file changed

+81
-65
lines changed

1 file changed

+81
-65
lines changed

src/parse.c

Lines changed: 81 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,7 +1503,7 @@ int parsemail(char *mbox, /* file name */
15031503
FileStatus alternative_lastfile_created = NO_FILE; /* previous alternative attachments, for non-inline MIME types */
15041504
char alternative_file[129]; /* file name where we store the non-inline alternatives */
15051505
char alternative_lastfile[129]; /* last file name where we store the non-inline alternatives */
1506-
char alternative_type[129]; /* the alternative Content-Type value */
1506+
char last_alternative_type[129]; /* the alternative Content-Type value */
15071507
int att_counter = 0; /* used to generate a unique name for attachments */
15081508
int parse_multipart_alternative_force_save_alts = 0; /* used to control if we are parsing alternative as multipart */
15091509
int old_set_save_alts = -1; /* used to store the set_save_alts when overriding it for apple mail */
@@ -1534,7 +1534,7 @@ int parsemail(char *mbox, /* file name */
15341534

15351535
struct boundary *multipartp = NULL; /* This variable is used to store a stack of
15361536
mimetypes in cases with mulitpart mails */
1537-
bool waiting_for_boundary = FALSE; /* This variable is used to help skip multipart/foo
1537+
bool skip_mime_epilogue = FALSE; /* This variable is used to help skip multipart/foo
15381538
epilogues */
15391539

15401540
char multilinenoend = FALSE; /* This variable is set TRUE if we have read
@@ -1673,7 +1673,16 @@ int parsemail(char *mbox, /* file name */
16731673
progerr("Can't write to \"mbox\""); /* revisit me */
16741674
}
16751675
}
1676-
line = line_buf + set_ietf_mbox;
1676+
line = line_buf + set_ietf_mbox;
1677+
1678+
if (skip_mime_epilogue) {
1679+
if (line[0] == '\n') {
1680+
continue;
1681+
} else {
1682+
skip_mime_epilogue = FALSE;
1683+
}
1684+
}
1685+
16771686
if (!is_deleted &&
16781687
inlist_regex_pos(set_filter_out_full_body, line) != -1) {
16791688
is_deleted = FILTERED_OUT;
@@ -1824,8 +1833,8 @@ int parsemail(char *mbox, /* file name */
18241833
content_type_p = head;
18251834
}
18261835
else if (applemail_ua_header_len > 0
1827-
&& !strncasecmp(head_name, set_applemail_ua_header,
1828-
applemail_ua_header_len)) {
1836+
&& !strncasecmp(head_name, set_applemail_ua_header,
1837+
applemail_ua_header_len)) {
18291838
/* we only need to set this one up once per message*/
18301839
head->parsedheader = TRUE;
18311840
if (alternativeparser
@@ -1842,19 +1851,22 @@ int parsemail(char *mbox, /* file name */
18421851
*/
18431852
if (!parse_multipart_alternative_force_save_alts
18441853
&& is_applemail_ua(head->line + applemail_ua_header_len + 2)) {
1845-
1854+
18461855
parse_multipart_alternative_force_save_alts = 1;
1847-
old_set_save_alts = set_save_alts;
1848-
/* to avoid confusion and quoting out of
1856+
1857+
/* to avoid confusion and quoting out of
18491858
** context, we won't show the alternatives
18501859
** in-line.
18511860
*/
1861+
1862+
old_set_save_alts = set_save_alts;
18521863
set_save_alts = 2;
1864+
18531865
#if DEBUG_PARSE
18541866
printf("Applemail_hack force save_alts: yes\n");
1855-
printf("Applemail_hack set_save_alts changed from %d to %d\n",
1867+
printf("Applemail_hack set_save_alts changed from %d to %d\n",
18561868
old_set_save_alts, set_save_alts);
1857-
#endif
1869+
#endif
18581870
}
18591871
}
18601872
}
@@ -1877,7 +1889,6 @@ int parsemail(char *mbox, /* file name */
18771889
if (!headp)
18781890
headp = bp;
18791891

1880-
18811892
savealternative = FALSE;
18821893
attach_force = FALSE;
18831894

@@ -2040,16 +2051,38 @@ int parsemail(char *mbox, /* file name */
20402051
if (alternativeparser) {
20412052
struct body *next;
20422053
struct body *temp_bp = NULL;
2043-
2054+
20442055
/* We are parsing alternatives... */
20452056

2057+
if (parse_multipart_alternative_force_save_alts
2058+
&& multipartp
2059+
&& !strcasecmp(multipartp->line, "multipart/alternative")
2060+
&& *last_alternative_type
2061+
&& !strcasecmp(last_alternative_type, "text/plain")) {
2062+
2063+
/* if the UA is Apple mail and if the only
2064+
** alternatives are text/plain and
2065+
** text/html and if the preference is
2066+
** text/plain, skip the text/html version
2067+
** if the applemail_hack is enabled
2068+
*/
2069+
if (!strcasecmp(type, "text/html")) {
2070+
#if DEBUG_PARSE
2071+
fprintf(stderr, "Discarding apparently equivalent text//html alternative\n");
2072+
#endif
2073+
content = CONTENT_IGNORE;
2074+
break;
2075+
}
2076+
}
2077+
20462078
if (preferedcontent(&alternative_weight, type, decode)) {
20472079
/* ... this is a prefered type, we want to store
20482080
this [instead of the earlier one]. */
20492081
/* erase the previous alternative info */
20502082
temp_bp = alternative_bp; /* remember the value of bp for GC */
20512083
alternative_bp = alternative_lp = NULL;
2052-
strcpy(alternative_type, type);
2084+
strncpy(last_alternative_type, type,
2085+
sizeof(last_alternative_type) - 1);
20532086
alternative_lastfile_created = NO_FILE;
20542087
content = CONTENT_UNKNOWN;
20552088
if (alternative_lastfile[0] != '\0') {
@@ -2064,7 +2097,7 @@ int parsemail(char *mbox, /* file name */
20642097
/* ...and this type is not a prefered one. Thus, we
20652098
* shall ignore it completely! */
20662099
content = CONTENT_IGNORE;
2067-
/* erase the current alternative info */
2100+
/* erase the current alternative info */
20682101
temp_bp = bp; /* remember the value of bp for GC */
20692102
lp = alternative_lp;
20702103
bp = alternative_bp;
@@ -2077,7 +2110,8 @@ int parsemail(char *mbox, /* file name */
20772110
alternative_lastfile[0] = '\0';
20782111
/* we haven't yet created any attachment file, so there's no need
20792112
to erase it yet */
2080-
}
2113+
}
2114+
20812115
/* free any previous alternative */
20822116
while (temp_bp) {
20832117
next = temp_bp->next;
@@ -2086,34 +2120,13 @@ int parsemail(char *mbox, /* file name */
20862120
free(temp_bp);
20872121
temp_bp = next;
20882122
}
2123+
20892124
/* @@ not sure if I should add a diff flag to do this break */
20902125
if (content == CONTENT_IGNORE)
20912126
/* end the header parsing... we already know what we want */
20922127
break;
20932128
}
20942129

2095-
if (content == CONTENT_BINARY
2096-
&& set_save_alts && alternativeparser
2097-
&& parse_multipart_alternative_force_save_alts
2098-
&& multipartp
2099-
&& !strcasecmp(multipartp->line, "multipart/alternative")
2100-
&& (!strcasecmp(type, "text/html")
2101-
&& *alternative_type
2102-
&& !strcasecmp(alternative_type, "text/plain"))) {
2103-
/* if the UA is Apple mail and if the only
2104-
** alternatives are text/plain and
2105-
** text/html and if the preference is
2106-
** text/plain, skip the text/html version
2107-
** if the applemail_hack is enabled
2108-
*/
2109-
content = CONTENT_IGNORE;
2110-
2111-
#if DEBUG_PARSE
2112-
printf("Discarding apparently equivalent text//html alternative\n");
2113-
#endif
2114-
continue;
2115-
}
2116-
21172130
if (content == CONTENT_IGNORE)
21182131
continue;
21192132
else if (ignorecontent(type))
@@ -2268,7 +2281,7 @@ int parsemail(char *mbox, /* file name */
22682281
*/
22692282
boundp = bound(boundp, boundbuffer);
22702283
multipartp = multipart(multipartp, type);
2271-
waiting_for_boundary = FALSE;
2284+
skip_mime_epilogue = FALSE;
22722285

22732286
/* printf("set new boundary: %s\n", boundp->line); */
22742287

@@ -2388,7 +2401,7 @@ int parsemail(char *mbox, /* file name */
23882401
alternative_lp = alternative_bp = NULL;
23892402
alternative_lastfile_created = NO_FILE;
23902403
alternative_file[0] = alternative_lastfile[0] = '\0';
2391-
alternative_type[0] = '\0';
2404+
last_alternative_type[0] = '\0';
23922405
}
23932406
headp = lp; /* start at this point next time */
23942407
}
@@ -2588,7 +2601,7 @@ msgid);
25882601
content = CONTENT_TEXT;
25892602
decode = ENCODE_NORMAL;
25902603
Mime_B = FALSE;
2591-
waiting_for_boundary = FALSE;
2604+
skip_mime_epilogue = FALSE;
25922605
headp = NULL;
25932606
content_type_p = NULL;
25942607
multilinenoend = FALSE;
@@ -2681,14 +2694,13 @@ msgid);
26812694
printf("alternativeparser %d\n", alternativeparser);
26822695
printf("has_more_alternatives %d\n", has_multipart(multipartp, "multipart/alternative"));
26832696
#endif
2697+
26842698
boundp = bound(boundp, NULL);
26852699
if (!boundp) {
26862700
bodyflags &= ~BODY_ATTACHED;
2687-
waiting_for_boundary = FALSE;
2688-
} else {
2689-
/* skip the MIME epilogue until the next section */
2690-
waiting_for_boundary = TRUE;
26912701
}
2702+
/* skip the MIME epilogue until the next section (or next message!) */
2703+
skip_mime_epilogue = TRUE;
26922704
multipartp = multipart(multipartp, NULL);
26932705
if (alternativeparser
26942706
&& !has_multipart(multipartp, "multipart/alternative")) {
@@ -2709,16 +2721,16 @@ msgid);
27092721
alternative_lastfile_created = NO_FILE;
27102722
alternative_file[0] =
27112723
alternative_lastfile[0] = '\0';
2712-
alternative_type[0] = '\0';
2724+
last_alternative_type[0] = '\0';
27132725
#if DEBUG_PARSE
27142726
printf("We DUMP the chosen alternative\n");
27152727
#endif
27162728
if (bp != origbp)
27172729
origbp = append_body(origbp, &origlp, bp);
27182730
bp = origbp;
27192731
lp = origlp;
2720-
origbp = origlp = NULL;
2721-
2732+
origbp = origlp = NULL;
2733+
27222734
headp = NULL;
27232735
}
27242736
#if DEBUG_PARSE
@@ -2735,7 +2747,7 @@ msgid);
27352747
}
27362748
else {
27372749
/* we found the beginning of a new section */
2738-
waiting_for_boundary = FALSE;
2750+
skip_mime_epilogue = FALSE;
27392751

27402752
if (alternativeparser && !set_save_alts) {
27412753
/*
@@ -2748,17 +2760,12 @@ msgid);
27482760
file_created;
27492761
strcpy(alternative_lastfile,
27502762
alternative_file);
2751-
strcpy(alternative_type, type);
2763+
strncpy(last_alternative_type, type,
2764+
sizeof(last_alternative_type) - 1);
27522765

27532766
/* and now reset them */
27542767
headp = bp = lp = NULL;
27552768
alternative_file[0] = '\0';
2756-
#if 0
2757-
/* @@ JK: review if att_counter is updated even with content ignore */
2758-
if (set_save_alts && parse_multipart_alternative_force_save_alts) {
2759-
att_counter++;
2760-
}
2761-
#endif
27622769
}
27632770
else {
27642771
att_counter++;
@@ -2794,10 +2801,6 @@ msgid);
27942801
}
27952802
continue;
27962803
}
2797-
else if (waiting_for_boundary) {
2798-
/* waiting for the next '--foo' */
2799-
continue;
2800-
}
28012804
}
28022805

28032806
switch (decode) {
@@ -3074,9 +3077,8 @@ msgid);
30743077
1);
30753078
/* save the last mime type to help deal with the
30763079
* apple mail hack */
3077-
strncpy(alternative_type, type,
3078-
sizeof(alternative_type) -
3079-
1);
3080+
strncpy(last_alternative_type, type,
3081+
sizeof(last_alternative_type) - 1);
30803082
}
30813083

30823084
}
@@ -3086,7 +3088,7 @@ msgid);
30863088
alternative_file[0] = '\0';
30873089
/* save the last mime type to help deal with the apple
30883090
* hack */
3089-
alternative_type[0] = '\0';
3091+
last_alternative_type[0] = '\0';
30903092
}
30913093
}
30923094

@@ -3349,7 +3351,7 @@ msgid);
33493351
content = CONTENT_TEXT;
33503352
decode = ENCODE_NORMAL;
33513353
Mime_B = FALSE;
3352-
waiting_for_boundary = FALSE;
3354+
skip_mime_epilogue = FALSE;
33533355
headp = NULL;
33543356
multilinenoend = FALSE;
33553357
if (att_dir) {
@@ -3370,6 +3372,21 @@ msgid);
33703372
att_name_list = NULL;
33713373
description = NULL;
33723374

3375+
if (parse_multipart_alternative_force_save_alts) {
3376+
parse_multipart_alternative_force_save_alts = 0;
3377+
3378+
#if DEBUG_PARSE
3379+
printf("Applemail_hack resetting parse_multipart_alternative_force_save_alts\n");
3380+
#endif
3381+
if (old_set_save_alts != -1) {
3382+
set_save_alts = old_set_save_alts;
3383+
old_set_save_alts = -1;
3384+
#if DEBUG_PARSE
3385+
printf("Applemail_hack resetting save_alts to %d\n", old_set_save_alts);
3386+
#endif
3387+
}
3388+
}
3389+
33733390
/* by default we have none! */
33743391
hassubject = 0;
33753392
hasdate = 0;
@@ -4658,4 +4675,3 @@ int count_deleted(int limit)
46584675
}
46594676
return total;
46604677
}
4661-

0 commit comments

Comments
 (0)