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;
       +}