From andrew@ugh.net.au  Fri Oct 30 07:02:35 1998
Received: from beebite.ugh.net.au ([203.17.118.121])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id HAA18601
          for <FreeBSD-gnats-submit@freebsd.org>; Fri, 30 Oct 1998 07:02:30 -0800 (PST)
          (envelope-from andrew@ugh.net.au)
Received: (from andrew@localhost)
	by beebite.ugh.net.au (8.8.8/8.8.8) id PAA08422;
	Fri, 30 Oct 1998 15:00:54 GMT
	(envelope-from andrew)
Message-Id: <199810301500.PAA08422@beebite.ugh.net.au>
Date: Fri, 30 Oct 1998 15:00:54 GMT
From: andrew@ugh.net.au
Reply-To: andrew@ugh.net.au
To: FreeBSD-gnats-submit@freebsd.org
Subject: snake has a segmentation fault depending on the terminal type
X-Send-Pr-Version: 3.2

>Number:         8501
>Category:       bin
>Synopsis:       snake has a segmentation fault depending on the terminal type
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Oct 30 07:10:00 PST 1998
>Closed-Date:    Sat May 20 23:53:07 PDT 2000
>Last-Modified:  Sun May 21 00:20:00 PDT 2000
>Originator:     Andrew
>Release:        FreeBSD 2.2.7-STABLE i386
>Organization:
UgH!
>Environment:

The termcap entry for my terminal dosn't define bc or bs

>Description:

When I run snake it crashes with a segmentation fault at line 660 when it
calls strlen(BS). BS is set to NULL. This is because the termcap entry for my
terminal dosn't define bc or bs.

>How-To-Repeat:

Use a termcap entry that dosn't define bs or bc and run snake

>Fix:
	
I have wrapped the strlen call in a test for BS "NULLness". I did the same
for ND and KL as they seemed likely to suffer the same fate if their
corresponding tgetstrs returned NULL.

While I was at it I also removed a few variables that were declared but never
used...just the odd int and char.

There was also some odd logic determining if the terminal had an addressable
cursor or home + 4 local motions. I have changed this to what I think is a
correct state.

I added in a few lines to hide the cursor when playing.

I rewrote the delay function so it wouldn't waste bandwidth when playing via
telnet. The new delay function should be better on the CPU as well. The new
delay function does what the coments indicate the earlier function was intended
to do (delay for t/20 seconds) although the old function didn't always acheive
this.

Patches are attached below:

--- snake.h.orig	Sun Sep  4 14:03:20 1994
+++ snake.h	Sat Oct 31 00:56:10 1998
@@ -50,7 +50,8 @@
 	*HO, *CM,
 	*TA, *LL,
 	*KL, *KR, *KU, *KD,
-	*TI, *TE, *KS, *KE;
+	*TI, *TE, *KS, *KE,
+	*VI, *VE;
 int	LINES, COLUMNS;	/* physical screen size. */
 int	lcnt, ccnt;	/* user's idea of screen size */
 char	xBC, PC;



--- snake.c.orig	Mon Mar  2 03:41:58 1998
+++ snake.c	Sat Oct 31 00:56:10 1998
@@ -104,7 +104,7 @@
 {
 	extern char *optarg;
 	extern int optind;
-	int ch, i, j, k;
+	int ch, i;
 	void stop();
 
 	rawscores = open(_PATH_RAWSCORES, O_RDWR|O_CREAT, 0664);
@@ -170,6 +170,7 @@
 	signal (SIGINT, stop);
 	putpad(TI); /*	String to begin programs that use cm */
 	putpad(KS); /*	Put terminal in keypad transmit mode */
+	putpad(VI); /*	Hide cursor */
 
 	snrand(&finish);
 	snrand(&you);
@@ -364,8 +365,6 @@
 
 			if (same(&you,&money))
 			{
-				char xp[20];
-				struct point z;
 				loot += 25;
 				if(k < repeat)
 					pchar(&you,' ');
@@ -632,7 +631,6 @@
 snap()
 {
 	struct point p;
-	int i;
 
 	if(you.line < 3){
 		pchar(point(&p,you.col,0),'-');
@@ -708,7 +706,7 @@
 surround(ps)
 struct point *ps;{
 	struct point x;
-	int i,j;
+	int j;
 
 	if(ps->col == 0)ps->col++;
 	if(ps->line == 0)ps->line++;
@@ -869,8 +867,6 @@
 
 suspend()
 {
-	char *sh;
-
 	ll();
 	cook();
 	kill(getpid(), SIGTSTP);



--- move.c.orig	Tue May 30 13:37:26 1995
+++ move.c	Sat Oct 31 00:56:10 1998
@@ -96,6 +96,8 @@
 #else
 #include <varargs.h>
 #endif
+#include <unistd.h>
+
 #include "snake.h"
 
 int CMlength;
@@ -186,7 +188,7 @@
 struct point *sp;
 {
 
-	int distance,f,tfield,j;
+	int distance,f,tfield;
 
 	if (cursor.line > LINES || cursor.line <0 ||
 	    cursor.col <0 || cursor.col > COLUMNS)
@@ -339,7 +341,7 @@
 }
 
 ll(){
-	int j,l;
+	int l;
 	struct point z;
 
 	l = lcnt + 2;
@@ -524,12 +526,7 @@
 delay(t)
 int t;
 {
-	int k,j;
-
-	k = baudrate() * t / 300;
-	for(j=0;j<k;j++){
-		putchar(PC);
-	}
+	usleep((unsigned int)t*50000U);
 }
 
 done()
@@ -543,6 +540,7 @@
 	delay(1);
 	putpad(TE);
 	putpad(KE);
+	putpad(VE);
 	fflush(stdout);
 	stty(0, &orig);
 #ifdef TIOCSLTC
@@ -574,7 +572,6 @@
 	char *getenv();
 	char *term;
 	char *xPC;
-	struct point z;
 	void stop();
 #ifdef TIOCGWINSZ
 	struct winsize win;
@@ -618,7 +615,7 @@
 	UP = tgetstr("up", &ap);
 
 	DO = tgetstr("do", &ap);
-	if (DO == 0)
+	if (DO == 0 && tgetflag("do"))
 		DO = "\n";
 
 	BS = tgetstr("bc", &ap);
@@ -640,7 +637,10 @@
 	KR = tgetstr("kr", &ap);
 	KU = tgetstr("ku", &ap);
 	KD = tgetstr("kd", &ap);
-	Klength = strlen(KL);
+	if (KL)
+		Klength = strlen(KL);
+	else
+		Klength = 0;
 		/*	NOTE:   If KL, KR, KU, and KD are not
 		 *		all the same length, some problems
 		 *		may arise, since tests are made on
@@ -652,14 +652,25 @@
 	KS = tgetstr("ks", &ap);
 	KE = tgetstr("ke", &ap);
 
+	VI = tgetstr("vi", &ap);
+	VE = tgetstr("ve", &ap);
+
 	xPC = tgetstr("pc", &ap);
 	if (xPC)
 		PC = *xPC;
 
-	NDlength = strlen(ND);
-	BSlength = strlen(BS);
+	if (ND)
+		NDlength = strlen(ND);
+	else
+		NDlength = 0;
+
+	if (BS)
+		BSlength = strlen(BS);
+	else
+		BSlength = 0;
+
 	if ((CM == 0) &&
-		(HO == 0 | UP==0 || BS==0 || ND==0)) {
+		(HO == 0 || DO==0 || UP==0 || BS==0 || ND==0)) {
 		fprintf(stderr, "Terminal must have addressible ");
 		fprintf(stderr, "cursor or home + 4 local motions\n");
 		exit(5);
>Release-Note:
>Audit-Trail:

From: Tim Vanderhoek <tim@localhost.nowhere>
To: freebsd-gnats-submit@FreeBSD.org, andrew@ugh.net.au
Cc: vanderh@ecf.toronto.edu
Subject: Re: bin/8501: snake has a segmentation fault depending%2
Date: Sun, 21 May 2000 02:49:06 -0400 (EDT)

 >
 >        DO = tgetstr("do", &ap);
 >-       if (DO == 0)
 >+       if (DO == 0 && tgetflag("do"))
 >                DO = "\n";
 
 What are you trying to do here?
 
State-Changed-From-To: open->closed 
State-Changed-By: hoek 
State-Changed-When: Sat May 20 23:53:07 PDT 2000 
State-Changed-Why:  
With the exception noted in follow-up, I've (manually) applied 
your patches. 

They've been more or less applied blindly, since I've been lead to 
believe you're competent.  If I am mistaken, please correct me 
immediately so that I can back the patch out.  Thanks! 

From: andrew@ugh.net.au
To: vanderh@ecf.toronto.edu
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: bin/8501: snake has a segmentation fault depending%2
Date: Sun, 21 May 2000 17:15:47 +1000 (EST)

 On Sun, 21 May 2000, Tim Vanderhoek wrote:
 
 > What are you trying to do here?
 
 Hmm...I can't rightly say :-) whatever it was it wouldn't have worked.
 
 Thanks,
 
 Andrew
 
 
>Unformatted:
