[gimp/gimp-2-10] plug-ins: make various usage of g_file_replace() safer.



commit ab851924dd116a7937c5e5e0c876fdfb58125af0
Author: Jehan <jehan girinstud io>
Date:   Tue Nov 27 12:27:20 2018 +0100

    plug-ins: make various usage of g_file_replace() safer.
    
    As I did on app/, finalizing an output stream also implicitly flushes
    and closes it. Hence if an export ended with an error, we'd end up with
    incomplete data file (possibly overwriting a previously exported image).
    Only 2 plug-ins I haven't fixed yet are file-tiff-io and file-gif-save.
    The later one don't even clean up its memory (which somehow is good here
    as at least the output stream is never finalized hence sane files are
    not overwritten in case of errors). As for the former (TIFF plug-in), it
    doesn't even seem to have any error control AFAICS, apart from printing
    error messages on standard error output.
    
    (cherry picked from commit 66ec467217572efb8549bdd6b02fa231861da4b6)

 plug-ins/common/file-cel.c        |  6 ++++++
 plug-ins/common/file-csource.c    |  6 ++++++
 plug-ins/common/file-gbr.c        | 18 ++++++++++++++++++
 plug-ins/common/file-gih.c        | 12 ++++++++++++
 plug-ins/common/file-header.c     |  6 ++++++
 plug-ins/common/file-heif.c       |  6 ++++++
 plug-ins/common/file-html-table.c |  6 ++++++
 plug-ins/common/file-pat.c        | 18 ++++++++++++++++++
 plug-ins/common/file-pix.c        | 11 +++++++++++
 plug-ins/common/file-pnm.c        |  9 +++++++++
 plug-ins/common/file-ps.c         |  6 ++++++
 plug-ins/common/file-xbm.c        |  6 ++++++
 plug-ins/common/file-xwd.c        |  9 +++++++++
 13 files changed, 119 insertions(+)
---
diff --git a/plug-ins/common/file-cel.c b/plug-ins/common/file-cel.c
index bac2cd3c51..95706c1933 100644
--- a/plug-ins/common/file-cel.c
+++ b/plug-ins/common/file-cel.c
@@ -753,6 +753,7 @@ save_image (GFile   *file,
   GOutputStream *output;
   GeglBuffer    *buffer;
   const Babl    *format;
+  GCancellable  *cancellable;
   gint           width;
   gint           height;
   guchar         header[32];    /* File header */
@@ -924,6 +925,11 @@ save_image (GFile   *file,
 
  fail:
 
+  cancellable = g_cancellable_new ();
+  g_cancellable_cancel (cancellable);
+  g_output_stream_close (output, cancellable, NULL);
+  g_object_unref (cancellable);
+
   g_free (buf);
   g_free (line);
   g_object_unref (buffer);
diff --git a/plug-ins/common/file-csource.c b/plug-ins/common/file-csource.c
index e4b9fed619..9258e875e5 100644
--- a/plug-ins/common/file-csource.c
+++ b/plug-ins/common/file-csource.c
@@ -455,6 +455,7 @@ save_image (GFile   *file,
 {
   GOutputStream *output;
   GeglBuffer    *buffer;
+  GCancellable  *cancellable;
   GimpImageType  drawable_type = gimp_drawable_type (drawable_ID);
   gchar         *s_uint_8, *s_uint, *s_char, *s_null;
   guint          c;
@@ -850,6 +851,11 @@ save_image (GFile   *file,
 
  fail:
 
+  cancellable = g_cancellable_new ();
+  g_cancellable_cancel (cancellable);
+  g_output_stream_close (output, cancellable, NULL);
+  g_object_unref (cancellable);
+
   g_object_unref (output);
   g_object_unref (buffer);
 
diff --git a/plug-ins/common/file-gbr.c b/plug-ins/common/file-gbr.c
index fe67b04559..1afc21cd1d 100644
--- a/plug-ins/common/file-gbr.c
+++ b/plug-ins/common/file-gbr.c
@@ -734,6 +734,12 @@ save_image (GFile   *file,
   if (! g_output_stream_write_all (output, &bh, sizeof (GimpBrushHeader),
                                    NULL, NULL, error))
     {
+      GCancellable *cancellable = g_cancellable_new ();
+
+      g_cancellable_cancel (cancellable);
+      g_output_stream_close (output, cancellable, NULL);
+      g_object_unref (cancellable);
+
       g_object_unref (output);
       return FALSE;
     }
@@ -743,6 +749,12 @@ save_image (GFile   *file,
                                    strlen (info.description) + 1,
                                    NULL, NULL, error))
     {
+      GCancellable *cancellable = g_cancellable_new ();
+
+      g_cancellable_cancel (cancellable);
+      g_output_stream_close (output, cancellable, NULL);
+      g_object_unref (cancellable);
+
       g_object_unref (output);
       return FALSE;
     }
@@ -783,6 +795,12 @@ save_image (GFile   *file,
       if (! g_output_stream_write_all (output, brush_buf, width * file_bpp,
                                        NULL, NULL, error))
         {
+          GCancellable *cancellable = g_cancellable_new ();
+
+          g_cancellable_cancel (cancellable);
+          g_output_stream_close (output, cancellable, NULL);
+          g_object_unref (cancellable);
+
           g_free (brush_buf);
           g_object_unref (output);
           return FALSE;
diff --git a/plug-ins/common/file-gih.c b/plug-ins/common/file-gih.c
index ab30f74426..a8f4698e96 100644
--- a/plug-ins/common/file-gih.c
+++ b/plug-ins/common/file-gih.c
@@ -1330,6 +1330,12 @@ gih_save_image (GFile    *file,
   if (! g_output_stream_write_all (output, header, strlen (header),
                                    NULL, NULL, error))
     {
+      GCancellable *cancellable = g_cancellable_new ();
+
+      g_cancellable_cancel (cancellable);
+      g_output_stream_close (output, cancellable, NULL);
+      g_object_unref (cancellable);
+
       g_free (parstring);
       g_free (header);
       g_object_unref (output);
@@ -1396,6 +1402,12 @@ gih_save_image (GFile    *file,
                                                         thisw, thish),
                                         name, error))
                 {
+                  GCancellable *cancellable = g_cancellable_new ();
+
+                  g_cancellable_cancel (cancellable);
+                  g_output_stream_close (output, cancellable, NULL);
+                  g_object_unref (cancellable);
+
                   g_object_unref (output);
                   return FALSE;
                 }
diff --git a/plug-ins/common/file-header.c b/plug-ins/common/file-header.c
index dfaa9bd2e0..6b2b4640f5 100644
--- a/plug-ins/common/file-header.c
+++ b/plug-ins/common/file-header.c
@@ -185,6 +185,7 @@ save_image (GFile   *file,
   guchar        *d         = NULL;
   guchar        *data      = NULL;
   guchar        *cmap;
+  GCancellable  *cancellable;
   gint           colors;
   gint           width;
   gint           height;
@@ -408,9 +409,14 @@ save_image (GFile   *file,
 
  fail:
 
+  cancellable = g_cancellable_new ();
+  g_cancellable_cancel (cancellable);
+  g_output_stream_close (output, cancellable, NULL);
+
   g_free (data);
   g_object_unref (output);
   g_object_unref (buffer);
+  g_object_unref (cancellable);
 
   return FALSE;
 }
diff --git a/plug-ins/common/file-heif.c b/plug-ins/common/file-heif.c
index 8f9bae49af..5cb0a49f84 100644
--- a/plug-ins/common/file-heif.c
+++ b/plug-ins/common/file-heif.c
@@ -708,6 +708,12 @@ save_image (GFile             *file,
 
   if (err.code != 0)
     {
+      GCancellable *cancellable = g_cancellable_new ();
+
+      g_cancellable_cancel (cancellable);
+      g_output_stream_close (output, cancellable, NULL);
+      g_object_unref (cancellable);
+
       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                    _("Writing HEIF image failed: %s"),
                    err.message);
diff --git a/plug-ins/common/file-html-table.c b/plug-ins/common/file-html-table.c
index 5deaf434d8..c4c03dffcd 100644
--- a/plug-ins/common/file-html-table.c
+++ b/plug-ins/common/file-html-table.c
@@ -221,6 +221,7 @@ save_image (GFile       *file,
 {
   const Babl    *format = babl_format ("R'G'B'A u8");
   GeglSampler   *sampler;
+  GCancellable  *cancellable;
   GOutputStream *output;
   gint           row, col;
   gint           cols, rows;
@@ -438,6 +439,11 @@ save_image (GFile       *file,
 
  fail:
 
+  cancellable = g_cancellable_new ();
+  g_cancellable_cancel (cancellable);
+  g_output_stream_close (output, cancellable, NULL);
+  g_object_unref (cancellable);
+
   g_object_unref (output);
   g_object_unref (sampler);
   g_free (width);
diff --git a/plug-ins/common/file-pat.c b/plug-ins/common/file-pat.c
index 0142cf2484..c78afd03b0 100644
--- a/plug-ins/common/file-pat.c
+++ b/plug-ins/common/file-pat.c
@@ -573,6 +573,12 @@ save_image (GFile   *file,
   if (! g_output_stream_write_all (output, &ph, sizeof (GimpPatternHeader),
                                    NULL, NULL, error))
     {
+      GCancellable *cancellable = g_cancellable_new ();
+
+      g_cancellable_cancel (cancellable);
+      g_output_stream_close (output, cancellable, NULL);
+      g_object_unref (cancellable);
+
       g_object_unref (output);
       return FALSE;
     }
@@ -581,6 +587,12 @@ save_image (GFile   *file,
                                    description, strlen (description) + 1,
                                    NULL, NULL, error))
     {
+      GCancellable *cancellable = g_cancellable_new ();
+
+      g_cancellable_cancel (cancellable);
+      g_output_stream_close (output, cancellable, NULL);
+      g_object_unref (cancellable);
+
       g_object_unref (output);
       return FALSE;
     }
@@ -599,6 +611,12 @@ save_image (GFile   *file,
       if (! g_output_stream_write_all (output, buf, line_size,
                                        NULL, NULL, error))
         {
+          GCancellable *cancellable = g_cancellable_new ();
+
+          g_cancellable_cancel (cancellable);
+          g_output_stream_close (output, cancellable, NULL);
+          g_object_unref (cancellable);
+
           g_object_unref (buffer);
           g_object_unref (output);
           return FALSE;
diff --git a/plug-ins/common/file-pix.c b/plug-ins/common/file-pix.c
index ee518ee6a6..751a5a73be 100644
--- a/plug-ins/common/file-pix.c
+++ b/plug-ins/common/file-pix.c
@@ -527,6 +527,7 @@ save_image (GFile   *file,
   GOutputStream *output;
   GeglBuffer    *buffer;
   const Babl    *format;
+  GCancellable  *cancellable;
   gint           width;
   gint           height;
   gint           depth, i, j, row, tile_height, rectHeight;
@@ -567,6 +568,11 @@ save_image (GFile   *file,
       ! put_short (output, 0,      error) ||
       ! put_short (output, 0,      error))
     {
+      cancellable = g_cancellable_new ();
+      g_cancellable_cancel (cancellable);
+      g_output_stream_close (output, cancellable, NULL);
+      g_object_unref (cancellable);
+
       g_object_unref (output);
       g_object_unref (buffer);
       return FALSE;
@@ -717,6 +723,11 @@ save_image (GFile   *file,
 
  fail:
 
+  cancellable = g_cancellable_new ();
+  g_cancellable_cancel (cancellable);
+  g_output_stream_close (output, cancellable, NULL);
+  g_object_unref (cancellable);
+
   g_free (src_base);
   g_object_unref (output);
   g_object_unref (buffer);
diff --git a/plug-ins/common/file-pnm.c b/plug-ins/common/file-pnm.c
index 77f205a4ee..2885bfddc2 100644
--- a/plug-ins/common/file-pnm.c
+++ b/plug-ins/common/file-pnm.c
@@ -1585,6 +1585,15 @@ save_image (GFile     *file,
   status = TRUE;
 
  out:
+  if (! status)
+    {
+      GCancellable  *cancellable = g_cancellable_new ();
+
+      g_cancellable_cancel (cancellable);
+      g_output_stream_close (output, cancellable, NULL);
+      g_object_unref (cancellable);
+    }
+
   if (comment)
     g_free (comment);
   if (buffer)
diff --git a/plug-ins/common/file-ps.c b/plug-ins/common/file-ps.c
index 769dd8f4fb..cf5cbb6fc8 100644
--- a/plug-ins/common/file-ps.c
+++ b/plug-ins/common/file-ps.c
@@ -1207,6 +1207,7 @@ save_image (GFile   *file,
             GError **error)
 {
   GOutputStream *output;
+  GCancellable  *cancellable;
   GimpImageType  drawable_type;
 
   drawable_type = gimp_drawable_type (drawable_ID);
@@ -1289,7 +1290,12 @@ save_image (GFile   *file,
 
  fail:
 
+  cancellable = g_cancellable_new ();
+  g_cancellable_cancel (cancellable);
+  g_output_stream_close (output, cancellable, NULL);
+
   g_object_unref (output);
+  g_object_unref (cancellable);
 
   return FALSE;
 }
diff --git a/plug-ins/common/file-xbm.c b/plug-ins/common/file-xbm.c
index 97b87b657b..9a5749777c 100644
--- a/plug-ins/common/file-xbm.c
+++ b/plug-ins/common/file-xbm.c
@@ -979,6 +979,7 @@ save_image (GFile        *file,
 {
   GOutputStream *output;
   GeglBuffer    *buffer;
+  GCancellable  *cancellable;
   gint           width, height, colors, dark;
   gint           intbits, lineints, need_comma, nints, rowoffset, tileheight;
   gint           c, i, j, k, thisbit;
@@ -1221,6 +1222,11 @@ save_image (GFile        *file,
 
  fail:
 
+  cancellable = g_cancellable_new ();
+  g_cancellable_cancel (cancellable);
+  g_output_stream_close (output, cancellable, NULL);
+  g_object_unref (cancellable);
+
   g_free (data);
   g_object_unref (buffer);
   g_object_unref (output);
diff --git a/plug-ins/common/file-xwd.c b/plug-ins/common/file-xwd.c
index 6e0f8cdfa9..20943c94f3 100644
--- a/plug-ins/common/file-xwd.c
+++ b/plug-ins/common/file-xwd.c
@@ -687,6 +687,15 @@ save_image (GFile   *file,
                       gimp_file_get_utf8_name (file));
       success = FALSE;
     }
+  else if (! success)
+    {
+      GCancellable  *cancellable;
+
+      cancellable = g_cancellable_new ();
+      g_cancellable_cancel (cancellable);
+      g_output_stream_close (output, cancellable, NULL);
+      g_object_unref (cancellable);
+    }
 
   g_object_unref (output);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]