Bug 28449

Summary: sh(1) aborts on certain input
Product: Base System Reporter: ru <ru>
Component: binAssignee: Martin Cracauer <cracauer>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 5.0-CURRENT   
Hardware: Any   
OS: Any   

Description ru freebsd_committer freebsd_triage 2001-06-27 13:40:07 UTC
sh(1) calls abort(3) on certain input (backslash followed by
the character with ASCII code 130).

How-To-Repeat: sh -c 'echo -e echo "\\\\\0202"' |sh
Abort trap - core dumped
Comment 1 Tor Egge 2001-06-28 03:07:07 UTC
Try this patch.

Index: expand.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/expand.c,v
retrieving revision 1.32
diff -u -r1.32 expand.c
--- expand.c	2000/05/15 12:33:17	1.32
+++ expand.c	2001/03/04 23:52:35
@@ -315,7 +315,7 @@
 		goto lose;
 	*p = c;
 	while ((c = *home++) != '\0') {
-		if (quotes && c >= 0 && SQSYNTAX[(int)c] == CCTL)
+		if (quotes && SQSYNTAX[(int)c] == CCTL)
 			STPUTC(CTLESC, expdest);
 		STPUTC(c, expdest);
 	}
@@ -478,7 +478,7 @@
 		}
 		lastc = *p++;
 		if (lastc != '\0') {
-			if (quotes && lastc >= 0 && syntax[(int)lastc] == CCTL)
+			if (quotes && syntax[(int)lastc] == CCTL)
 				STPUTC(CTLESC, dest);
 			STPUTC(lastc, dest);
 		}
@@ -694,7 +694,7 @@
 			}
 			else {
 				while (*val) {
-					if (quotes && *val >= 0 &&
+					if (quotes &&
 					    syntax[(int)*val] == CCTL)
 						STPUTC(CTLESC, expdest);
 					STPUTC(*val++, expdest);
@@ -866,7 +866,7 @@
 	if (allow_split) { \
 		syntax = quoted? DQSYNTAX : BASESYNTAX; \
 		while (*p) { \
-			if (*p >= 0 && syntax[(int)*p] == CCTL) \
+			if (syntax[(int)*p] == CCTL) \
 				STPUTC(CTLESC, expdest); \
 			STPUTC(*p++, expdest); \
 		} \
Index: mksyntax.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/mksyntax.c,v
retrieving revision 1.15
diff -u -r1.15 mksyntax.c
--- mksyntax.c	2001/06/19 15:41:57	1.15
+++ mksyntax.c	2001/06/21 21:54:20
@@ -352,9 +352,9 @@
 
 static char *macro[] = {
 	"#define is_digit(c)\t((c >= 0 && is_type+SYNBASE)[c] & ISDIGIT)",
-	"#define is_alpha(c)\t((c) != PEOF && ((c) < CTLESC || (c) > CTLENDARI) && isalpha((unsigned char) (c)))",
-	"#define is_name(c)\t((c) != PEOF && ((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalpha((unsigned char) (c))))",
-	"#define is_in_name(c)\t((c) != PEOF && ((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalnum((unsigned char) (c))))",
+	"#define is_alpha(c)\t((c) != PEOF && ((c) < CTLESC || (c) > CTLQUOTEMARK) && isalpha((unsigned char) (c)))",
+	"#define is_name(c)\t((c) != PEOF && ((c) < CTLESC || (c) > CTLQUOTEMARK) && ((c) == '_' || isalpha((unsigned char) (c))))",
+	"#define is_in_name(c)\t((c) != PEOF && ((c) < CTLESC || (c) > CTLQUOTEMARK) && ((c) == '_' || isalnum((unsigned char) (c))))",
 	"#define is_special(c)\t((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))",
 	NULL
 };
Index: parser.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/parser.c,v
retrieving revision 1.36
diff -u -r1.36 parser.c
--- parser.c	2001/04/09 12:46:19	1.36
+++ parser.c	2001/04/17 18:27:52
@@ -977,7 +977,7 @@
 					    c != '`' && c != '$' &&
 					    (c != '"' || eofmark != NULL))
 						USTPUTC('\\', out);
-					if (c >= 0 && SQSYNTAX[c] == CCTL)
+					if (SQSYNTAX[c] == CCTL)
 						USTPUTC(CTLESC, out);
 					else if (eofmark == NULL)
 						USTPUTC(CTLQUOTEMARK, out);
@@ -1496,7 +1496,7 @@
 			continue;
 		if (c == CTLESC)
 			p++;
-		else if (c >= 0 && BASESYNTAX[(int)c] == CCTL)
+		else if (BASESYNTAX[(int)c] == CCTL)
 			return 0;
 	}
 	return 1;


- Tor Egge
Comment 2 ru freebsd_committer freebsd_triage 2001-06-29 08:11:22 UTC
Nope, doesn't work.  Your patch only hides the real bug, and
simply backs out changes Martin did in parser.c,v 1.27, etc.

> Index: parser.c
> ===================================================================
> RCS file: /home/ncvs/src/bin/sh/parser.c,v
> retrieving revision 1.36
> diff -u -r1.36 parser.c
> --- parser.c	2001/04/09 12:46:19	1.36
> +++ parser.c	2001/04/17 18:27:52
> @@ -977,7 +977,7 @@
>  					    c != '`' && c != '$' &&
>  					    (c != '"' || eofmark != NULL))
>  						USTPUTC('\\', out);
> -					if (c >= 0 && SQSYNTAX[c] == CCTL)
> +					if (SQSYNTAX[c] == CCTL)
>  						USTPUTC(CTLESC, out);
>  					else if (eofmark == NULL)
>  						USTPUTC(CTLQUOTEMARK, out);

With my test, `c' will be -126 here, and SQSYNTAX[-126] is obviously the
wrong thing.

Funny though, I've managed to make almost identical patch before I sent
a PR.  :-)

Then realized that it's bogus, and the actual problem is that our sh(1)
is not 8-bit clean (apparently).


Cheers,
-- 
Ruslan Ermilov		Oracle Developer/DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer,
+380.652.512.251	Simferopol, Ukraine

http://www.FreeBSD.org	The Power To Serve
http://www.oracle.com	Enabling The Information Age
Comment 3 Tor Egge 2001-06-29 13:14:49 UTC
> With my test, `c' will be -126 here, and SQSYNTAX[-126] is obviously t=
he
> wrong thing.

It is obviously the right thing.

From=20the generated file syntax.h:


	#define SYNBASE 129
	#define SQSYNTAX (sqsyntax + SYNBASE)

i.e. SQSYNTAX[-126] becomes (sqsyntax + 129)[-126] which is sqsyntax[3].=


- Tor Egge
Comment 4 ru freebsd_committer freebsd_triage 2001-06-29 13:18:20 UTC
Ouch, then this definitely works for me, at least this doesn't
abort(3)'s anymore.

On Fri, Jun 29, 2001 at 02:14:49PM +0200, Tor.Egge@fast.no wrote:
> 
> 
> > With my test, `c' will be -126 here, and SQSYNTAX[-126] is obviously the
> > wrong thing.
> 
> It is obviously the right thing.
> 
> >From the generated file syntax.h:
> 
> 
> 	#define SYNBASE 129
> 	#define SQSYNTAX (sqsyntax + SYNBASE)
> 
> i.e. SQSYNTAX[-126] becomes (sqsyntax + 129)[-126] which is sqsyntax[3].
> 
> - Tor Egge

-- 
Ruslan Ermilov		Oracle Developer/DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer,
+380.652.512.251	Simferopol, Ukraine

http://www.FreeBSD.org	The Power To Serve
http://www.oracle.com	Enabling The Information Age
Comment 5 Kris Kennaway freebsd_committer freebsd_triage 2001-07-01 22:29:33 UTC
Responsible Changed
From-To: freebsd-bugs->cracauer

Martin is the sh maintainer
Comment 6 Tim Robbins freebsd_committer freebsd_triage 2003-03-25 11:53:29 UTC
State Changed
From-To: open->closed

This has been fixed in -current and -stable for a while now.