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.
This commit is contained in:
Jehan 2018-11-27 12:27:20 +01:00
parent 613bf7c5ab
commit 66ec467217
13 changed files with 119 additions and 0 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -1323,6 +1323,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);
@ -1389,6 +1395,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;
}

View File

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

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -1586,6 +1586,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)

View File

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

View File

@ -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);

View File

@ -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);