* ascii.c (struct ascii_driver_ext): New member reported_error.
authorBen Pfaff <blp@gnu.org>
Fri, 21 Sep 2007 14:12:57 +0000 (14:12 +0000)
committerBen Pfaff <blp@gnu.org>
Fri, 21 Sep 2007 14:12:57 +0000 (14:12 +0000)
(ascii_open_driver): Initialize reported_error.
(ascii_open_page): Initialize the rest of the ascii driver data
even if we fail to open the output file.  Fixes bug #21117.

* chart.c (chart_create): Initialize lp member.  Fixes crash if
chart initialization fails.

* html.c (html_open_driver): Don't free chart_file_name in error
case, since html_close_driver will do that.  Fixes crash if file
open fails.

* postscript.c (ps_close_driver): Don't try to write to file if
it's null.  Fixes crash if file open fails.

src/output/ascii.c
src/output/chart.c
src/output/html.c
src/output/postscript.c

index 2ac0401d5504f84ea5bb085496a4801f7df92837..bdb02dbf3c8443a4c86eff9ca13ec2d50b837ff0 100644 (file)
@@ -120,6 +120,7 @@ struct ascii_driver_ext
     /* Internal state. */
     char *file_name;            /* Output file name. */
     FILE *file;                 /* Output file. */
+    bool reported_error;        /* Reported file open error? */
     int page_number;           /* Current page number. */
     struct line *lines;         /* Page content. */
     int line_cap;               /* Number of lines allocated. */
@@ -161,6 +162,7 @@ ascii_open_driver (struct outp_driver *this, struct substring options)
   x->init = NULL;
   x->file_name = pool_strdup (x->pool, "pspp.list");
   x->file = NULL;
+  x->reported_error = false;
   x->page_number = 0;
   x->lines = NULL;
   x->line_cap = 0;
@@ -449,16 +451,25 @@ ascii_open_page (struct outp_driver *this)
   if (x->file == NULL)
     {
       x->file = fn_open (x->file_name, x->append ? "a" : "w");
-      if (x->file == NULL)
+      if (x->file != NULL)
         {
-          error (0, errno, _("ascii: opening output file \"%s\""),
-                 x->file_name);
-          return;
+          pool_attach_file (x->pool, x->file);
+          if (x->init != NULL)
+            fputs (x->init, x->file);
+        }
+      else
+        {
+          /* Report the error to the user and complete
+             initialization.  If we do not finish initialization,
+             then calls to other driver functions will segfault
+             later.  It would be better to simply drop the driver
+             entirely, but we do not have a convenient mechanism
+             for this (yet). */
+          if (!x->reported_error)
+            error (0, errno, _("ascii: opening output file \"%s\""),
+                   x->file_name);
+          x->reported_error = true;
         }
-      pool_attach_file (x->pool, x->file);
-
-      if (x->init != NULL)
-        fputs (x->init, x->file);
     }
 
   x->page_number++;
index 9ae12f9c3105c600cea0a2bed692a8dea824908c..489ef189f6d3817c047147ef8bcd206ec31cc56c 100644 (file)
@@ -52,6 +52,7 @@ chart_create(void)
     return NULL;
 
   chart = xmalloc (sizeof *chart);
+  chart->lp = NULL;
   d->class->initialise_chart(d, chart);
   if (!chart->lp)
     {
index 90c2ce1915b48a90bcbc1fdad325c2552d09ab0f..17be1751c1b1cf2fc71bcd58788163a2201c8e1d 100644 (file)
@@ -91,7 +91,6 @@ html_open_driver (struct outp_driver *this, struct substring options)
   return true;
 
  error:
-  free (x->chart_file_name);
   this->class->close_driver (this);
   return false;
 }
index c90cdedd8c95df472d4a483020e36a20dc3a0a45..27d0404f8166fb8996677882a9743e6b7e0d86de 100644 (file)
@@ -230,18 +230,23 @@ static bool
 ps_close_driver (struct outp_driver *this)
 {
   struct ps_driver_ext *x = this->ext;
-  bool ok;
+  bool ok = true;
   size_t i;
 
-  fprintf (x->file,
-          "%%%%Trailer\n"
-           "%%%%Pages: %d\n"
-           "%%%%EOF\n",
-           x->page_number);
-
-  ok = fn_close (x->file_name, x->file) == 0;
-  if (!ok)
-    error (0, errno, _("closing PostScript output file \"%s\""), x->file_name);
+  if (x->file != NULL)
+    {
+      fprintf (x->file,
+               "%%%%Trailer\n"
+               "%%%%Pages: %d\n"
+               "%%%%EOF\n",
+               x->page_number);
+
+      ok = fn_close (x->file_name, x->file) == 0;
+      if (!ok)
+        error (0, errno, _("closing PostScript output file \"%s\""),
+               x->file_name);
+    }
+
   free (x->file_name);
   for (i = 0; i < OUTP_FONT_CNT; i++)
     free_font (x->fonts[i]);