Apply patch from Debian Security Team for CAN-2004-1184. - enscript - GNU Enscript
(HTM) git clone git://thinkerwim.org/enscript.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 9510e4315705329e51b27fa2f3f688989b9fb37f
(DIR) parent 0acc7b63a1be9f5d02f1a21d6df52cb5a9ce7e58
(HTM) Author: Tim Retout <diocles@gnu.org>
Date: Sun, 27 Dec 2009 14:50:37 +0000
Apply patch from Debian Security Team for CAN-2004-1184.
Diffstat:
M src/ChangeLog | 14 ++++++++++++++
M src/gsint.h | 5 +++++
M src/main.c | 22 ++++++++++++++++------
M src/util.c | 50 ++++++++++++++++++++++++++++----
4 files changed, 80 insertions(+), 11 deletions(-)
---
(DIR) diff --git a/src/ChangeLog b/src/ChangeLog
@@ -1,3 +1,17 @@
+2009-12-27 Tim Retout <diocles@gnu.org>
+
+ Apply patch from Debian Security Team for CAN-2004-1184.
+
+ * gsint.h: Add shell_escape prototype.
+ * util.c (shell_escape): New function to escape filenames for
+ shell usage.
+ * util.c (is_open): Use shell_escape to expand command buffer.
+
+ * main.c (main): Use single quotes when building command string,
+ and use shell_escape to quote contents.
+
+ * util.c (escape_string): Check return code of xmalloc.
+
2009-03-28 Tim Retout <diocles@gnu.org>
* psgen.c (recognize_eps_file): Remove ability to read EPS data
(DIR) diff --git a/src/gsint.h b/src/gsint.h
@@ -699,4 +699,9 @@ FILE *printer_open ___P ((char *cmd, char *options, char *queue_param,
*/
void printer_close ___P ((void *context));
+/*
+ * Escape filenames for shell usage
+ */
+char *shell_escape ___P ((const char *fn));
+
#endif /* not GSINT_H */
(DIR) diff --git a/src/main.c b/src/main.c
@@ -1544,9 +1544,13 @@ name width\theight\tllx\tlly\turx\tury\n\
buffer_append (&cmd, intbuf);
buffer_append (&cmd, " ");
- buffer_append (&cmd, "-Ddocument_title=\"");
- buffer_append (&cmd, title);
- buffer_append (&cmd, "\" ");
+ buffer_append (&cmd, "-Ddocument_title=\'");
+ if ((cp = shell_escape (title)) != NULL)
+ {
+ buffer_append (&cmd, cp);
+ free (cp);
+ }
+ buffer_append (&cmd, "\' ");
buffer_append (&cmd, "-Dtoc=");
buffer_append (&cmd, toc ? "1" : "0");
@@ -1563,8 +1567,14 @@ name width\theight\tllx\tlly\turx\tury\n\
/* Append input files. */
for (i = optind; i < argc; i++)
{
- buffer_append (&cmd, " ");
- buffer_append (&cmd, argv[i]);
+ char *cp;
+ if ((cp = shell_escape (argv[i])) != NULL)
+ {
+ buffer_append (&cmd, " \'");
+ buffer_append (&cmd, cp);
+ buffer_append (&cmd, "\'");
+ free (cp);
+ }
}
/* And do the job. */
@@ -1625,7 +1635,7 @@ name width\theight\tllx\tlly\turx\tury\n\
buffer_ptr (opts), buffer_len (opts));
}
- buffer_append (&buffer, " \"%s\"");
+ buffer_append (&buffer, " \'%s\'");
input_filter = buffer_copy (&buffer);
input_filter_stdin = "-";
(DIR) diff --git a/src/util.c b/src/util.c
@@ -1237,6 +1237,8 @@ escape_string (char *string)
/* Create result. */
cp = xmalloc (len + 1);
+ if (cp == NULL)
+ return NULL;
for (i = 0, j = 0; string[i]; i++)
switch (string[i])
{
@@ -1877,6 +1879,7 @@ is_open (InputStream *is, FILE *fp, char *fname, char *input_filter)
char *cmd = NULL;
int cmdlen;
int i, pos;
+ char *cp;
is->is_pipe = 1;
@@ -1900,12 +1903,16 @@ is_open (InputStream *is, FILE *fp, char *fname, char *input_filter)
{
case 's':
/* Expand cmd-buffer. */
- cmdlen += strlen (fname);
- cmd = xrealloc (cmd, cmdlen);
+ if ((cp = shell_escape (fname)) != NULL)
+ {
+ cmdlen += strlen (cp);
+ cmd = xrealloc (cmd, cmdlen);
- /* Paste filename. */
- strcpy (cmd + pos, fname);
- pos += strlen (fname);
+ /* Paste filename. */
+ strcpy (cmd + pos, cp);
+ pos += strlen (cp);
+ free (cp);
+ }
i++;
break;
@@ -2114,3 +2121,36 @@ buffer_len (Buffer *buffer)
{
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;
+}