diff -urN lynx2-8-5.orig/CHANGES lynx2-8-5/CHANGES --- lynx2-8-5.orig/CHANGES 2004-02-04 07:07:09.000000000 -0500 +++ lynx2-8-5/CHANGES 2005-10-12 09:26:54.000000000 -0400 @@ -1,6 +1,11 @@ Changes since Lynx 2.8 release =============================================================================== +2005-0?-?? (2.8.5rel.1) +* eliminate fixed-size buffers in HTrjis() and related functions to avoid + potential buffer overflow in nntp pages (report by Ulf Harnhammar). + Back-ported from Thomas Dickey's patch to 2.8.6dev.13 by Seemant Kulleen + 2004-02-04 (2.8.5rel.1) * build fixes for MINGW32 -DK * build fixes for OS/2 (reported by IZ) -TD diff -urN lynx2-8-5.orig/WWW/Library/Implementation/HTMIME.c lynx2-8-5/WWW/Library/Implementation/HTMIME.c --- lynx2-8-5.orig/WWW/Library/Implementation/HTMIME.c 2004-01-07 21:03:09.000000000 -0500 +++ lynx2-8-5/WWW/Library/Implementation/HTMIME.c 2005-10-12 09:22:59.000000000 -0400 @@ -2062,15 +2062,9 @@ ** ** Written by S. Ichikawa, ** partially inspired by encdec.c of . -** Assume caller's buffer is LINE_LENGTH bytes, these decode to -** no longer than the input strings. +** Caller's buffers 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 /* S/390 -- gil -- 0163 */ -#define ESC CH_ESC PRIVATE char HTmm64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" ; @@ -2078,11 +2072,14 @@ PRIVATE int HTmmcont = 0; PUBLIC void HTmmdec_base64 ARGS2( - char *, t, + 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 +2110,18 @@ *bp++ = nw[2]; } *bp = '\0'; - strcpy(t, buf); + StrAllocCopy(*t, buf); + FREE(buf); } PUBLIC void HTmmdec_quote ARGS2( - char *, t, + 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 +2148,27 @@ } } *bp = '\0'; - strcpy(t, buf); + StrAllocCopy(*t, buf); + FREE(buf); } /* ** HTmmdecode for ISO-2022-JP - FM */ PUBLIC void HTmmdecode ARGS2( - char *, trg, - char *, str) + char **, target, + char *, source) { - 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'; + if ((buf = malloc(strlen(source) + 1)) == 0) + outofmem(__FILE__, "HTmmdecode"); - for (s = str, u = buf; *s; ) { + for (s = source, u = buf; *s; ) { if (!strncasecomp(s, "=?ISO-2022-JP?B?", 16)) { base64 = 1; } else { @@ -2177,15 +2182,18 @@ if (base64 || quote) { if (HTmmcont) { for (t = s - 1; - t >= str && (*t == ' ' || *t == '\t'); t--) { + t >= source && (*t == ' ' || *t == '\t'); t--) { u--; } } + if (mmbuf == 0) /* allocate buffer big enough for source */ + StrAllocCopy(mmbuf, source); for (s += 16, t = mmbuf; *s; ) { if (s[0] == '?' && s[1] == '=') { break; } else { *t++ = *s++; + *t = '\0'; } } if (s[0] != '?' || s[1] != '=') { @@ -2195,10 +2203,10 @@ *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; */ @@ -2211,7 +2219,10 @@ } *u = '\0'; end: - strcpy(trg, buf); + StrAllocCopy(*target, buf); + FREE(m2buf); + FREE(mmbuf); + FREE(buf); } /* @@ -2219,22 +2230,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 +2262,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 +2271,8 @@ } *p = *s; /* terminate string */ - strcpy(t, buf); + StrAllocCopy(*t, buf); + FREE(buf); return 0; } diff -urN lynx2-8-5.orig/WWW/Library/Implementation/HTMIME.h lynx2-8-5/WWW/Library/Implementation/HTMIME.h --- lynx2-8-5.orig/WWW/Library/Implementation/HTMIME.h 2003-01-22 04:43:13.000000000 -0500 +++ lynx2-8-5/WWW/Library/Implementation/HTMIME.h 2005-10-12 09:24:50.000000000 -0400 @@ -67,21 +67,13 @@ 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 * str)); + char ** target, + char * source)); extern int HTrjis PARAMS(( - char * t, - char * s)); + char ** target, + char * source)); extern int HTmaybekanji PARAMS(( int c1, diff -urN lynx2-8-5.orig/WWW/Library/Implementation/HTNews.c lynx2-8-5/WWW/Library/Implementation/HTNews.c --- lynx2-8-5.orig/WWW/Library/Implementation/HTNews.c 2004-01-07 21:03:09.000000000 -0500 +++ lynx2-8-5/WWW/Library/Implementation/HTNews.c 2005-10-12 09:05:14.000000000 -0400 @@ -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,44 +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_LEX 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; + HTmmdecode(str, *str); + return HTrjis(str, *str) ? *str : ""; } -#else /* !SH_EX */ -static char *decode_mime ARGS1(char *, str) -{ - HTmmdecode(str, str); - HTrjis(str, str); - return str; -} -#endif /* Read in an Article read_article @@ -1087,22 +1057,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 +1681,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; @@ -1723,9 +1693,7 @@ char *reference = NULL; /* Href for article */ int art; /* Article number WITHIN GROUP */ 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)