mirror of https://github.com/GNOME/gimp.git
app, libgimpconfig: make various usage of g_file_replace() safer.
When an error occurs, we want to prevent overwriting any previous version of the file by incomplete contents. So run g_output_stream_close() with a cancelled GCancellable to do so. See also discussion in #2565.
This commit is contained in:
parent
076b53511a
commit
613bf7c5ab
|
@ -288,17 +288,25 @@ gimp_internal_data_save_data_file (Gimp *gimp,
|
|||
success = FALSE;
|
||||
}
|
||||
}
|
||||
else if (error && *error)
|
||||
{
|
||||
g_prefix_error (error,
|
||||
_("Error saving '%s': "),
|
||||
gimp_file_get_utf8_name (file));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_WRITE,
|
||||
_("Error saving '%s'"),
|
||||
gimp_file_get_utf8_name (file));
|
||||
GCancellable *cancellable = g_cancellable_new ();
|
||||
|
||||
g_cancellable_cancel (cancellable);
|
||||
if (error && *error)
|
||||
{
|
||||
g_prefix_error (error,
|
||||
_("Error saving '%s': "),
|
||||
gimp_file_get_utf8_name (file));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_WRITE,
|
||||
_("Error saving '%s'"),
|
||||
gimp_file_get_utf8_name (file));
|
||||
}
|
||||
g_output_stream_close (output, cancellable, NULL);
|
||||
g_object_unref (cancellable);
|
||||
}
|
||||
|
||||
g_object_unref (output);
|
||||
|
|
|
@ -138,12 +138,24 @@ gimp_tags_user_install (void)
|
|||
else if (! g_output_stream_write_all (output,
|
||||
tags_installer.buf->str,
|
||||
tags_installer.buf->len,
|
||||
NULL, NULL, &error) ||
|
||||
! g_output_stream_close (output, NULL, &error))
|
||||
NULL, NULL, &error))
|
||||
{
|
||||
GCancellable *cancellable = g_cancellable_new ();
|
||||
|
||||
g_printerr (_("Error writing '%s': %s"),
|
||||
gimp_file_get_utf8_name (file), error->message);
|
||||
result = FALSE;
|
||||
|
||||
/* Cancel the overwrite initiated by g_file_replace(). */
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_output_stream_close (output, cancellable, NULL);
|
||||
g_object_unref (cancellable);
|
||||
}
|
||||
else if (! g_output_stream_close (output, NULL, &error))
|
||||
{
|
||||
g_printerr (_("Error closing '%s': %s"),
|
||||
gimp_file_get_utf8_name (file), error->message);
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
if (output)
|
||||
|
|
|
@ -592,17 +592,25 @@ gimp_data_save (GimpData *data,
|
|||
success = FALSE;
|
||||
}
|
||||
}
|
||||
else if (error && *error)
|
||||
{
|
||||
g_prefix_error (error,
|
||||
_("Error saving '%s': "),
|
||||
gimp_file_get_utf8_name (private->file));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_WRITE,
|
||||
_("Error saving '%s'"),
|
||||
gimp_file_get_utf8_name (private->file));
|
||||
GCancellable *cancellable = g_cancellable_new ();
|
||||
|
||||
g_cancellable_cancel (cancellable);
|
||||
if (error && *error)
|
||||
{
|
||||
g_prefix_error (error,
|
||||
_("Error saving '%s': "),
|
||||
gimp_file_get_utf8_name (private->file));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_WRITE,
|
||||
_("Error saving '%s'"),
|
||||
gimp_file_get_utf8_name (private->file));
|
||||
}
|
||||
g_output_stream_close (output, cancellable, NULL);
|
||||
g_object_unref (cancellable);
|
||||
}
|
||||
|
||||
g_object_unref (output);
|
||||
|
|
|
@ -207,13 +207,21 @@ gimp_gradient_save_pov (GimpGradient *gradient,
|
|||
if (! g_output_stream_write_all (output, string->str, string->len,
|
||||
NULL, NULL, &my_error))
|
||||
{
|
||||
GCancellable *cancellable = g_cancellable_new ();
|
||||
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_WRITE,
|
||||
_("Writing POV file '%s' failed: %s"),
|
||||
gimp_file_get_utf8_name (file),
|
||||
my_error->message);
|
||||
g_clear_error (&my_error);
|
||||
g_string_free (string, TRUE);
|
||||
|
||||
/* Cancel the overwrite initiated by g_file_replace(). */
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_output_stream_close (output, cancellable, NULL);
|
||||
g_object_unref (cancellable);
|
||||
g_object_unref (output);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -430,11 +430,22 @@ gimp_tag_cache_save (GimpTagCache *cache)
|
|||
g_printerr ("%s\n", error->message);
|
||||
}
|
||||
else if (! g_output_stream_write_all (output, buf->str, buf->len,
|
||||
NULL, NULL, &error) ||
|
||||
! g_output_stream_close (output, NULL, &error))
|
||||
NULL, NULL, &error))
|
||||
{
|
||||
GCancellable *cancellable = g_cancellable_new ();
|
||||
|
||||
g_printerr (_("Error writing '%s': %s\n"),
|
||||
gimp_file_get_utf8_name (file), error->message);
|
||||
|
||||
/* Cancel the overwrite initiated by g_file_replace(). */
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_output_stream_close (output, cancellable, NULL);
|
||||
g_object_unref (cancellable);
|
||||
}
|
||||
else if (! g_output_stream_close (output, NULL, &error))
|
||||
{
|
||||
g_printerr (_("Error closing '%s': %s\n"),
|
||||
gimp_file_get_utf8_name (file), error->message);
|
||||
}
|
||||
|
||||
if (output)
|
||||
|
|
|
@ -285,13 +285,26 @@ themes_apply_theme (Gimp *gimp,
|
|||
"/* end of theme.css */\n",
|
||||
gimp_file_get_utf8_name (css_user),
|
||||
esc_css_theme,
|
||||
esc_css_user) ||
|
||||
! g_output_stream_close (output, NULL, &error))
|
||||
esc_css_user))
|
||||
{
|
||||
GCancellable *cancellable = g_cancellable_new ();
|
||||
|
||||
gimp_message (gimp, NULL, GIMP_MESSAGE_ERROR,
|
||||
_("Error writing '%s': %s"),
|
||||
gimp_file_get_utf8_name (theme_css), error->message);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* Cancel the overwrite initiated by g_file_replace(). */
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_output_stream_close (output, cancellable, NULL);
|
||||
g_object_unref (cancellable);
|
||||
}
|
||||
else if (! g_output_stream_close (output, NULL, &error))
|
||||
{
|
||||
gimp_message (gimp, NULL, GIMP_MESSAGE_ERROR,
|
||||
_("Error closing '%s': %s"),
|
||||
gimp_file_get_utf8_name (theme_css), error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
g_free (esc_css_theme);
|
||||
|
|
|
@ -136,10 +136,17 @@ gimp_pdb_dump (GimpPDB *pdb,
|
|||
|
||||
if (pdb_dump.error)
|
||||
{
|
||||
GCancellable *cancellable = g_cancellable_new ();
|
||||
|
||||
g_set_error (error, pdb_dump.error->domain, pdb_dump.error->code,
|
||||
_("Writing PDB file '%s' failed: %s"),
|
||||
gimp_file_get_utf8_name (file), pdb_dump.error->message);
|
||||
g_clear_error (&pdb_dump.error);
|
||||
|
||||
/* Cancel the overwrite initiated by g_file_replace(). */
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_output_stream_close (pdb_dump.output, cancellable, NULL);
|
||||
g_object_unref (cancellable);
|
||||
g_object_unref (pdb_dump.output);
|
||||
|
||||
return FALSE;
|
||||
|
|
|
@ -221,6 +221,8 @@ gimp_filter_tool_settings_export (GimpSettingsBox *box,
|
|||
|
||||
if (! tool_class->settings_export (filter_tool, output, &error))
|
||||
{
|
||||
GCancellable *cancellable = g_cancellable_new ();
|
||||
|
||||
gimp_message (GIMP_TOOL (filter_tool)->tool_info->gimp,
|
||||
G_OBJECT (gimp_tool_gui_get_dialog (filter_tool->gui)),
|
||||
GIMP_MESSAGE_ERROR,
|
||||
|
@ -228,7 +230,13 @@ gimp_filter_tool_settings_export (GimpSettingsBox *box,
|
|||
gimp_file_get_utf8_name (file),
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* Cancel the overwrite initiated by g_file_replace(). */
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_output_stream_close (output, cancellable, NULL);
|
||||
g_object_unref (cancellable);
|
||||
g_object_unref (output);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,12 +83,20 @@ gimp_vectors_export_file (GimpImage *image,
|
|||
if (! g_output_stream_write_all (output, string->str, string->len,
|
||||
NULL, NULL, &my_error))
|
||||
{
|
||||
GCancellable *cancellable = g_cancellable_new ();
|
||||
|
||||
g_set_error (error, my_error->domain, my_error->code,
|
||||
_("Writing SVG file '%s' failed: %s"),
|
||||
gimp_file_get_utf8_name (file), my_error->message);
|
||||
g_clear_error (&my_error);
|
||||
g_string_free (string, TRUE);
|
||||
|
||||
/* Cancel the overwrite initiated by g_file_replace(). */
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_output_stream_close (output, cancellable, NULL);
|
||||
g_object_unref (cancellable);
|
||||
g_object_unref (output);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -4344,8 +4344,15 @@ gimp_dashboard_log_start_recording (GimpDashboard *dashboard,
|
|||
|
||||
if (priv->log_error)
|
||||
{
|
||||
GCancellable *cancellable = g_cancellable_new ();
|
||||
|
||||
gimp_backtrace_stop ();
|
||||
|
||||
/* Cancel the overwrite initiated by g_file_replace(). */
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_output_stream_close (priv->log_output, cancellable, NULL);
|
||||
g_object_unref (cancellable);
|
||||
|
||||
g_clear_object (&priv->log_output);
|
||||
|
||||
g_propagate_error (error, priv->log_error);
|
||||
|
@ -4422,7 +4429,18 @@ gimp_dashboard_log_stop_recording (GimpDashboard *dashboard,
|
|||
gimp_backtrace_stop ();
|
||||
|
||||
if (! priv->log_error)
|
||||
g_output_stream_close (priv->log_output, NULL, &priv->log_error);
|
||||
{
|
||||
g_output_stream_close (priv->log_output, NULL, &priv->log_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
GCancellable *cancellable = g_cancellable_new ();
|
||||
|
||||
/* Cancel the overwrite initiated by g_file_replace(). */
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_output_stream_close (priv->log_output, cancellable, NULL);
|
||||
g_object_unref (cancellable);
|
||||
}
|
||||
|
||||
g_clear_object (&priv->log_output);
|
||||
|
||||
|
|
|
@ -1764,12 +1764,20 @@ gimp_text_buffer_save (GimpTextBuffer *buffer,
|
|||
if (! g_output_stream_write_all (output, text_contents, text_length,
|
||||
NULL, NULL, &my_error))
|
||||
{
|
||||
GCancellable *cancellable = g_cancellable_new ();
|
||||
|
||||
g_set_error (error, my_error->domain, my_error->code,
|
||||
_("Writing text file '%s' failed: %s"),
|
||||
gimp_file_get_utf8_name (file), my_error->message);
|
||||
g_clear_error (&my_error);
|
||||
g_free (text_contents);
|
||||
|
||||
/* Cancel the overwrite initiated by g_file_replace(). */
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_output_stream_close (output, cancellable, NULL);
|
||||
g_object_unref (cancellable);
|
||||
g_object_unref (output);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -760,6 +760,13 @@ gimp_config_writer_close_output (GimpConfigWriter *writer,
|
|||
|
||||
if (writer->error)
|
||||
{
|
||||
GCancellable *cancellable = g_cancellable_new ();
|
||||
|
||||
/* Cancel the overwrite initiated by g_file_replace(). */
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_output_stream_close (writer->output, cancellable, NULL);
|
||||
g_object_unref (cancellable);
|
||||
|
||||
g_object_unref (writer->output);
|
||||
writer->output = NULL;
|
||||
|
||||
|
|
Loading…
Reference in New Issue