$NetBSD: patch-ad,v 1.1 2005/03/17 12:24:13 salo Exp $ --- src/util.c.orig 1999-09-17 17:26:51.000000000 +0200 +++ src/util.c 2005-03-17 11:58:59.000000000 +0100 @@ -1239,6 +1239,8 @@ /* Create result. */ cp = xmalloc (len + 1); + if (cp == NULL) + return NULL; for (i = 0, j = 0; string[i]; i++) switch (string[i]) { @@ -1879,6 +1881,7 @@ char *cmd = NULL; int cmdlen; int i, pos; + char *cp; is->is_pipe = 1; @@ -1902,12 +1905,16 @@ { case 's': /* Expand cmd-buffer. */ - cmdlen += strlen (fname); + if ((cp = shell_escape (fname)) != NULL) + { + cmdlen += strlen (cp); cmd = xrealloc (cmd, cmdlen); /* Paste filename. */ - strcpy (cmd + pos, fname); - pos += strlen (fname); + strcpy (cmd + pos, cp); + pos += strlen (cp); + free (cp); + } i++; break; @@ -2116,3 +2123,36 @@ { return buffer->len; } + +/* + * Escapes the name of a file so that the shell groks it in 'single' + * quotation marks. The resulting pointer has to be free()ed when not + * longer used. +*/ +char * +shell_escape(const char *fn) +{ + size_t len = 0; + const char *inp; + char *retval, *outp; + + for(inp = fn; *inp; ++inp) + switch(*inp) + { + case '\'': len += 4; break; + default: len += 1; break; + } + + outp = retval = malloc(len + 1); + if(!outp) + return NULL; /* perhaps one should do better error handling here */ + for(inp = fn; *inp; ++inp) + switch(*inp) + { + case '\'': *outp++ = '\''; *outp++ = '\\'; *outp++ = '\'', *outp++ = '\''; break; + default: *outp++ = *inp; break; + } + *outp = 0; + + return retval; +}