[news.software.b] Crossposting considered dangerous

leres@ace.ee.lbl.gov (Craig Leres) (12/11/89)

We run B news (version 2.11 12/1/87). We recently started using C news
expire and started getting complaints about "wrong number of fields" in
the history file. These were all in reference to articles that were
crossposted to a large number of newsgroups.

The last time I applied patches to news, the length of the nbuf field
of the hbuf struct changed from BUFLEN to LBUFLEN. This was a good idea
but a noop unless you also fix the code in header.c to use sizeof()
when calling hfgets(). I also fixed various off-by-one errors in
hfgets() itself.

At this point, a test cross posting would cause inews to dump core.
This was because the xref field of the hbuf struct was getting overrun.
I installed code to handle this case. But xref needs to be larger than
nbuf so I raised it to LBUFLEN + BUFLEN.

My site is now safe from the bozos that insist on crossposting to 12,
15 or more newsgroups. Context diffs are appended.

		Craig
------
RCS file: RCS/header.c,v
retrieving revision 1.4
diff -c -r1.4 header.c
*** /tmp/,RCSt1a03790	Sun Dec 10 20:48:05 1989
--- header.c	Sun Dec 10 17:31:30 1989
***************
*** 59,65 ****
  	}
  
  	/* Check that it's a B news style header. */
! 	if (hfgets(bfr, PATHLEN, fp) != NULL && isalpha(bfr[0])
  	    && index(bfr, ':'))
  		if (frmread(fp, hp))
  			goto strip;
--- 59,65 ----
  	}
  
  	/* Check that it's a B news style header. */
! 	if (hfgets(bfr, sizeof(bfr), fp) != NULL && isalpha(bfr[0])
  	    && index(bfr, ':'))
  		if (frmread(fp, hp))
  			goto strip;
***************
*** 83,98 ****
  	(void) sprintf(hp->ident, "<%s@%s%s>", p, bfr+1, ".UUCP");
  
  	/* Newsgroup List */
! 	if (hfgets(hp->nbuf, BUFLEN, fp) == NULL || !nstrip(hp->nbuf))
  		return NULL;
  	/* source path */
! 	if (hfgets(hp->path, PATHLEN, fp) == NULL || !nstrip(hp->path))
  		return NULL;
  	/* date */
! 	if (hfgets(hp->subdate, DATELEN, fp) == NULL || !nstrip(hp->subdate))
  		return NULL;
  	/* title */
! 	if (hfgets(hp->title, BUFLEN, fp) == NULL || !nstrip(hp->title))
  		return NULL;
  #endif /* OLD */
  
--- 83,100 ----
  	(void) sprintf(hp->ident, "<%s@%s%s>", p, bfr+1, ".UUCP");
  
  	/* Newsgroup List */
! 	if (hfgets(hp->nbuf, sizeof(hp->nbuf), fp) == NULL || !nstrip(hp->nbuf))
  		return NULL;
  	/* source path */
! 	if (hfgets(hp->path, sizeof(hp->path), fp) == NULL || !nstrip(hp->path))
  		return NULL;
  	/* date */
! 	if (hfgets(hp->subdate, sizeof(hp->subdate), fp) == NULL ||
! 	    !nstrip(hp->subdate))
  		return NULL;
  	/* title */
! 	if (hfgets(hp->title, sizeof(hp->title), fp) == NULL ||
! 	    !nstrip(hp->title))
  		return NULL;
  #endif /* OLD */
  
***************
*** 265,271 ****
  			}
  			break;
  		}
! 	} while ((i = type(hfgets(bfr, LBUFLEN, fp))) > 0);
  
  	if ((hp->from[0] || hp->path[0]) && hp->subdate[0] && hp->ident[0])
  		return TRUE;
--- 267,273 ----
  			}
  			break;
  		}
! 	} while ((i = type(hfgets(bfr, sizeof(bfr), fp))) > 0);
  
  	if ((hp->from[0] || hp->path[0]) && hp->subdate[0] && hp->ident[0])
  		return TRUE;
***************
*** 745,751 ****
  	register char *cp;
  
  	cp = buf;
! 	while (n < len && (c = getc(fp)) != EOF) {
  		if (c == '\n')
  			break;
  		if (isprint(c) || c == '\b' || c == ' ' || c == '\t') {
--- 747,753 ----
  	register char *cp;
  
  	cp = buf;
! 	while (n < (len - 1) && (c = getc(fp)) != EOF) {
  		if (c == '\n')
  			break;
  		if (isprint(c) || c == '\b' || c == ' ' || c == '\t') {
***************
*** 770,783 ****
  
  	while ((c = getc(fp)) == ' ' || c == '\t') {	/* for each cont line */
  		/* Continuation line. */
! 		if ((n += 2) < len) {
  			*cp++ = '\n';
  			*cp++ = c;
  		}
  		while ((c = getc(fp)) != '\n' && c != EOF)
! 			if ((isprint(c) || c == '\b' || c == ' ' || c == '\t')
! 				&& n++ < len)
! 				*cp++ = c;
  	}
  	if (n >= len - 1)
  		cp = buf + len - 2;
--- 772,788 ----
  
  	while ((c = getc(fp)) == ' ' || c == '\t') {	/* for each cont line */
  		/* Continuation line. */
! 		if (n < (len - 2)) {
  			*cp++ = '\n';
  			*cp++ = c;
+ 			n += 2;
  		}
  		while ((c = getc(fp)) != '\n' && c != EOF)
! 			if (isprint(c) || c == '\b' || c == ' ' || c == '\t')
! 				if (n < (len - 1)) {
! 					*cp++ = c;
! 					n++;
! 				}
  	}
  	if (n >= len - 1)
  		cp = buf + len - 2;

RCS file: RCS/inews.c,v
retrieving revision 1.2
diff -c -r1.2 inews.c
*** /tmp/,RCSt1a03795	Sun Dec 10 20:48:13 1989
--- inews.c	Sun Dec 10 19:27:56 1989
***************
*** 904,909 ****
--- 904,910 ----
  	int is_invalid = FALSE;
  	int exitcode = 0;
  	long now;
+ 	register int n, i, diderr;
  #ifdef DOXREFS
  	register char *nextref = header.xref;
  #endif /* DOXREFS */
***************
*** 1048,1061 ****
  			srec = dummy_srec;
  		}
  #ifdef DOXREFS
! 		(void) strncpy(nextref, PATHSYSNAME, BUFLEN);
  #endif /* DOXREFS */
  		for (ptr = nbuf; *ptr;) {
  			if (ngmatch(ptr,srec.s_nbuf) || index(ptr,'.') == NULL){
  #ifdef DOXREFS
! 				while (*nextref++)
! 					;
! 				(void) sprintf(--nextref, " %s:%ld", ptr, localize(ptr));
  #else /* !DOXREFS */
  				(void) localize(ptr);
  #endif /* !DOXREFS */
--- 1049,1077 ----
  			srec = dummy_srec;
  		}
  #ifdef DOXREFS
! 		(void) strncpy(nextref, PATHSYSNAME, sizeof(header.xref));
! 		n = strlen(nextref);
! 		nextref += n;
! 		diderr = 0;
  #endif /* DOXREFS */
  		for (ptr = nbuf; *ptr;) {
  			if (ngmatch(ptr,srec.s_nbuf) || index(ptr,'.') == NULL){
  #ifdef DOXREFS
! 				char xbuf[BUFLEN];
! 
! 				(void) sprintf(xbuf, " %s:%ld",
! 				    ptr, localize(ptr));
! 				i = strlen(xbuf);
! 				/* Only add to xref list if it fits */
! 				if (n + i < sizeof(header.xref) - 1) {
! 					strcpy(nextref, xbuf);
! 					nextref += i;
! 					n += i;
! 				} else if (!diderr) {
! 					logerr("xref larger than %d",
! 					    sizeof(header.xref));
! 					++diderr;
! 				}
  #else /* !DOXREFS */
  				(void) localize(ptr);
  #endif /* !DOXREFS */

RCS file: RCS/header.h,v
retrieving revision 1.2
diff -c -r1.2 header.h
*** /tmp/,RCSt1a03800	Sun Dec 10 20:48:16 1989
--- header.h	Sun Dec 10 19:33:02 1989
***************
*** 32,38 ****
  	char	nf_from[BUFLEN];	/* Nf-From:		*/
  	char 	supersedes[BUFLEN];	/* Supersedes:		*/
  #ifdef DOXREFS
! 	char 	xref[BUFLEN];		/* Xref:		*/
  #endif /* DOXREFS */
  	char	*unrec[NUNREC];		/* unrecognized lines	*/
  };
--- 32,38 ----
  	char	nf_from[BUFLEN];	/* Nf-From:		*/
  	char 	supersedes[BUFLEN];	/* Supersedes:		*/
  #ifdef DOXREFS
! 	char 	xref[LBUFLEN + BUFLEN];	/* Xref:		*/
  #endif /* DOXREFS */
  	char	*unrec[NUNREC];		/* unrecognized lines	*/
  };