| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | /* shquote - functions to quote and dequote strings */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | /* Copyright (C) 1999 Free Software Foundation, Inc.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This file is part of GNU Bash, the Bourne Again SHell. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    Bash is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |    it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |    the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |    (at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Bash is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |    GNU General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <config.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (HAVE_UNISTD_H)
 | 
					
						
							|  |  |  | #  ifdef _MINIX
 | 
					
						
							|  |  |  | #    include <sys/types.h>
 | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  | #  include <unistd.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | #include "syntax.h"
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #include <xmalloc.h>
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* **************************************************************** */ | 
					
						
							|  |  |  | /*								    */ | 
					
						
							|  |  |  | /*	 Functions for quoting strings to be re-read as input	    */ | 
					
						
							|  |  |  | /*								    */ | 
					
						
							|  |  |  | /* **************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Return a new string which is the single-quoted version of STRING.
 | 
					
						
							|  |  |  |    Used by alias and trap, among others. */ | 
					
						
							|  |  |  | char * | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | sh_single_quote (string) | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |      const char *string; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   register int c; | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |   char *result, *r; | 
					
						
							|  |  |  |   const char *s; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   result = (char *)xmalloc (3 + (4 * strlen (string))); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |   r = result; | 
					
						
							|  |  |  |   *r++ = '\''; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (s = string; s && (c = *s); s++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       *r++ = c; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (c == '\'') | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	  *r++ = '\\';	/* insert escaped single quote */ | 
					
						
							|  |  |  | 	  *r++ = '\''; | 
					
						
							|  |  |  | 	  *r++ = '\'';	/* start new quoted string */ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *r++ = '\''; | 
					
						
							|  |  |  |   *r = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (result); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Quote STRING using double quotes.  Return a new string. */ | 
					
						
							|  |  |  | char * | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | sh_double_quote (string) | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |      const char *string; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   register unsigned char c; | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |   char *result, *r; | 
					
						
							|  |  |  |   const char *s; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   result = (char *)xmalloc (3 + (2 * strlen (string))); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |   r = result; | 
					
						
							|  |  |  |   *r++ = '"'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (s = string; s && (c = *s); s++) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  |       /* Backslash-newline disappears within double quotes, so don't add one. */ | 
					
						
							|  |  |  |       if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n') | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 	*r++ = '\\'; | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |       else if (c == CTLESC || c == CTLNUL) | 
					
						
							|  |  |  | 	*r++ = CTLESC;		/* could be '\\'? */ | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       *r++ = c; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *r++ = '"'; | 
					
						
							|  |  |  |   *r = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (result); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | /* Turn S into a simple double-quoted string.  If FLAGS is non-zero, quote
 | 
					
						
							|  |  |  |    double quote characters in S with backslashes. */ | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | sh_mkdoublequoted (s, slen, flags) | 
					
						
							|  |  |  |      const char *s; | 
					
						
							|  |  |  |      int slen, flags; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char *r, *ret; | 
					
						
							|  |  |  |   int rlen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   rlen = (flags == 0) ? slen + 3 : (2 * slen) + 1; | 
					
						
							|  |  |  |   ret = r = (char *)xmalloc (rlen); | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   *r++ = '"'; | 
					
						
							|  |  |  |   while (*s) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (flags && *s == '"') | 
					
						
							|  |  |  | 	*r++ = '\\'; | 
					
						
							|  |  |  |       *r++ = *s++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   *r++ = '"'; | 
					
						
							|  |  |  |   *r = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | /* Remove backslashes that are quoting characters that are special between
 | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |    double quotes.  Return a new string.  XXX - should this handle CTLESC | 
					
						
							|  |  |  |    and CTLNUL? */ | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | char * | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | sh_un_double_quote (string) | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |      char *string; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register int c, pass_next; | 
					
						
							|  |  |  |   char *result, *r, *s; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   r = result = (char *)xmalloc (strlen (string) + 1); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   for (pass_next = 0, s = string; s && (c = *s); s++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (pass_next) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	  *r++ = c; | 
					
						
							|  |  |  | 	  pass_next = 0; | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |       if (c == '\\' && (sh_syntaxtab[(unsigned char) s[1]] & CBSDQUOTE)) | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 	  pass_next = 1; | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       *r++ = c; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *r = '\0'; | 
					
						
							|  |  |  |   return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Quote special characters in STRING using backslashes.  Return a new
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  |    string.  NOTE:  if the string is to be further expanded, we need a | 
					
						
							|  |  |  |    way to protect the CTLESC and CTLNUL characters.  As I write this, | 
					
						
							|  |  |  |    the current callers will never cause the string to be expanded without | 
					
						
							|  |  |  |    going through the shell parser, which will protect the internal | 
					
						
							|  |  |  |    quoting characters. */ | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | char * | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | sh_backslash_quote (string) | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |      char *string; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int c; | 
					
						
							|  |  |  |   char *result, *r, *s; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   result = (char *)xmalloc (2 * strlen (string) + 1); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   for (r = result, s = string; s && (c = *s); s++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       switch (c) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case ' ': case '\t': case '\n':		/* IFS white space */ | 
					
						
							|  |  |  | 	case '\'': case '"': case '\\':		/* quoting chars */ | 
					
						
							|  |  |  | 	case '|': case '&': case ';':		/* shell metacharacters */ | 
					
						
							|  |  |  | 	case '(': case ')': case '<': case '>': | 
					
						
							|  |  |  | 	case '!': case '{': case '}':		/* reserved words */ | 
					
						
							|  |  |  | 	case '*': case '[': case '?': case ']':	/* globbing chars */ | 
					
						
							|  |  |  | 	case '^': | 
					
						
							|  |  |  | 	case '$': case '`':			/* expansion chars */ | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | 	case ',':				/* brace expansion */ | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 	  *r++ = '\\'; | 
					
						
							|  |  |  | 	  *r++ = c; | 
					
						
							|  |  |  | 	  break; | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 	case '~':				/* tilde expansion */ | 
					
						
							|  |  |  | 	  if (s == string || s[-1] == '=' || s[-1] == ':') | 
					
						
							|  |  |  | 	    *r++ = '\\'; | 
					
						
							|  |  |  | 	  *r++ = c; | 
					
						
							|  |  |  | 	  break; | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 	case CTLESC: case CTLNUL:		/* internal quoting characters */ | 
					
						
							|  |  |  | 	  *r++ = CTLESC;			/* could be '\\'? */ | 
					
						
							|  |  |  | 	  *r++ = c; | 
					
						
							|  |  |  | 	  break; | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 	case '#':				/* comment char */ | 
					
						
							|  |  |  | 	  if (s == string) | 
					
						
							|  |  |  | 	    *r++ = '\\'; | 
					
						
							|  |  |  | 	  /* FALLTHROUGH */ | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 	  *r++ = c; | 
					
						
							|  |  |  | 	  break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *r = '\0'; | 
					
						
							|  |  |  |   return (result); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | #if defined (PROMPT_STRING_DECODE)
 | 
					
						
							|  |  |  | /* Quote characters that get special treatment when in double quotes in STRING
 | 
					
						
							|  |  |  |    using backslashes.  Return a new string. */ | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | sh_backslash_quote_for_double_quotes (string) | 
					
						
							|  |  |  |      char *string; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   unsigned char c; | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   char *result, *r, *s; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   result = (char *)xmalloc (2 * strlen (string) + 1); | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   for (r = result, s = string; s && (c = *s); s++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (sh_syntaxtab[c] & CBSDQUOTE) | 
					
						
							|  |  |  | 	*r++ = '\\'; | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |       /* I should probably add flags for these to sh_syntaxtab[] */ | 
					
						
							|  |  |  |       else if (c == CTLESC || c == CTLNUL) | 
					
						
							|  |  |  | 	*r++ = CTLESC;		/* could be '\\'? */ | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       *r++ = c; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *r = '\0'; | 
					
						
							|  |  |  |   return (result); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* PROMPT_STRING_DECODE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | int | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | sh_contains_shell_metas (string) | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |      char *string; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char *s; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (s = string; s && *s; s++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       switch (*s) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case ' ': case '\t': case '\n':		/* IFS white space */ | 
					
						
							|  |  |  | 	case '\'': case '"': case '\\':		/* quoting chars */ | 
					
						
							|  |  |  | 	case '|': case '&': case ';':		/* shell metacharacters */ | 
					
						
							|  |  |  | 	case '(': case ')': case '<': case '>': | 
					
						
							|  |  |  | 	case '!': case '{': case '}':		/* reserved words */ | 
					
						
							|  |  |  | 	case '*': case '[': case '?': case ']':	/* globbing chars */ | 
					
						
							|  |  |  | 	case '^': | 
					
						
							|  |  |  | 	case '$': case '`':			/* expansion chars */ | 
					
						
							|  |  |  | 	  return (1); | 
					
						
							|  |  |  | 	case '~':				/* tilde expansion */ | 
					
						
							|  |  |  | 	  if (s == string || s[-1] == '=' || s[-1] == ':') | 
					
						
							|  |  |  | 	    return (1); | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | 	  break; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 	case '#': | 
					
						
							|  |  |  | 	  if (s == string)			/* comment char */ | 
					
						
							|  |  |  | 	    return (1); | 
					
						
							|  |  |  | 	  /* FALLTHROUGH */ | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 	  break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (0); | 
					
						
							|  |  |  | } |