bugs in -ltermlib termcap.c

hakanson hakanson at orstcs.UUCP
Tue May 14 07:09:00 AEST 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 at 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 at csnet-relay
                        UUCP :  {hp-pcd,tekchips}!orstcs!hakanson



More information about the Comp.unix.wizards mailing list