# ------------------------------------------------------------------------------
# CHANGES                             |    5 ++
# WWW/Library/Implementation/HTMIME.c |   82 +++++++++++++++++++--------------
# WWW/Library/Implementation/HTMIME.h |   12 ----
# WWW/Library/Implementation/HTNews.c |   83 +++++++++-------------------------
# configure                           |    2 
# configure.in                        |    4 -
# lynx.cfg                            |    4 -
# userdefs.h                          |    4 -
# 8 files changed, 84 insertions(+), 112 deletions(-)
# ------------------------------------------------------------------------------
Index: CHANGES
--- 2.8.5rel.2/CHANGES	Thu Apr 22 16:08:10 2004
+++ 2.8.5rel.3/CHANGES	Mon Oct 17 13:47:09 2005
@@ -1,6 +1,11 @@
 Changes since Lynx 2.8 release
 ===============================================================================
 
+2004-10-17 (2.8.5rel.3 fixes from 2.8.6dev.14)
+* eliminate fixed-size buffers in LYExpandHostForURL() to guard against
+  buffer overflow resulting from too-long domain prefix/suffix data from
+  lynx.cfg (report by Ulf Harnhammar, CAN-2005-3120) -TD
+
 2004-04-22 (2.8.5rel.2 fixes from 2.8.6dev.1)
 * correct ifdef in LYgetattrs() to ensure that getattrs() is used only if the
   configure script actually found it (report/patch by Paul Gilmartin).
Index: WWW/Library/Implementation/HTMIME.c
Prereq:  0.2 
--- 2.8.5rel.2/WWW/Library/Implementation/HTMIME.c	Wed Jan  7 18:03:09 2004
+++ 2.8.5rel.3/WWW/Library/Implementation/HTMIME.c	Mon Oct 17 13:47:09 2005
@@ -2062,27 +2062,23 @@
 **
 **	Written by S. Ichikawa,
 **	partially inspired by encdec.c of <jh@efd.lth.se>.
-**	Assume caller's buffer is LINE_LENGTH bytes, these decode to
-**	no longer than the input strings.
 */
-#define LINE_LENGTH 512		/* Maximum length of line of ARTICLE etc */
-#ifdef ESC
-#undef ESC
-#endif /* ESC */
 #include <LYCharVals.h>  /* S/390 -- gil -- 0163 */
-#define ESC	CH_ESC
 
 PRIVATE char HTmm64[] =
     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" ;
 PRIVATE char HTmmquote[] = "0123456789ABCDEF";
 PRIVATE int HTmmcont = 0;
 
-PUBLIC void HTmmdec_base64 ARGS2(
-	char *,		t,
+PRIVATE void HTmmdec_base64 ARGS2(
+	char **,	t,
 	char *,		s)
 {
     int   d, count, j, val;
-    char  buf[LINE_LENGTH], *bp, nw[4], *p;
+    char *buf, *bp, nw[4], *p;
+
+    if ((buf = malloc(strlen(s) * 3 + 1)) == 0)
+	outofmem(__FILE__, "HTmmdec_base64");
 
     for (bp = buf; *s; s += 4) {
 	val = 0;
@@ -2113,14 +2109,18 @@
 	    *bp++ = nw[2];
     }
     *bp = '\0';
-    strcpy(t, buf);
+    StrAllocCopy(*t, buf);
+    FREE(buf);
 }
 
-PUBLIC void HTmmdec_quote ARGS2(
-	char *,		t,
+PRIVATE void HTmmdec_quote ARGS2(
+	char **,	t,
 	char *,		s)
 {
-    char  buf[LINE_LENGTH], cval, *bp, *p;
+    char *buf, cval, *bp, *p;
+
+    if ((buf = malloc(strlen(s) + 1)) == 0)
+	outofmem(__FILE__, "HTmmdec_quote");
 
     for (bp = buf; *s; ) {
 	if (*s == '=') {
@@ -2147,23 +2147,27 @@
 	}
     }
     *bp = '\0';
-    strcpy(t, buf);
+    StrAllocCopy(*t, buf);
+    FREE(buf);
 }
 
 /*
 **	HTmmdecode for ISO-2022-JP - FM
 */
 PUBLIC void HTmmdecode ARGS2(
-	char *,		trg,
+	char **,	trg,
 	char *,		str)
 {
-    char buf[LINE_LENGTH], mmbuf[LINE_LENGTH];
+    char *buf;
+    char *mmbuf = NULL;
+    char *m2buf = NULL;
     char *s, *t, *u;
     int  base64, quote;
 
-    buf[0] = '\0';
-
-    for (s = str, u = buf; *s; ) {
+    if ((buf = malloc(strlen(str) + 1)) == 0)
+	outofmem(__FILE__, "HTmmdecode");
+  
+    for (s = str, u = buf; *s;) {
 	if (!strncasecomp(s, "=?ISO-2022-JP?B?", 16)) {
 	    base64 = 1;
 	} else {
@@ -2181,11 +2185,14 @@
 			u--;
 		}
 	    }
+	    if (mmbuf == 0)	/* allocate buffer big enough for source */
+		StrAllocCopy(mmbuf, str);
 	    for (s += 16, t = mmbuf; *s; ) {
 		if (s[0] == '?' && s[1] == '=') {
 		    break;
 		} else {
 		    *t++ = *s++;
+		    *t = '\0';
 		}
 	    }
 	    if (s[0] != '?' || s[1] != '=') {
@@ -2195,14 +2202,12 @@
 		*t = '\0';
 	    }
 	    if (base64)
-		HTmmdec_base64(mmbuf, mmbuf);
+		HTmmdec_base64(&m2buf, mmbuf);
 	    if (quote)
-		HTmmdec_quote(mmbuf, mmbuf);
-	    for (t = mmbuf; *t; )
+		HTmmdec_quote(&m2buf, mmbuf);
+	    for (t = m2buf; *t; )
 		*u++ = *t++;
 	    HTmmcont = 1;
-	    /* if (*s == ' ' || *s == '\t') *u++ = *s; */
-	    /* for ( ; *s == ' ' || *s == '\t'; s++) ; */
 	} else {
 	    if (*s != ' ' && *s != '\t')
 		HTmmcont = 0;
@@ -2211,7 +2216,10 @@
     }
     *u = '\0';
 end:
-    strcpy(trg, buf);
+    StrAllocCopy(*t, buf);
+    FREE(m2buf);
+    FREE(mmbuf);
+    FREE(buf);
 }
 
 /*
@@ -2219,22 +2227,27 @@
 **  (The author of this function "rjis" is S. Ichikawa.)
 */
 PUBLIC int HTrjis ARGS2(
-	char *,		t,
+	char **,	t,
 	char *,		s)
 {
-    char *p, buf[LINE_LENGTH];
+    char *p;
+    char *buf = NULL;
     int kanji = 0;
 
-    if (strchr(s, ESC) || !strchr(s, '$')) {
-	if (s != t)
-	    strcpy(t, s);
+    if (strchr(s, CH_ESC) || !strchr(s, '$')) {
+	if (s != *t)
+	    StrAllocCopy(*t, s);
 	return 1;
     }
+
+    if ((buf = malloc(strlen(s) * 2 + 1)) == 0)
+	outofmem(__FILE__, "HTrjis");
+
     for (p = buf; *s; ) {
 	if (!kanji && s[0] == '$' && (s[1] == '@' || s[1] == 'B')) {
 	    if (HTmaybekanji((int)s[2], (int)s[3])) {
 		kanji = 1;
-		*p++ = ESC;
+		*p++ = CH_ESC;
 		*p++ = *s++;
 		*p++ = *s++;
 		*p++ = *s++;
@@ -2246,7 +2259,7 @@
 	}
 	if (kanji && s[0] == '(' && (s[1] == 'J' || s[1] == 'B')) {
 	    kanji = 0;
-	    *p++ = ESC;
+	    *p++ = CH_ESC;
 	    *p++ = *s++;
 	    *p++ = *s++;
 	    continue;
@@ -2255,7 +2268,8 @@
     }
     *p = *s;	/* terminate string */
 
-    strcpy(t, buf);
+    StrAllocCopy(*t, buf);
+    FREE(buf);
     return 0;
 }
 
Index: WWW/Library/Implementation/HTMIME.h
--- 2.8.5rel.2/WWW/Library/Implementation/HTMIME.h	Wed Jan 22 01:43:13 2003
+++ 2.8.5rel.3/WWW/Library/Implementation/HTMIME.h	Mon Oct 17 13:47:09 2005
@@ -67,20 +67,12 @@
   For handling Japanese headers.
 
 */
-extern void HTmmdec_base64 PARAMS((
-	char *	t,
-	char *	s));
-
-extern void HTmmdec_quote PARAMS((
-	char *	t,
-	char *	s));
-
 extern void HTmmdecode PARAMS((
-	char *	trg,
+	char **	trg,
 	char *	str));
 
 extern int HTrjis PARAMS((
-	char *	t,
+	char **	t,
 	char *	s));
 
 extern int HTmaybekanji PARAMS((
Index: WWW/Library/Implementation/HTNews.c
--- 2.8.5rel.2/WWW/Library/Implementation/HTNews.c	Wed Jan  7 18:03:09 2004
+++ 2.8.5rel.3/WWW/Library/Implementation/HTNews.c	Mon Oct 17 13:47:09 2005
@@ -940,7 +940,6 @@
     }
 }
 
-#ifdef SH_EX	/* for MIME */
 #ifdef NEWS_DEBUG
 /* for DEBUG 1997/11/07 (Fri) 17:20:16 */
 void debug_print(unsigned char *p)
@@ -962,45 +961,15 @@
 }
 #endif
 
-static char *decode_mime(char *str)
+static char *decode_mime(char **str)
 {
-    char temp[LINE_LENGTH];	/* FIXME: what determines the actual size? */
-    char *p, *q;
-
-    if (str == NULL)
-	return "";
-
+#ifdef SH_EX
     if (HTCJK != JAPANESE)
-	return str;
-
-    LYstrncpy(temp, str, sizeof(temp) - 1);
-    q = temp;
-    while ((p = strchr(q, '=')) != 0) {
-	if (p[1] == '?') {
-	    HTmmdecode(p, p);
-	    q = p + 2;
-	} else {
-	    q = p + 1;
-	}
-    }
-#ifdef NEWS_DEBUG
-    printf("new=[");
-    debug_print(temp);
+	return *str;
 #endif
-    HTrjis(temp, temp);
-    strcpy(str, temp);
-
-    return str;
-}
-#else /* !SH_EX */
-static char *decode_mime ARGS1(char *, str)
-{
-    HTmmdecode(str, str);
-    HTrjis(str, str);
-    return str;
+    HTmmdecode(str, *str);
+    return HTrjis(str, *str) ? *str : "";
 }
-#endif
-
 
 /*	Read in an Article					read_article
 **	------------------
@@ -1087,22 +1056,22 @@
 
 		} else if (match(full_line, "SUBJECT:")) {
 		    StrAllocCopy(subject, HTStrip(strchr(full_line,':')+1));
-		    decode_mime(subject);
+		    decode_mime(&subject);
 		} else if (match(full_line, "DATE:")) {
 		    StrAllocCopy(date, HTStrip(strchr(full_line,':')+1));
 
 		} else if (match(full_line, "ORGANIZATION:")) {
 		    StrAllocCopy(organization,
 				 HTStrip(strchr(full_line,':')+1));
-		    decode_mime(organization);
+		    decode_mime(&organization);
 
 		} else if (match(full_line, "FROM:")) {
 		    StrAllocCopy(from, HTStrip(strchr(full_line,':')+1));
-		    decode_mime(from);
+		    decode_mime(&from);
 
 		} else if (match(full_line, "REPLY-TO:")) {
 		    StrAllocCopy(replyto, HTStrip(strchr(full_line,':')+1));
-		    decode_mime(replyto);
+		    decode_mime(&replyto);
 
 		} else if (match(full_line, "NEWSGROUPS:")) {
 		    StrAllocCopy(newsgroups, HTStrip(strchr(full_line,':')+1));
@@ -1711,8 +1680,8 @@
 	int,		last_required)
 {
     char line[LINE_LENGTH+1];
-    char author[LINE_LENGTH+1];
-    char subject[LINE_LENGTH+1];
+    char *author = NULL;
+    char *subject = NULL;
     char *date = NULL;
     int i;
     char *p;
@@ -1725,7 +1694,6 @@
     int status, count, first, last;	/* Response fields */
 					/* count is only an upper limit */
 
-    author[0] = '\0';
     START(HTML_HEAD);
     PUTC('\n');
     START(HTML_TITLE);
@@ -1946,8 +1914,8 @@
 			case 'S':
 			case 's':
 			    if (match(line, "SUBJECT:")) {
-				LYstrncpy(subject, line+9, sizeof(subject)-1);/* Save subject */
-				decode_mime(subject);
+				StrAllocCopy(subject, line + 9);
+				decode_mime(&subject);
 			    }
 			    break;
 
@@ -1964,10 +1932,8 @@
 			case 'F':
 			    if (match(line, "FROM:")) {
 				char * p2;
-				LYstrncpy(author,
-					author_name(strchr(line,':')+1),
-					sizeof(author)-1);
-				decode_mime(author);
+				StrAllocCopy(author, strchr(line, ':') + 1);
+				decode_mime(&author);
 				p2 = author + strlen(author) - 1;
 				if (*p2==LF)
 				    *p2 = '\0'; /* Chop off newline */
@@ -1988,11 +1954,8 @@
 
 		PUTC('\n');
 		START(HTML_LI);
-#ifdef SH_EX	/* for MIME */
-		HTSprintf0(&temp, "\"%s\"", decode_mime(subject));
-#else
-		HTSprintf0(&temp, "\"%s\"", subject);
-#endif
+		p = decode_mime(&subject);
+		HTSprintf0(&temp, "\"%s\"", NonNull(p));
 		if (reference) {
 		    write_anchor(temp, reference);
 		    FREE(reference);
@@ -2001,18 +1964,14 @@
 		}
 		FREE(temp);
 
-		if (author[0] != '\0') {
+		if (author != NULL) {
 		     PUTS(" - ");
 		     if (LYListNewsDates)
 			 START(HTML_I);
-#ifdef SH_EX	/* for MIME */
-		     PUTS(decode_mime(author));
-#else
-		     PUTS(author);
-#endif
+		    PUTS(decode_mime(&author));
 		     if (LYListNewsDates)
 			 END(HTML_I);
-		     author[0] = '\0';
+		    FREE(author);
 		}
 		if (date) {
 		    if (!diagnostic) {
@@ -2055,6 +2014,8 @@
 		MAYBE_END(HTML_LI);
 	    } /* Handle response to HEAD request */
 	} /* Loop over article */
+	FREE(author);
+	FREE(subject);
     } /* If read headers */
     PUTC('\n');
     if (LYListNewsNumbers)
Index: configure
--- 2.8.5rel.2/configure	Wed Feb  4 04:07:09 2004
+++ 2.8.5rel.3/configure	Wed Feb  4 04:07:09 2004
@@ -723,7 +723,7 @@
 
 PACKAGE=lynx
 # $Format: "VERSION=$ProjectVersion$"$
-VERSION=2.8.5rel.2
+VERSION=2.8.5rel.3
 
 
 
Index: configure.in
--- 2.8.5rel.2/configure.in	Wed Feb  4 04:07:09 2004
+++ 2.8.5rel.3/configure.in	Wed Feb  4 04:07:09 2004
@@ -5,7 +5,7 @@
 dnl
 dnl ask PRCS to plug-in the project-version for the configure-script.
 dnl $Format: "AC_REVISION($ProjectVersion$)"$
-AC_REVISION(2.8.5rel.2)
+AC_REVISION(2.8.5rel.3)
 
 # Save the original $CFLAGS so we can distinguish whether the user set those
 # in the environment, or whether autoconf added -O and -g options:
@@ -33,7 +33,7 @@
 PACKAGE=lynx
 dnl ask PRCS to plug-in the project-version for the packages.
 # $Format: "VERSION=$ProjectVersion$"$
-VERSION=2.8.5rel.2
+VERSION=2.8.5rel.3
 AC_SUBST(PACKAGE)
 AC_SUBST(VERSION)
 AC_SUBST(DESTDIR)
Index: lynx.cfg
--- 2.8.5rel.2/lynx.cfg	Wed Jan 28 11:30:38 2004
+++ 2.8.5rel.3/lynx.cfg	Wed Jan 28 11:30:38 2004
@@ -3,10 +3,10 @@
 #                                     or Lynx_Dir:lynx.cfg (VMS)
 #
 # $Format: "#PRCS LYNX_VERSION \"$ProjectVersion$\""$
-#PRCS LYNX_VERSION "2.8.5rel.2"
+#PRCS LYNX_VERSION "2.8.5rel.3"
 #
 # $Format: "#PRCS LYNX_DATE \"$ProjectDate$\""$
-#PRCS LYNX_DATE "Thu, 22 Apr 2004 16:08:10 -0700"
+#PRCS LYNX_DATE "Mon, 17 Oct 2005 13:47:09 -0700"
 #
 # Definition pairs are of the form  VARIABLE:DEFINITION
 # NO spaces are allowed between the pair items.
Index: userdefs.h
--- 2.8.5rel.2/userdefs.h	Mon Feb  2 12:02:28 2004
+++ 2.8.5rel.3/userdefs.h	Mon Feb  2 12:02:28 2004
@@ -1360,11 +1360,11 @@
  * the version definition with the Project Version on checkout.  Just
  * ignore it. - kw */
 /* $Format: "#define LYNX_VERSION \"$ProjectVersion$\""$ */
-#define LYNX_VERSION "2.8.5rel.2"
+#define LYNX_VERSION "2.8.5rel.3"
 #define LYNX_WWW_HOME "http://lynx.isc.org/"
 #define LYNX_WWW_DIST "http://lynx.isc.org/current/"
 /* $Format: "#define LYNX_DATE \"$ProjectDate$\""$ */
-#define LYNX_DATE "Thu, 22 Apr 2004 16:08:10 -0700"
+#define LYNX_DATE "Mon, 17 Oct 2005 13:47:09 -0700"
 #define LYNX_DATE_OFF 5		/* truncate the automatically-generated date */
 #define LYNX_DATE_LEN 11	/* truncate the automatically-generated date */