hypermail patches
Paul DuBois
dubois@primate.wisc.edu
http://www.primate.wisc.edu/people/dubois
24 May 1996
This file contains patches to correct certain problems with
hypermail 1.02. The following problems were found by me:
parse.c:
- Off-by-one errors in string-collection loops can cause buffer overwrites
- Mailbox files that begin with blank lines can send hypermail
into an infinite loop
string.c:
- Incorrect hyperlink written for in-reply-to's (was generating 3-digit
link references, whereas files are written with 4-digit names)
In addition, for parse.c:
/* The getid subroutine in the next line was modified by Patrick Goebel
(02/14/1996) to avoid a segmentation fault when messages have
non-standard message ids. Some mailers are sending out message
ids that aren't enclosed in <...> or begin on the next line.
The modifications were modelled on the getsubject routine that
follows.
*/
To apply these patches, you should be in the hypermail source
directory. Just feed this file into patch:
% patch < hm-patches
*** hypermail.h.orig Sun Jul 31 20:01:50 1994
--- hypermail.h Fri May 24 15:06:55 1996
***************
*** 19,24 ****
--- 19,25 ----
#define NONAME "(no name)"
#define NODATE "(no date)"
#define NOEMAIL "(no email)"
+ #define NOMSGID "(no message-id)"
#define NOSUBJECT "(no subject)"
#define MAXLINE 1000
#define MAXFILELEN 100
***************
*** 26,32 ****
#define NUMSTRLEN 10
#define MAILSTRLEN 80
#define DATESTRLEN 80
! #define MSGDSTRLEN 80
#define REPYSTRLEN 240
#define SUBJSTRLEN 100
#define URLSTRLEN 100
--- 27,33 ----
#define NUMSTRLEN 10
#define MAILSTRLEN 80
#define DATESTRLEN 80
! #define MSGDSTRLEN 80 /* must be <= REPLYSTRLEN */
#define REPYSTRLEN 240
#define SUBJSTRLEN 100
#define URLSTRLEN 100
*** parse.c.orig Sun Jul 31 20:35:51 1994
--- parse.c Fri May 24 15:03:49 1996
***************
*** 25,31 ****
--- 25,33 ----
line[MAXLINE], tmpfrom[MAXLINE], fromdate[DATESTRLEN],
oldline[MAXLINE];
int num, isinheader, hassubject, hasdate, wasinreply;
+ int skipblanks;
struct body *bp;
+ char *c;
if (!strcmp(mbox, "NONE") || use_stdin)
fp = stdin;
***************
*** 45,50 ****
--- 47,53 ----
hasdate = 0;
wasinreply = 0;
isinheader = 1;
+ skipblanks = 1; /* true only at top of file */
inreply[0] = '\0';
tmpfrom[0] = '\0';
oldline[0] = '\0';
***************
*** 64,69 ****
--- 67,77 ----
printf("Loading mailbox \"%s\"... ", mbox);
}
while (fgets(line, MAXLINE, fp) != NULL) {
+ if (skipblanks) { /* skip blank lines at top of file */
+ if (*line == '\n')
+ continue;
+ skipblanks = 0;
+ }
if (isinheader) {
if (!strncmp(line, "Received:", 9) ||
!strncmp(line, "Return-Path:", 12) ||
***************
*** 84,89 ****
--- 92,103 ----
}
else if (!strncmp(line, "Message-Id:", 11)) {
bp = (struct body *) addbody(bp, line);
+
+ /* The getid subroutine in the next line was patched
+ to avoid a segmentation fault from strchr when messages
+ have non-standard message ids.
+ */
+
strcpy(msgid, (char *) getid(line));
}
else if (!strncmp(line, "Subject:", 8)) {
***************
*** 516,522 ****
c += 2;
while (isspace(*c))
c++;
! for (i = 0; *c && *c != '\n' && i < DATESTRLEN; c++)
date[i++] = *c;
date[i] = '\0';
--- 530,536 ----
c += 2;
while (isspace(*c))
c++;
! for (i = 0; *c && *c != '\n' && i < DATESTRLEN - 1; c++)
date[i++] = *c;
date[i] = '\0';
***************
*** 539,545 ****
if (days[i] == NULL)
tmpdate[0] = '\0';
else {
! for (i = 0; *c && *c != '\n' && i < DATESTRLEN; c++)
tmpdate[i++] = *c;
tmpdate[i] = '\0';
if (tmpdate[16] != ':') {
--- 553,559 ----
if (days[i] == NULL)
tmpdate[0] = '\0';
else {
! for (i = 0; *c && *c != '\n' && i < DATESTRLEN - 1; c++)
tmpdate[i++] = *c;
tmpdate[i] = '\0';
if (tmpdate[16] != ':') {
***************
*** 578,584 ****
while (isspace(*c))
c++;
for (i = 0; *c && *c != '(' && *c != ' ' &&
! *c != '\n' && i < MAILSTRLEN; c++)
email[i++] = *c;
email[i] = '\0';
}
--- 592,598 ----
while (isspace(*c))
c++;
for (i = 0; *c && *c != '(' && *c != ' ' &&
! *c != '\n' && i < MAILSTRLEN - 1; c++)
email[i++] = *c;
email[i] = '\0';
}
***************
*** 590,596 ****
c--;
c++;
for (i = 0; *c && *c != '>' && *c != ' ' && *c != '\n' &&
! i < MAILSTRLEN;
c++)
email[i++] = *c;
email[i] = '\0';
--- 604,610 ----
c--;
c++;
for (i = 0; *c && *c != '>' && *c != ' ' && *c != '\n' &&
! i < MAILSTRLEN - 1;
c++)
email[i++] = *c;
email[i] = '\0';
***************
*** 612,618 ****
}
for (i = 0; *c && *c != '<' && *c != '\"' && *c != ')' &&
! *c != '(' && *c != '\n' && i < NAMESTRLEN; c++)
name[i++] = *c;
if (*c == '<' || *c == '(')
name[--i] = '\0';
--- 626,632 ----
}
for (i = 0; *c && *c != '<' && *c != '\"' && *c != ')' &&
! *c != '(' && *c != '\n' && i < NAMESTRLEN - 1; c++)
name[i++] = *c;
if (*c == '<' || *c == '(')
name[--i] = '\0';
***************
*** 623,628 ****
--- 637,650 ----
/* Grabs the message ID, like <...> from the Message-ID: header.
*/
+ /* The getid subroutine in the next line was modified by Patrick Goebel
+ (02/14/1996) to avoid a segmentation fault when messages have
+ non-standard message ids. Some mailers are sending out message
+ ids that aren't enclosed in <...> or begin on the next line.
+ The modifications were modelled on the getsubject routine that
+ follows.
+ */
+
char *getid(line)
char *line;
{
***************
*** 630,643 ****
char *c;
static char msgid[MSGDSTRLEN];
! c = (char *) strchr(line, '<') + 1;
! for (i = 0; *c && *c != '>' && *c != '\n' && i < MSGDSTRLEN; c++) {
! if (*c == '\\')
continue;
msgid[i++] = *c;
}
msgid[i] = '\0';
return msgid;
}
--- 652,673 ----
char *c;
static char msgid[MSGDSTRLEN];
! c = (char *) strchr(line, ':') + 2;
! while (isspace(*c))
! c++;
!
! for (i = 0; *c && *c != '\n' && i < MSGDSTRLEN - 1; c++) {
! if (*c == '\\' || *c == '<' || *c == '>')
continue;
msgid[i++] = *c;
}
msgid[i] = '\0';
+ for (i--; i >= 0 && isspace(msgid[i]); i--)
+ msgid[i] = '\0';
+ if (msgid[0] == NULL || isspace(msgid[0]) || msgid[0] == '\n')
+ strcpy(msgid, NOMSGID);
+
return msgid;
}
***************
*** 654,660 ****
c = (char *) strchr(line, ':') + 2;
while (isspace(*c))
c++;
! for (i = 0; *c && *c != '\n' && i < SUBJSTRLEN; c++)
subject[i++] = *c;
subject[i] = '\0';
for (i--; i >= 0 && isspace(subject[i]); i--)
--- 684,690 ----
c = (char *) strchr(line, ':') + 2;
while (isspace(*c))
c++;
! for (i = 0; *c && *c != '\n' && i < SUBJSTRLEN - 1; c++)
subject[i++] = *c;
subject[i] = '\0';
for (i--; i >= 0 && isspace(subject[i]); i--)
***************
*** 680,686 ****
if ((c = (char *) strstr(line, "dated: ")) != NULL) {
c += 7;
! for (i = 0; *c && *c != '.' && *c != '\n' && i < REPYSTRLEN;
c++)
reply[i++] = *c;
reply[i] = '\0';
--- 710,716 ----
if ((c = (char *) strstr(line, "dated: ")) != NULL) {
c += 7;
! for (i = 0; *c && *c != '.' && *c != '\n' && i < REPYSTRLEN - 1;
c++)
reply[i++] = *c;
reply[i] = '\0';
***************
*** 689,695 ****
if ((c = (char *) strchr(line, '<')) != NULL ) {
c++;
! for (i = 0; *c && *c != '>' && *c != '\n' && i < MSGDSTRLEN;
c++) {
if (*c == '\\')
continue;
--- 719,725 ----
if ((c = (char *) strchr(line, '<')) != NULL ) {
c++;
! for (i = 0; *c && *c != '>' && *c != '\n' && i < MSGDSTRLEN - 1;
c++) {
if (*c == '\\')
continue;
***************
*** 704,710 ****
if (*c == '\"')
c++;
for (i = 0; *c && *c != '.' && *c != '\n' && *c != 'f' &&
! i < REPYSTRLEN; c++)
reply[i++] = *c;
reply[i] = '\0';
if (*c == 'f')
--- 734,740 ----
if (*c == '\"')
c++;
for (i = 0; *c && *c != '.' && *c != '\n' && *c != 'f' &&
! i < REPYSTRLEN - 1; c++)
reply[i++] = *c;
reply[i] = '\0';
if (*c == 'f')
***************
*** 715,717 ****
--- 745,748 ----
reply[0] = '\0';
return reply;
}
+
*** string.c.orig Mon Aug 1 01:04:55 1994
--- string.c Fri May 17 10:32:53 1996
***************
*** 96,102 ****
i++;
}
tmpline3[j] = '\0';
! sprintf(tmpline3, "%s",
tmpline3, status);
for (j = strlen(tmpline3); tmpline4[i] &&
tmpline4[i] != '\n' && j < MAXLINE; i++)
--- 96,102 ----
i++;
}
tmpline3[j] = '\0';
! sprintf(tmpline3, "%s",
tmpline3, status);
for (j = strlen(tmpline3); tmpline4[i] &&
tmpline4[i] != '\n' && j < MAXLINE; i++)