Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 19 Jun 2009 22:09:55 +0000 (UTC)
From:      Jilles Tjoelker <jilles@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r194516 - head/bin/sh
Message-ID:  <200906192209.n5JM9tVK056725@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jilles
Date: Fri Jun 19 22:09:55 2009
New Revision: 194516
URL: http://svn.freebsd.org/changeset/base/194516

Log:
  Fix some issues with quoted output and shorten it in some cases.
  
  Output quoted suitable for re-input to the shell occurs in
  various cases such as 'set', 'trap'.
  
  Bugfix: *, ? and [ must be quoted (except sole [)
  Bugfix: ~ and # must be quoted (really only sometimes, but keep it simple)
  Bugfix: space, tab and newline must always be quoted
  Shortening: other IFS characters do not need quoting
  Bugfix: send to correct output file, not hard-coded stdout
  Shortening: avoid unnecessary '' with \'
  
  Approved by:	ed (mentor)

Modified:
  head/bin/sh/output.c

Modified: head/bin/sh/output.c
==============================================================================
--- head/bin/sh/output.c	Fri Jun 19 21:14:39 2009	(r194515)
+++ head/bin/sh/output.c	Fri Jun 19 22:09:55 2009	(r194516)
@@ -133,32 +133,38 @@ void
 outqstr(const char *p, struct output *file)
 {
 	char ch;
+	int inquotes;
 
 	if (p[0] == '\0') {
 		outstr("''", file);
 		return;
 	}
-	if (p[strcspn(p, "|&;<>()$`\\\"'")] == '\0' && (!ifsset() ||
-	    p[strcspn(p, ifsval())] == '\0')) {
+	/* Caller will handle '=' if necessary */
+	if (p[strcspn(p, "|&;<>()$`\\\"' \t\n*?[~#")] == '\0' ||
+			strcmp(p, "[") == 0) {
 		outstr(p, file);
 		return;
 	}
 
-	out1c('\'');
+	inquotes = 0;
 	while ((ch = *p++) != '\0') {
 		switch (ch) {
 		case '\'':
-			/*
-			 * Can't quote single quotes inside single quotes;
-			 * close them, write escaped single quote, open again.
-			 */
-			outstr("'\\''", file);
+			/* Can't quote single quotes inside single quotes. */
+			if (inquotes)
+				outc('\'', file);
+			inquotes = 0;
+			outstr("\\'", file);
 			break;
 		default:
+			if (!inquotes)
+				outc('\'', file);
+			inquotes = 1;
 			outc(ch, file);
 		}
 	}
-	out1c('\'');
+	if (inquotes)
+		outc('\'', file);
 }
 
 STATIC char out_junk[16];



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906192209.n5JM9tVK056725>