Security bugfixes (CAN-2004-1184, CAN-2004-1185, CAN-2004-1186)
and some additional non-security bugfixes.

Index: compat/regex.c
--- compat/regex.c.orig	1998-10-20 15:39:02 +0200
+++ compat/regex.c	2005-02-05 09:50:45 +0100
@@ -2400,11 +2400,13 @@
             case ')':
               if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
 
-              if (COMPILE_STACK_EMPTY)
-                if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+              if (COMPILE_STACK_EMPTY) {
+                if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) {
                   goto normal_backslash;
-                else
+		} else {
                   FREE_STACK_RETURN (REG_ERPAREN);
+		}  
+	      }	
 
             handle_close:
               if (fixup_alt_jump)
@@ -2420,11 +2422,13 @@
                 }
 
               /* See similar code for backslashed left paren above.  */
-              if (COMPILE_STACK_EMPTY)
-                if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+              if (COMPILE_STACK_EMPTY) {
+                if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) {
                   goto normal_char;
-                else
+		} else {
                   FREE_STACK_RETURN (REG_ERPAREN);
+		}
+	      }	
 
               /* Since we just checked for an empty stack above, this
                  ``can't happen''.  */
Index: docs/Makefile.in
--- docs/Makefile.in.orig	2002-01-24 08:39:44 +0100
+++ docs/Makefile.in	2005-02-05 09:50:45 +0100
@@ -284,7 +284,7 @@
 	  enscript.fns enscript.ky enscript.kys enscript.ps \
 	  enscript.log enscript.pg enscript.toc enscript.tp \
 	  enscript.tps enscript.vr enscript.vrs enscript.op enscript.tr \
-	  enscript.cv enscript.cn
+	  enscript.cv enscript.cn enscript.1 states.1
 
 clean-aminfo:
 
Index: docs/enscript.man
--- docs/enscript.man.orig	2000-11-30 07:55:31 +0100
+++ docs/enscript.man	2005-02-05 09:50:45 +0100
@@ -118,7 +118,7 @@
 The header string \f2header\f1 can contain the same formatting escapes
 which can be specified for the \f3%Format\f1 directives in the user
 defined fancy headers.  For example, the following option prints the
-file name, current data and page numbers:
+file name, current date and page numbers:
 
 \f3enscript \-\-header='$n %W Page $% of $=' *.c\f1
 
Index: lib/enscript-color.hdr
--- lib/enscript-color.hdr.orig	1998-12-29 09:40:47 +0100
+++ lib/enscript-color.hdr	2005-02-05 09:50:45 +0100
@@ -27,8 +27,8 @@
 
 % -- code follows this line --
 %%DocumentNeededResources: font Times-Bold Times-Roman
-%Format: moddatestr	$W
-%Format: modtimestr	$C
+%Format: moddatestr	$D{%x}
+%Format: modtimestr	$D{%X}
 %Format: pagenumstr	$%
 %Format: pagecountstr	/$=
 
Index: lib/enscript.hdr
--- lib/enscript.hdr.orig	1997-03-03 09:20:34 +0100
+++ lib/enscript.hdr	2005-02-05 09:50:45 +0100
@@ -25,8 +25,8 @@
 
 % -- code follows this line --
 %%DocumentNeededResources: font Times-Bold Times-Roman
-%Format: moddatestr	$W
-%Format: modtimestr	$C
+%Format: moddatestr	$D{%x}
+%Format: modtimestr	$D{%X}
 %Format: pagenumstr	$%
 
 % Fonts.
Index: src/gsint.h
--- src/gsint.h.orig	2000-07-11 17:28:06 +0200
+++ src/gsint.h	2005-02-05 09:50:45 +0100
@@ -701,4 +701,9 @@
  */
 void printer_close ___P ((void *context));
 
+/*
+ * Escape filenames for shell usage
+ */
+char *shell_escape ___P ((const char *fn));
+
 #endif /* not GSINT_H */
Index: src/main.c
--- src/main.c.orig	2002-01-24 08:35:45 +0100
+++ src/main.c	2005-02-05 09:50:45 +0100
@@ -973,6 +973,8 @@
    */
 #if HAVE_LC_MESSAGES
   setlocale (LC_MESSAGES, "");
+  setlocale (LC_CTYPE, "");
+  setlocale (LC_TIME, "");
 #endif
 #endif
 #if ENABLE_NLS
@@ -1546,9 +1548,13 @@
       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");
@@ -1565,8 +1571,14 @@
       /* 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. */
@@ -1627,7 +1639,7 @@
 				 buffer_ptr (opts), buffer_len (opts));
 	    }
 
-	  buffer_append (&buffer, " \"%s\"");
+	  buffer_append (&buffer, " \'%s\'");
 
 	  input_filter = buffer_copy (&buffer);
 	  input_filter_stdin = "-";
Index: src/mkafmmap.c
--- src/mkafmmap.c.orig	1997-07-03 13:14:59 +0200
+++ src/mkafmmap.c	2005-02-05 09:50:45 +0100
@@ -126,6 +126,7 @@
 #if HAVE_SETLOCALE
 #if HAVE_LC_MESSAGES
   setlocale (LC_MESSAGES, "");
+  setlocale (LC_CTYPE, "");
 #endif
 #endif
 #if ENABLE_NLS
Index: src/psgen.c
--- src/psgen.c.orig	2002-01-24 08:38:58 +0100
+++ src/psgen.c	2005-02-05 09:50:45 +0100
@@ -2034,8 +2034,9 @@
   else
     {
       ftail++;
-      strncpy (buf, fname, ftail - fname);
-      buf[ftail - fname] = '\0';
+      i = ftail - fname >= sizeof (buf)-1 ? sizeof (buf)-1 : ftail - fname;
+      strncpy (buf, fname, i);
+      buf[i] = '\0';
     }
 
   if (nup > 1)
@@ -2385,9 +2386,10 @@
   MESSAGE (2, (stderr, "^@epsf=\"%s\"\n", token->u.epsf.filename));
 
   i = strlen (token->u.epsf.filename);
+  /*
   if (i > 0 && token->u.epsf.filename[i - 1] == '|')
     {
-      /* Read EPS data from pipe. */
+      / * Read EPS data from pipe. * /
       token->u.epsf.pipe = 1;
       token->u.epsf.filename[i - 1] = '\0';
       token->u.epsf.fp = popen (token->u.epsf.filename, "r");
@@ -2400,6 +2402,7 @@
 	}
     }
   else
+  */
     {
       char *filename;
 
@@ -2581,7 +2584,7 @@
 read_float (InputStream *is, int units, int horizontal)
 {
   char buf[256];
-  int i, ch;
+  int i, ch = 0;
   double val;
 
   for (i = 0; (i < sizeof (buf) - 1
Index: src/util.c
--- src/util.c.orig	1999-09-17 17:26:51 +0200
+++ src/util.c	2005-02-05 09:59:00 +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);
-		  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;
@@ -1991,12 +1998,13 @@
   if (is->bufpos >= is->data_in_buf)
     {
       /* At the EOF? */
-      if (is->nreads > 0 && is->data_in_buf < sizeof (is->buf))
+      if (is->nreads > 0 && is->data_in_buf < sizeof (is->buf)-1)
 	/* Yes. */
 	return EOF;
 
       /* Read more data. */
-      is->data_in_buf = fread (is->buf, 1, sizeof (is->buf), is->fp);
+      memset (is->buf, 0, sizeof (is->buf));
+      is->data_in_buf = fread (is->buf, 1, sizeof (is->buf)-1, is->fp);
       is->bufpos = 0;
       is->nreads++;
 
@@ -2116,3 +2124,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;
+}
Index: states/main.c
--- states/main.c.orig	2000-11-30 07:40:17 +0100
+++ states/main.c	2005-02-05 09:50:45 +0100
@@ -202,6 +202,7 @@
 #if HAVE_SETLOCALE
 #if HAVE_LC_MESSAGES
   setlocale (LC_MESSAGES, "");
+  setlocale (LC_CTYPE, "");
 #endif
 #endif
 #if ENABLE_NLS
Index: states/over.in
--- states/over.in.orig	1997-03-19 11:24:49 +0100
+++ states/over.in	2005-02-05 09:50:45 +0100
@@ -2,4 +2,4 @@
 
 librarydir=@LIBRARYDIR@
 
-enscript -E -p- --quiet --language=overstrike $* 2>&1 | less
+enscript -E -p- --quiet --language=overstrike "$@" 2>&1 | sensible-pager
Index: afm/Makefile.in
--- afm/Makefile.in.orig	2002-01-24 08:39:24 +0100
+++ afm/Makefile.in	2005-02-05 10:04:31 +0100
@@ -227,10 +227,10 @@
 
 
 install-data-local:
-	$(top_srcdir)/mkinstalldirs $(datadir)/enscript
-	$(top_srcdir)/mkinstalldirs $(datadir)/enscript/afm
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir)/enscript
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir)/enscript/afm
 	for f in $(EXTRA_DIST); do \
-	  $(INSTALL_DATA) $(srcdir)/$$f $(datadir)/enscript/afm/$$f; \
+	  $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(datadir)/enscript/afm/$$f; \
 	done
 
 uninstall-local:
Index: lib/Makefile.in
--- lib/Makefile.in.orig	2002-01-24 08:39:27 +0100
+++ lib/Makefile.in	2005-02-05 10:07:31 +0100
@@ -254,15 +254,15 @@
 all-local: enscript.cfg
 
 install-data-local: enscript.cfg
-	$(top_srcdir)/mkinstalldirs $(sysconfdir)
-	if test -r $(sysconfdir)/enscript.cfg; then \
-	  cp $(sysconfdir)/enscript.cfg $(sysconfdir)/enscript.cfg.old; \
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(sysconfdir)
+	if test -r $(DESTDIR)$(sysconfdir)/enscript.cfg; then \
+	  cp $(DESTDIR)$(sysconfdir)/enscript.cfg $(DESTDIR)$(sysconfdir)/enscript.cfg.old; \
 	else :; \
 	fi
-	$(INSTALL_DATA) enscript.cfg $(sysconfdir)/enscript.cfg
+	$(INSTALL_DATA) enscript.cfg $(DESTDIR)$(sysconfdir)/enscript.cfg
 
 uninstall-local:
-	rm -f $(sysconfdir)/enscript.cfg
+	rm -f $(DESTDIR)$(sysconfdir)/enscript.cfg
 
 enscript.cfg: $(srcdir)/enscript.cfg.in Makefile
 	sed 's%@DATADIR@%$(datadir)%g; s%@media@%@MEDIA@%g; s%@BINDIR@%$(bindir)%g; s%@spooler@%@SPOOLER@%g; s%@pslevel@%@PSLEVEL@%g; s%@queueparam@%@QUEUEPARAM@%g' \
Index: states/hl/Makefile.in
--- states/hl/Makefile.in.orig	2002-01-24 08:39:40 +0100
+++ states/hl/Makefile.in	2005-02-05 14:17:13 +0100
@@ -234,14 +234,14 @@
 
 
 install-data-local:
-	$(top_srcdir)/mkinstalldirs $(datadir)/enscript
-	$(top_srcdir)/mkinstalldirs $(datadir)/enscript/hl
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir)/enscript
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir)/enscript/hl
 	for f in $(states); do \
-	  $(INSTALL_DATA) $(srcdir)/$$f $(datadir)/enscript/hl/$$f; \
+	  $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(datadir)/enscript/hl/$$f; \
 	done
 
 uninstall-local:
-	rm -rf $(datadir)/enscript/hl
+	rm -rf $(DESTDIR)$(datadir)/enscript/hl
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
