Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: notesfiles Path: utzoo!linus!philabs!prls!amdimage!amdcad!amd!pesnta!hplabs!hp-pcd!orstcs!hakanson From: hakanson@orstcs.UUCP (hakanson) Newsgroups: net.unix-wizards Subject: Re: bugs in -ltermlib termcap.c Message-ID: <21900004@orstcs.UUCP> Date: Mon, 13-May-85 17:09:00 EDT Article-I.D.: orstcs.21900004 Posted: Mon May 13 17:09:00 1985 Date-Received: Sun, 12-May-85 11:11:04 EDT References: <2295@pegasus.UUCP> Organization: Oregon State University - Corvallis, OR Lines: 219 Nf-ID: #R:pegasus:-229500:orstcs:21900004:000:6475 Nf-From: orstcs!hakanson May 7 13:09:00 1985 The following is in reference to the termcap (termlib) fixes posted by pegasus!hansen. Our mailer couldn't find a path to pegasus, so here is what I would've sent directly if I could have: I finally got around to examining the patches to termcap(3), and noticed a few problems with them. The contextual diff seemed to show a few lines that had been inserted before lines they had been meant to replace (easily fixed, of course). But the patch to avoid core dumps (doubling the size of the buffer) only puts off the core dump until an entry gets too big for the larger buffer. Since I felt this was an inelegant fix, I bit the bullet and found the bug(s) that caused the problem, and patched that part myself. I'd appreciate hearing about anything I've broken below. BTW, these patches work fine on our VAX 750 running 4.2bsd, etc..... /* rcsdiff -c -r1.1 -r1.2 termcap.c */ RCS file: RCS/termcap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -c -r1.1 -r1.2 *** /tmp/,RCSt1025137 Tue May 7 12:28:53 1985 --- /tmp/,RCSt2025137 Tue May 7 12:28:57 1985 *************** *** 1,5 #ifndef lint static char sccsid[] = "@(#)termcap.c 4.1 (Berkeley) 6/27/83"; #endif #define BUFSIZ 1024 --- 1,6 ----- #ifndef lint static char sccsid[] = "@(#)termcap.c 4.1 (Berkeley) 6/27/83"; + static char rcsid[] = "$Header: termcap.c,v 1.2 85/05/06 10:31:50 hakanson Exp $"; #endif #define BUFSIZ 1024 *************** *** 20,25 * in string capabilities. We don't use stdio because the editor * doesn't, and because living w/o it is not hard. */ static char *tbuf; static int hopcount; /* detect infinite loops in termcap, init 0 */ --- 21,38 ----- * in string capabilities. We don't use stdio because the editor * doesn't, and because living w/o it is not hard. */ + /* + * Modified 05/06/85 by R. Marion Hakanson (hakanson@oregon-state). + * Fixed the following bugs (from Tony Hansen (pegasus!hansen)): + * + * 1: tgetent() cannot be called more than once in a program (hopcount + * doesn't get rezeroed). + * 2: an entry with ":tc=foo" but no trailing colon will cause coredumps. + * 3. buffer overflows can still occur, causing coredumps. + * 4. in tc=foo, foo can only be 16 chars long. this is not checked. + * + * The patches for #1, #2 & #4 came from hansen; I fixed #3. + */ static char *tbuf; static int hopcount; /* detect infinite loops in termcap, init 0 */ *************** *** 36,41 tgetent(bp, name) char *bp, *name; { register char *cp; register int c; register int i = 0, cnt = 0; --- 49,61 ----- tgetent(bp, name) char *bp, *name; { + hopcount = 0; + return (_tgetent(bp, name)); + } + + static _tgetent(bp, name) + char *bp, *name; + { register char *cp; register int c; register int i = 0, cnt = 0; *************** *** 93,98 break; } if (cp >= bp+BUFSIZ) { write(2,"Termcap entry too long\n", 23); break; } else --- 113,119 ----- break; } if (cp >= bp+BUFSIZ) { + cp = bp+BUFSIZ-1; write(2,"Termcap entry too long\n", 23); break; } else *************** *** 117,122 * entries to say "like an HP2621 but doesn't turn on the labels". * Note that this works because of the left to right scan. */ tnchktc() { register char *p, *q; --- 138,145 ----- * entries to say "like an HP2621 but doesn't turn on the labels". * Note that this works because of the left to right scan. */ + #define NAMESIZE 16 + tnchktc() { register char *p, *q; *************** *** 120,126 tnchktc() { register char *p, *q; ! char tcname[16]; /* name of similar terminal */ char tcbuf[BUFSIZ]; char *holdtbuf = tbuf; int l; --- 143,149 ----- tnchktc() { register char *p, *q; ! char tcname[NAMESIZE]; /* name of similar terminal */ char tcbuf[BUFSIZ]; char *holdtbuf = tbuf; int l; *************** *** 135,141 /* p now points to beginning of last field */ if (p[0] != 't' || p[1] != 'c') return(1); ! strcpy(tcname,p+3); q = tcname; while (q && *q != ':') q++; --- 158,165 ----- /* p now points to beginning of last field */ if (p[0] != 't' || p[1] != 'c') return(1); ! strncpy(tcname,p+3,NAMESIZE); ! tcname[NAMESIZE-1] = 0; q = tcname; while (*q && *q != ':') q++; *************** *** 137,143 return(1); strcpy(tcname,p+3); q = tcname; ! while (q && *q != ':') q++; *q = 0; if (++hopcount > MAXHOP) { --- 161,167 ----- strncpy(tcname,p+3,NAMESIZE); tcname[NAMESIZE-1] = 0; q = tcname; ! while (*q && *q != ':') q++; *q = 0; if (++hopcount > MAXHOP) { *************** *** 144,150 write(2, "Infinite tc= loop\n", 18); return (0); } ! if (tgetent(tcbuf, tcname) != 1) return(0); for (q=tcbuf; *q != ':'; q++) ; --- 168,174 ----- write(2, "Infinite tc= loop\n", 18); return (0); } ! if (_tgetent(tcbuf, tcname) != 1) return(0); for (q=tcbuf; *q != ':'; q++) ; *************** *** 151,157 l = p - holdtbuf + strlen(q); if (l > BUFSIZ) { write(2, "Termcap entry too long\n", 23); ! q[BUFSIZ - (p-tbuf)] = 0; } strcpy(p, q+1); tbuf = holdtbuf; --- 175,181 ----- l = p - holdtbuf + strlen(q); if (l > BUFSIZ) { write(2, "Termcap entry too long\n", 23); ! q[BUFSIZ - (p-holdtbuf)] = 0; } strcpy(p, q+1); tbuf = holdtbuf; /* end diff listing */ Marion Hakanson CSnet: hakanson%oregon-state@csnet-relay UUCP : {hp-pcd,tekchips}!orstcs!hakanson