From fredriks@mcs.com  Fri May 24 20:43:11 1996
Received: from fredriks.pr.mcs.net (fredriks.pr.mcs.net [199.3.36.197])
          by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id UAA03473
          for <FreeBSD-gnats-submit@freebsd.org>; Fri, 24 May 1996 20:43:08 -0700 (PDT)
Received: (from fredriks@localhost) by fredriks.pr.mcs.net (8.7.5/8.6.6) id MAA12700; Fri, 24 May 1996 12:28:32 -0500 (CDT)
Message-Id: <199605241728.MAA12700@fredriks.pr.mcs.net>
Date: Fri, 24 May 1996 12:28:32 -0500 (CDT)
From: fredriks@mcs.com
Reply-To: fredriks@mcs.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: shell having problem parsing arguments
X-Send-Pr-Version: 3.2

>Number:         1248
>Category:       bin
>Synopsis:       /bin/sh has trouble with arguments past 9(ie. ${10})
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    joerg
>State:          closed
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri May 24 20:50:02 PDT 1996
>Closed-Date:    Mon Sep 9 18:24:38 PDT 1996
>Last-Modified:  Mon Sep  9 18:26:03 PDT 1996
>Originator:     Lars Fredriksen
>Release:        FreeBSD 2.2-CURRENT i386
>Organization:
Flaaklypa Hackers
>Environment:
		FreeBSD 2.2-CURRENT as of 5/23/96 (sup and compile)


>Description:
	/bin/sh has a couple of bugs when dealing with arguments past
	argument #9. First off you get a syntax error when it tries
	to parse ${11}, enclosed is fix for the parser. The second 
	problem is that the setting and retrieving of variables did
	not handle anything past 9 arguments. The fix is in expand.c
	and is included below. Please test and review these. The
	fixes seem to work on the stuff I have tested, but I do not
	claim to have done a complete regression test on the sh.

	I do have commit priviledges so I can do the commits, but
	I need someone to review this. The same goes for kern/1245!

>How-To-Repeat:
>Fix:

Index: parser.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/parser.c,v
retrieving revision 1.11
diff -r1.11 parser.c
1111,1112c1111,1120
< 			USTPUTC(c, out);
< 			c = pgetc();
---
> 			
> 			if (is_digit(c)) {
> 				do {
> 					STPUTC(c, out);
> 					c = pgetc();
> 				} while( is_digit(c));
> 			} else {
> 				USTPUTC(c, out);
> 				c = pgetc();
> 			}


Index: expand.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/expand.c,v
retrieving revision 1.4
diff -r1.4 expand.c
93,94c93,94
< STATIC int varisset(int);
< STATIC void varvalue(int, int, int);
---
> STATIC int varisset(char *);
> STATIC void varvalue(char *, int, int);
456c456
< 		set = varisset(*var);
---
> 		set = varisset(var);
470c470
< 			varvalue(*var, varflags & VSQUOTE, flag & EXP_FULL);
---
> 			varvalue(var, varflags & VSQUOTE, flag & EXP_FULL);
542c542
< 	char name;
---
> 	char *name;
543a544,545
> 	char *t;
> 	int numvar;
546c548
< 	if (name == '!') {
---
> 	if (*name == '!') {
549c551
< 	} else if (name == '@' || name == '*') {
---
> 	} else if (*name == '@' || *name == '*') {
552,557c554,568
< 	} else if ((unsigned)(name -= '1') <= '9' - '1') {
< 		ap = shellparam.p;
< 		do {
< 			if (*ap++ == NULL)
< 				return 0;
< 		} while (--name >= 0);
---
> 	} else {
> 		t = name;
> 		while (is_digit(*t++)) {
> 			;
> 		}
> 
> 		if ( *--t == '=' ) { 
> 			*t = '\0';
> 			numvar = atoi(name);
> 			ap = shellparam.p;
> 			do {
> 				if (*ap++ == NULL)
> 					return 0;
> 			} while (--numvar > 0);
> 		} 
570c581
< 	char name;
---
> 	char *name;
572a584
> 	int numvar;
574a587
> 	char *t;
596c609
< 	switch (name) {
---
> 	switch (*name) {
643,644c656,663
< 		if ((unsigned)(name -= '1') <= '9' - '1') {
< 			p = shellparam.p[name];
---
> 
> 		t = name;
> 		while (is_digit(*t++)) {
> 		}
> 
> 		if ( *t == '\0' ) { 
> 			numvar = atoi(name);
> 			p = shellparam.p[numvar-1];
>Release-Note:
>Audit-Trail:

From: J Wunsch <j@uriah.heep.sax.de>
To: fredriks@mcs.com
Cc: FreeBSD-gnats-submit@FreeBSD.org
Subject: Re: bin/1248: shell having problem parsing arguments
Date: Sat, 25 May 1996 10:13:05 +0200 (MET DST)

 As fredriks@mcs.com wrote:
 
 > 	/bin/sh has a couple of bugs when dealing with arguments past
 > 	argument #9. First off you get a syntax error when it tries
 > 	to parse ${11}, enclosed is fix for the parser. The second 
 
 > Index: parser.c
 > ===================================================================
 > RCS file: /home/ncvs/src/bin/sh/parser.c,v
 > retrieving revision 1.11
 > diff -r1.11 parser.c
 > 1111,1112c1111,1120
 > < 			USTPUTC(c, out);
 > < 			c = pgetc();
 > ---
 > > 			
 > > 			if (is_digit(c)) {
 > > 				do {
 
 Aw!  Can you please re-submit this as a context (or uni) diff?
 (The -c or -u flags to [cvs] diff.)  It's nearly impossible to
 integrate plain diffs.
 
 You can simply followup to this thread, GNATS will append it then to
 the PR.
 
 -- 
 cheers, J"org
 
 joerg_wunsch@uriah.heep.sax.de -- http://www.sax.de/~joerg/ -- NIC: JW11-RIPE
 Never trust an operating system you don't have sources for. ;-)

From: "Lars Fredriksen" <fredriks@mcs.com>
To: joerg_wunsch@uriah.heep.sax.de
Cc: FreeBSD-gnats-submit@FreeBSD.org
Subject: Re: bin/1248: shell having problem parsing arguments
Date: Sat, 25 May 1996 12:20:34 -0500 (CDT)

 J Wunsch writes:
 > 
 > Aw!  Can you please re-submit this as a context (or uni) diff?
 > (The -c or -u flags to [cvs] diff.)  It's nearly impossible to
 > integrate plain diffs.
 > 
 > You can simply followup to this thread, GNATS will append it then to
 > the PR.
 > 
 > -- 
 > cheers, J"org
 > 
 
 Hi J"org,
 	Sorry about that, here they are:
 
 Lars
 
 
 Index: parser.c
 ===================================================================
 RCS file: /home/ncvs/src/bin/sh/parser.c,v
 retrieving revision 1.11
 diff -c -r1.11 parser.c
 *** parser.c	1996/02/03 13:27:55	1.11
 --- parser.c	1996/04/16 04:16:37
 ***************
 *** 1108,1115 ****
   		} else {
   			if (! is_special(c))
   badsub:				synerror("Bad substitution");
 ! 			USTPUTC(c, out);
 ! 			c = pgetc();
   		}
   		STPUTC('=', out);
   		flags = 0;
 --- 1108,1123 ----
   		} else {
   			if (! is_special(c))
   badsub:				synerror("Bad substitution");
 ! 			
 ! 			if (is_digit(c)) {
 ! 				do {
 ! 					STPUTC(c, out);
 ! 					c = pgetc();
 ! 				} while( is_digit(c));
 ! 			} else {
 ! 				USTPUTC(c, out);
 ! 				c = pgetc();
 ! 			}
   		}
   		STPUTC('=', out);
   		flags = 0;
 
 Index: expand.c
 ===================================================================
 RCS file: /home/ncvs/src/bin/sh/expand.c,v
 retrieving revision 1.4
 diff -c -r1.4 expand.c
 *** expand.c	1995/05/30 00:07:13	1.4
 --- expand.c	1996/05/24 17:13:03
 ***************
 *** 90,97 ****
   STATIC void argstr(char *, int);
   STATIC void expbackq(union node *, int, int);
   STATIC char *evalvar(char *, int);
 ! STATIC int varisset(int);
 ! STATIC void varvalue(int, int, int);
   STATIC void recordregion(int, int, int);
   STATIC void ifsbreakup(char *, struct arglist *);
   STATIC void expandmeta(struct strlist *, int);
 --- 90,97 ----
   STATIC void argstr(char *, int);
   STATIC void expbackq(union node *, int, int);
   STATIC char *evalvar(char *, int);
 ! STATIC int varisset(char *);
 ! STATIC void varvalue(char *, int, int);
   STATIC void recordregion(int, int, int);
   STATIC void ifsbreakup(char *, struct arglist *);
   STATIC void expandmeta(struct strlist *, int);
 ***************
 *** 453,459 ****
   	p = strchr(p, '=') + 1;
   again: /* jump here after setting a variable with ${var=text} */
   	if (special) {
 ! 		set = varisset(*var);
   		val = NULL;
   	} else {
   		val = lookupvar(var);
 --- 453,459 ----
   	p = strchr(p, '=') + 1;
   again: /* jump here after setting a variable with ${var=text} */
   	if (special) {
 ! 		set = varisset(var);
   		val = NULL;
   	} else {
   		val = lookupvar(var);
 ***************
 *** 467,473 ****
   	if (set && subtype != VSPLUS) {
   		/* insert the value of the variable */
   		if (special) {
 ! 			varvalue(*var, varflags & VSQUOTE, flag & EXP_FULL);
   		} else {
   			char const *syntax = (varflags & VSQUOTE)? DQSYNTAX : BASESYNTAX;
   
 --- 467,473 ----
   	if (set && subtype != VSPLUS) {
   		/* insert the value of the variable */
   		if (special) {
 ! 			varvalue(var, varflags & VSQUOTE, flag & EXP_FULL);
   		} else {
   			char const *syntax = (varflags & VSQUOTE)? DQSYNTAX : BASESYNTAX;
   
 ***************
 *** 539,560 ****
   
   STATIC int
   varisset(name)
 ! 	char name;
   	{
   	char **ap;
   
 ! 	if (name == '!') {
   		if (backgndpid == -1)
   			return 0;
 ! 	} else if (name == '@' || name == '*') {
   		if (*shellparam.p == NULL)
   			return 0;
 ! 	} else if ((unsigned)(name -= '1') <= '9' - '1') {
 ! 		ap = shellparam.p;
 ! 		do {
 ! 			if (*ap++ == NULL)
 ! 				return 0;
 ! 		} while (--name >= 0);
   	}
   	return 1;
   }
 --- 539,571 ----
   
   STATIC int
   varisset(name)
 ! 	char *name;
   	{
 + 	char *t;
 + 	int numvar;
   	char **ap;
   
 ! 	if (*name == '!') {
   		if (backgndpid == -1)
   			return 0;
 ! 	} else if (*name == '@' || *name == '*') {
   		if (*shellparam.p == NULL)
   			return 0;
 ! 	} else {
 ! 		t = name;
 ! 		while (is_digit(*t++)) {
 ! 			;
 ! 		}
 ! 
 ! 		if ( *--t == '=' ) { 
 ! 			*t = '\0';
 ! 			numvar = atoi(name);
 ! 			ap = shellparam.p;
 ! 			do {
 ! 				if (*ap++ == NULL)
 ! 					return 0;
 ! 			} while (--numvar > 0);
 ! 		} 
   	}
   	return 1;
   }
 ***************
 *** 567,577 ****
   
   STATIC void
   varvalue(name, quoted, allow_split)
 ! 	char name;
   	{
   	int num;
   	char temp[32];
   	char *p;
   	int i;
   	extern int exitstatus;
   	char sep;
 --- 578,590 ----
   
   STATIC void
   varvalue(name, quoted, allow_split)
 ! 	char *name;
   	{
   	int num;
 + 	int numvar;
   	char temp[32];
   	char *p;
 + 	char *t;
   	int i;
   	extern int exitstatus;
   	char sep;
 ***************
 *** 593,599 ****
   	} while (0)
   
   
 ! 	switch (name) {
   	case '$':
   		num = rootpid;
   		goto numvar;
 --- 606,612 ----
   	} while (0)
   
   
 ! 	switch (*name) {
   	case '$':
   		num = rootpid;
   		goto numvar;
 ***************
 *** 640,647 ****
   		STRTODEST(p);
   		break;
   	default:
 ! 		if ((unsigned)(name -= '1') <= '9' - '1') {
 ! 			p = shellparam.p[name];
   			STRTODEST(p);
   		}
   		break;
 --- 653,666 ----
   		STRTODEST(p);
   		break;
   	default:
 ! 
 ! 		t = name;
 ! 		while (is_digit(*t++)) {
 ! 		}
 ! 
 ! 		if ( *t == '\0' ) { 
 ! 			numvar = atoi(name);
 ! 			p = shellparam.p[numvar-1];
   			STRTODEST(p);
   		}
   		break;
 -- 
 -------------------------------------------------------------------
 Lars Fredriksen		fredriks@mcs.com		(home)
 			lars@fredriks.pr.mcs.net	(home-home)
Responsible-Changed-From-To: freebsd-bugs->joerg 
Responsible-Changed-By: joerg 
Responsible-Changed-When: Sun May 26 20:22:35 MET DST 1996 
Responsible-Changed-Why:  
I'm collecting sh(1) PRs. 

From: "Lars Fredriksen" <fredriks@mcs.com>
To: fredriks@mcs.com (Lars Fredriksen)
Cc: joerg_wunsch@uriah.heep.sax.de, FreeBSD-gnats-submit@freebsd.org
Subject: Re: bin/1248: shell having problem parsing arguments
Date: Tue, 28 May 1996 12:12:04 -0500 (CDT)

 Hi,
 	Here is a revised patch to expand.c that does work. It was tested on
 a make install in /usr/src. The previous patch to expand.c would dump core 
 doing this. Please consider this patch to expand.c to superseed the one
 previously submitted.
 
 Lars
 
 
 Index: expand.c
 ===================================================================
 RCS file: /home/ncvs/src/bin/sh/expand.c,v
 retrieving revision 1.4
 diff -c -r1.4 expand.c
 *** expand.c	1995/05/30 00:07:13	1.4
 --- expand.c	1996/05/28 16:19:42
 ***************
 *** 90,97 ****
   STATIC void argstr(char *, int);
   STATIC void expbackq(union node *, int, int);
   STATIC char *evalvar(char *, int);
 ! STATIC int varisset(int);
 ! STATIC void varvalue(int, int, int);
   STATIC void recordregion(int, int, int);
   STATIC void ifsbreakup(char *, struct arglist *);
   STATIC void expandmeta(struct strlist *, int);
 --- 90,97 ----
   STATIC void argstr(char *, int);
   STATIC void expbackq(union node *, int, int);
   STATIC char *evalvar(char *, int);
 ! STATIC int varisset(char *);
 ! STATIC void varvalue(char *, int, int);
   STATIC void recordregion(int, int, int);
   STATIC void ifsbreakup(char *, struct arglist *);
   STATIC void expandmeta(struct strlist *, int);
 ***************
 *** 453,459 ****
   	p = strchr(p, '=') + 1;
   again: /* jump here after setting a variable with ${var=text} */
   	if (special) {
 ! 		set = varisset(*var);
   		val = NULL;
   	} else {
   		val = lookupvar(var);
 --- 453,459 ----
   	p = strchr(p, '=') + 1;
   again: /* jump here after setting a variable with ${var=text} */
   	if (special) {
 ! 		set = varisset(var);
   		val = NULL;
   	} else {
   		val = lookupvar(var);
 ***************
 *** 467,473 ****
   	if (set && subtype != VSPLUS) {
   		/* insert the value of the variable */
   		if (special) {
 ! 			varvalue(*var, varflags & VSQUOTE, flag & EXP_FULL);
   		} else {
   			char const *syntax = (varflags & VSQUOTE)? DQSYNTAX : BASESYNTAX;
   
 --- 467,473 ----
   	if (set && subtype != VSPLUS) {
   		/* insert the value of the variable */
   		if (special) {
 ! 			varvalue(var, varflags & VSQUOTE, flag & EXP_FULL);
   		} else {
   			char const *syntax = (varflags & VSQUOTE)? DQSYNTAX : BASESYNTAX;
   
 ***************
 *** 539,560 ****
   
   STATIC int
   varisset(name)
 ! 	char name;
   	{
   	char **ap;
   
 ! 	if (name == '!') {
   		if (backgndpid == -1)
   			return 0;
 ! 	} else if (name == '@' || name == '*') {
   		if (*shellparam.p == NULL)
   			return 0;
 ! 	} else if ((unsigned)(name -= '1') <= '9' - '1') {
 ! 		ap = shellparam.p;
 ! 		do {
 ! 			if (*ap++ == NULL)
 ! 				return 0;
 ! 		} while (--name >= 0);
   	}
   	return 1;
   }
 --- 539,573 ----
   
   STATIC int
   varisset(name)
 ! 	char *name;
   	{
 + 	char *t;
 + 	char temp[32];
 + 	int numvar;
   	char **ap;
   
 ! 	if (*name == '!') {
   		if (backgndpid == -1)
   			return 0;
 ! 	} else if (*name == '@' || *name == '*') {
   		if (*shellparam.p == NULL)
   			return 0;
 ! 	} else {
 ! 		t = strcpy(temp, name);
 ! 
 ! 		while (is_digit(*t++)) {
 ! 			;
 ! 		}
 ! 
 ! 		if ( *--t == '=' ) { 
 ! 			*t = '\0';
 ! 			numvar = atoi(temp);
 ! 			ap = shellparam.p;
 ! 			do {
 ! 				if (*ap++ == NULL)
 ! 					return 0;
 ! 			} while (--numvar > 0);
 ! 		} 
   	}
   	return 1;
   }
 ***************
 *** 567,577 ****
   
   STATIC void
   varvalue(name, quoted, allow_split)
 ! 	char name;
   	{
   	int num;
   	char temp[32];
   	char *p;
   	int i;
   	extern int exitstatus;
   	char sep;
 --- 580,592 ----
   
   STATIC void
   varvalue(name, quoted, allow_split)
 ! 	char *name;
   	{
   	int num;
 + 	int numvar;
   	char temp[32];
   	char *p;
 + 	char *t;
   	int i;
   	extern int exitstatus;
   	char sep;
 ***************
 *** 593,599 ****
   	} while (0)
   
   
 ! 	switch (name) {
   	case '$':
   		num = rootpid;
   		goto numvar;
 --- 608,614 ----
   	} while (0)
   
   
 ! 	switch (*name) {
   	case '$':
   		num = rootpid;
   		goto numvar;
 ***************
 *** 640,647 ****
   		STRTODEST(p);
   		break;
   	default:
 ! 		if ((unsigned)(name -= '1') <= '9' - '1') {
 ! 			p = shellparam.p[name];
   			STRTODEST(p);
   		}
   		break;
 --- 655,670 ----
   		STRTODEST(p);
   		break;
   	default:
 ! 
 ! 		t = strcpy(temp, name);
 ! 		while (is_digit(*t++)) {
 ! 			;
 ! 		}
 ! 
 ! 		if ( *--t == '=' ) { 
 ! 			*t = '\0';
 ! 			numvar = atoi(temp);
 ! 			p = shellparam.p[numvar-1];
   			STRTODEST(p);
   		}
   		break;
 
 -- 
 -------------------------------------------------------------------
 Lars Fredriksen		fredriks@mcs.com		(home)
 			lars@fredriks.pr.mcs.net	(home-home)

From: "Lars Fredriksen" <fredriks@mcs.com>
To: fredriks@mcs.com (Lars Fredriksen)
Cc: joerg_wunsch@uriah.heep.sax.de, FreeBSD-gnats-submit@FreeBSD.org
Subject: Re: bin/1248: shell having problem parsing arguments
Date: Wed, 29 May 1996 10:53:35 -0500 (CDT)

 Hi again,
 	I managed to loose $0, so here is yet another superseed
 expand.c context diff. This one should be the last.
 
 Lars
 
 
 Index: expand.c
 ===================================================================
 RCS file: /home/ncvs/src/bin/sh/expand.c,v
 retrieving revision 1.4
 diff -c -r1.4 expand.c
 *** expand.c	1995/05/30 00:07:13	1.4
 --- expand.c	1996/05/29 15:42:58
 ***************
 *** 90,97 ****
   STATIC void argstr(char *, int);
   STATIC void expbackq(union node *, int, int);
   STATIC char *evalvar(char *, int);
 ! STATIC int varisset(int);
 ! STATIC void varvalue(int, int, int);
   STATIC void recordregion(int, int, int);
   STATIC void ifsbreakup(char *, struct arglist *);
   STATIC void expandmeta(struct strlist *, int);
 --- 90,97 ----
   STATIC void argstr(char *, int);
   STATIC void expbackq(union node *, int, int);
   STATIC char *evalvar(char *, int);
 ! STATIC int varisset(char *);
 ! STATIC void varvalue(char *, int, int);
   STATIC void recordregion(int, int, int);
   STATIC void ifsbreakup(char *, struct arglist *);
   STATIC void expandmeta(struct strlist *, int);
 ***************
 *** 453,459 ****
   	p = strchr(p, '=') + 1;
   again: /* jump here after setting a variable with ${var=text} */
   	if (special) {
 ! 		set = varisset(*var);
   		val = NULL;
   	} else {
   		val = lookupvar(var);
 --- 453,459 ----
   	p = strchr(p, '=') + 1;
   again: /* jump here after setting a variable with ${var=text} */
   	if (special) {
 ! 		set = varisset(var);
   		val = NULL;
   	} else {
   		val = lookupvar(var);
 ***************
 *** 467,473 ****
   	if (set && subtype != VSPLUS) {
   		/* insert the value of the variable */
   		if (special) {
 ! 			varvalue(*var, varflags & VSQUOTE, flag & EXP_FULL);
   		} else {
   			char const *syntax = (varflags & VSQUOTE)? DQSYNTAX : BASESYNTAX;
   
 --- 467,473 ----
   	if (set && subtype != VSPLUS) {
   		/* insert the value of the variable */
   		if (special) {
 ! 			varvalue(var, varflags & VSQUOTE, flag & EXP_FULL);
   		} else {
   			char const *syntax = (varflags & VSQUOTE)? DQSYNTAX : BASESYNTAX;
   
 ***************
 *** 539,560 ****
   
   STATIC int
   varisset(name)
 ! 	char name;
   	{
   	char **ap;
   
 ! 	if (name == '!') {
   		if (backgndpid == -1)
   			return 0;
 ! 	} else if (name == '@' || name == '*') {
   		if (*shellparam.p == NULL)
   			return 0;
 ! 	} else if ((unsigned)(name -= '1') <= '9' - '1') {
 ! 		ap = shellparam.p;
 ! 		do {
 ! 			if (*ap++ == NULL)
 ! 				return 0;
 ! 		} while (--name >= 0);
   	}
   	return 1;
   }
 --- 539,575 ----
   
   STATIC int
   varisset(name)
 ! 	char *name;
   	{
 + 	char *t;
 + 	char temp[32];
 + 	int numvar;
   	char **ap;
   
 ! 	if (*name == '!') {
   		if (backgndpid == -1)
   			return 0;
 ! 	} else if (*name == '@' || *name == '*') {
   		if (*shellparam.p == NULL)
   			return 0;
 ! 	} else {
 ! 		t = strcpy(temp, name);
 ! 
 ! 		while (is_digit(*t++)) {
 ! 			;
 ! 		}
 ! 
 ! 		if ( *--t == '=' ) { 
 ! 			*t = '\0';
 ! 			numvar = atoi(temp);
 ! 			if (numvar > 0 ) {
 ! 				ap = shellparam.p;
 ! 				do {
 ! 					if (*ap++ == NULL)
 ! 						return 0;
 ! 				} while (--numvar > 0);
 ! 			} 
 ! 		} 
   	}
   	return 1;
   }
 ***************
 *** 567,577 ****
   
   STATIC void
   varvalue(name, quoted, allow_split)
 ! 	char name;
   	{
   	int num;
   	char temp[32];
   	char *p;
   	int i;
   	extern int exitstatus;
   	char sep;
 --- 582,594 ----
   
   STATIC void
   varvalue(name, quoted, allow_split)
 ! 	char *name;
   	{
   	int num;
 + 	int numvar;
   	char temp[32];
   	char *p;
 + 	char *t;
   	int i;
   	extern int exitstatus;
   	char sep;
 ***************
 *** 593,599 ****
   	} while (0)
   
   
 ! 	switch (name) {
   	case '$':
   		num = rootpid;
   		goto numvar;
 --- 610,616 ----
   	} while (0)
   
   
 ! 	switch (*name) {
   	case '$':
   		num = rootpid;
   		goto numvar;
 ***************
 *** 640,647 ****
   		STRTODEST(p);
   		break;
   	default:
 ! 		if ((unsigned)(name -= '1') <= '9' - '1') {
 ! 			p = shellparam.p[name];
   			STRTODEST(p);
   		}
   		break;
 --- 657,672 ----
   		STRTODEST(p);
   		break;
   	default:
 ! 
 ! 		t = strcpy(temp, name);
 ! 		while (is_digit(*t++)) {
 ! 			;
 ! 		}
 ! 
 ! 		if ( *--t == '=' ) { 
 ! 			*t = '\0';
 ! 			numvar = atoi(temp);
 ! 			p = shellparam.p[numvar-1];
   			STRTODEST(p);
   		}
   		break;
 -- 
 -------------------------------------------------------------------
 Lars Fredriksen		fredriks@mcs.com		(home)
 			lars@fredriks.pr.mcs.net	(home-home)

From: "Lars Fredriksen" <fredriks@mcs.com>
To: fredriks@mcs.com (Lars Fredriksen)
Cc: joerg_wunsch@uriah.heep.sax.de, FreeBSD-gnats-submit@FreeBSD.org
Subject: Re: bin/1248: shell having problem parsing arguments
Date: Fri, 31 May 1996 12:43:42 -0500 (CDT)

 Hi joerg,
 	This is getting embarresing, here is  yet another version of expand.c.
 Interessting what overwiting lage porsions of the stack will do to you :-)
 
 Basic change is that a strcpy() has been changed to a strncpy().
 
 Lars
 
 
 Index: expand.c
 ===================================================================
 RCS file: /home/ncvs/src/bin/sh/expand.c,v
 retrieving revision 1.4
 diff -c -r1.4 expand.c
 *** expand.c	1995/05/30 00:07:13	1.4
 --- expand.c	1996/05/31 16:26:22
 ***************
 *** 90,97 ****
   STATIC void argstr(char *, int);
   STATIC void expbackq(union node *, int, int);
   STATIC char *evalvar(char *, int);
 ! STATIC int varisset(int);
 ! STATIC void varvalue(int, int, int);
   STATIC void recordregion(int, int, int);
   STATIC void ifsbreakup(char *, struct arglist *);
   STATIC void expandmeta(struct strlist *, int);
 --- 90,97 ----
   STATIC void argstr(char *, int);
   STATIC void expbackq(union node *, int, int);
   STATIC char *evalvar(char *, int);
 ! STATIC int varisset(char *);
 ! STATIC void varvalue(char *, int, int);
   STATIC void recordregion(int, int, int);
   STATIC void ifsbreakup(char *, struct arglist *);
   STATIC void expandmeta(struct strlist *, int);
 ***************
 *** 453,459 ****
   	p = strchr(p, '=') + 1;
   again: /* jump here after setting a variable with ${var=text} */
   	if (special) {
 ! 		set = varisset(*var);
   		val = NULL;
   	} else {
   		val = lookupvar(var);
 --- 453,459 ----
   	p = strchr(p, '=') + 1;
   again: /* jump here after setting a variable with ${var=text} */
   	if (special) {
 ! 		set = varisset(var);
   		val = NULL;
   	} else {
   		val = lookupvar(var);
 ***************
 *** 467,473 ****
   	if (set && subtype != VSPLUS) {
   		/* insert the value of the variable */
   		if (special) {
 ! 			varvalue(*var, varflags & VSQUOTE, flag & EXP_FULL);
   		} else {
   			char const *syntax = (varflags & VSQUOTE)? DQSYNTAX : BASESYNTAX;
   
 --- 467,473 ----
   	if (set && subtype != VSPLUS) {
   		/* insert the value of the variable */
   		if (special) {
 ! 			varvalue(var, varflags & VSQUOTE, flag & EXP_FULL);
   		} else {
   			char const *syntax = (varflags & VSQUOTE)? DQSYNTAX : BASESYNTAX;
   
 ***************
 *** 539,560 ****
   
   STATIC int
   varisset(name)
 ! 	char name;
   	{
   	char **ap;
   
 ! 	if (name == '!') {
   		if (backgndpid == -1)
   			return 0;
 ! 	} else if (name == '@' || name == '*') {
   		if (*shellparam.p == NULL)
   			return 0;
 ! 	} else if ((unsigned)(name -= '1') <= '9' - '1') {
 ! 		ap = shellparam.p;
 ! 		do {
 ! 			if (*ap++ == NULL)
 ! 				return 0;
 ! 		} while (--name >= 0);
   	}
   	return 1;
   }
 --- 539,576 ----
   
   STATIC int
   varisset(name)
 ! 	char *name;
   	{
 + 	char *t;
 + 	char temp[32];
 + 	int numvar;
   	char **ap;
   
 ! 	if (*name == '!') {
   		if (backgndpid == -1)
   			return 0;
 ! 	} else if (*name == '@' || *name == '*') {
   		if (*shellparam.p == NULL)
   			return 0;
 ! 	} else {
 ! 		t = strncpy(temp, name, sizeof(temp)-1);
 ! 		temp[31] = '\0';
 ! 
 ! 		while (is_digit(*t++)) {
 ! 			;
 ! 		}
 ! 
 ! 		if ( *--t == '=' ) { 
 ! 			*t = '\0';
 ! 			numvar = atoi(temp);
 ! 			if (numvar > 0 ) {
 ! 				ap = shellparam.p;
 ! 				do {
 ! 					if (*ap++ == NULL)
 ! 						return 0;
 ! 				} while (--numvar > 0);
 ! 			} 
 ! 		} 
   	}
   	return 1;
   }
 ***************
 *** 567,577 ****
   
   STATIC void
   varvalue(name, quoted, allow_split)
 ! 	char name;
   	{
   	int num;
   	char temp[32];
   	char *p;
   	int i;
   	extern int exitstatus;
   	char sep;
 --- 583,595 ----
   
   STATIC void
   varvalue(name, quoted, allow_split)
 ! 	char *name;
   	{
   	int num;
 + 	int numvar;
   	char temp[32];
   	char *p;
 + 	char *t;
   	int i;
   	extern int exitstatus;
   	char sep;
 ***************
 *** 593,599 ****
   	} while (0)
   
   
 ! 	switch (name) {
   	case '$':
   		num = rootpid;
   		goto numvar;
 --- 611,617 ----
   	} while (0)
   
   
 ! 	switch (*name) {
   	case '$':
   		num = rootpid;
   		goto numvar;
 ***************
 *** 640,647 ****
   		STRTODEST(p);
   		break;
   	default:
 ! 		if ((unsigned)(name -= '1') <= '9' - '1') {
 ! 			p = shellparam.p[name];
   			STRTODEST(p);
   		}
   		break;
 --- 658,674 ----
   		STRTODEST(p);
   		break;
   	default:
 ! 
 ! 		t = strncpy(temp, name, sizeof(temp)-1);
 ! 		temp[31] = '\0';
 ! 		while (is_digit(*t++)) {
 ! 			;
 ! 		}
 ! 
 ! 		if ( *--t == '=' ) { 
 ! 			*t = '\0';
 ! 			numvar = atoi(temp);
 ! 			p = shellparam.p[numvar-1];
   			STRTODEST(p);
   		}
   		break;
 -- 
 -------------------------------------------------------------------
 Lars Fredriksen		fredriks@mcs.com		(home)
 			lars@fredriks.pr.mcs.net	(home-home)
State-Changed-From-To: open->closed 
State-Changed-By: peter 
State-Changed-When: Mon Sep 9 18:24:38 PDT 1996 
State-Changed-Why:  
Fixed in expand.c rev 1.8 and parser.c rev 1.14 
>Unformatted:
 >Repeat-By:
 	JUNK="1 2 3 4 5 6 7 8 9 10 11 12"
 	set $JUNK
 	echo ${11}
 
 
