summary refs log tree commit diff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2005-11-14 21:20:36 +1100
committerHerbert Xu <herbert@gondor.apana.org.au>2005-11-14 21:20:36 +1100
commitaee564cf4bc8616385493580f5375c3368647653 (patch)
treeaebf8be974d09bc3d5d726163077e2ba061a514d
parent[BUILTIN] Always call conv_escape_str in echocmd (diff)
downloaddash-aee564cf4bc8616385493580f5375c3368647653.tar.gz
dash-aee564cf4bc8616385493580f5375c3368647653.zip
[BUILTIN] Fix \c spillage across echo commands
On Thu, Nov 03, 2005 at 07:16:53PM +0100, Mike Hommey wrote:
> Here is a simple test case:
>
> #!/bin/dash
> echo test\\ test
> echo '\c'
> echo test\\ test
>
> it outputs:
> test\ test
> test\
>
> This is due to mis-usage of a global variable. See attached patch for a
> fix.

Instead of setting rval when \c is detected, this is now set in the
return value of conv_escape_str.  This prevents the spillage reported
in http://bugs.debian.org/337294.
Diffstat (limited to '')
-rw-r--r--ChangeLog4
-rw-r--r--src/bltin/printf.c23
2 files changed, 16 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index a8def74..20eee4d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2005-11-14  Herbert Xu <herbert@gondor.apana.org.au>
+
+	* Fix \c spillage across echo commands.
+
 2005-11-13  Herbert Xu <herbert@gondor.apana.org.au>
 
 	* Remove unnecessary truncation in _STPUTC.
diff --git a/src/bltin/printf.c b/src/bltin/printf.c
index ef9b2b4..b0c3774 100644
--- a/src/bltin/printf.c
+++ b/src/bltin/printf.c
@@ -40,7 +40,7 @@
 #include <string.h>
 #include <unistd.h>
 
-static char	*conv_escape_str(char *);
+static int	 conv_escape_str(char *);
 static char	*conv_escape(char *, int *);
 static int	 getchr(void);
 static double	 getdouble(void);
@@ -155,11 +155,12 @@ pc:
 			switch (ch) {
 
 			case 'b': {
-				char *p = conv_escape_str(getstr());
+				int done = conv_escape_str(getstr());
+				char *p = stackblock();
 				*fmt = 's';
 				PF(start, p);
 				/* escape if a \c was encountered */
-				if (rval & 0x100)
+				if (done)
 					goto out;
 				*fmt = 'b';
 				break;
@@ -208,7 +209,7 @@ pc:
 	} while (gargv != argv && *gargv);
 
 out:
-	return (rval & ~0x100);
+	return rval;
 err:
 	return 1;
 }
@@ -218,7 +219,7 @@ err:
  * Print SysV echo(1) style escape string 
  *	Halts processing string if a \c escape is encountered.
  */
-static char *
+static int
 conv_escape_str(char *str)
 {
 	int ch;
@@ -237,8 +238,7 @@ conv_escape_str(char *str)
 		ch = *str++;
 		if (ch == 'c') {
 			/* \c as in SYSV echo - abort all processing.... */
-			rval |= 0x100;
-			ch = 0;
+			ch = 0x100;
 			continue;
 		}
 
@@ -265,9 +265,9 @@ conv_escape_str(char *str)
 		/* Finally test for sequences valid in the format string */
 		str = conv_escape(str - 1, &c);
 		ch = c;
-	} while (STPUTC(ch, cp), ch);
+	} while (STPUTC(ch, cp), (char)ch);
 
-	return stackblock();
+	return ch;
 }
 
 /*
@@ -445,8 +445,9 @@ echocmd(int argc, char **argv)
 	do {
 		char c;
 
-		outstr(conv_escape_str(*argv), outs);
-		if (rval & 0x100)
+		nonl += conv_escape_str(*argv);
+		outstr(stackblock(), outs);
+		if (nonl > 0)
 			break;
 
 		c = ' ';