From: scislac Date: Wed, 16 Sep 2009 02:04:50 +0000 (+0000) Subject: Fix by Adib for 353847 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=c091bf609ef421557ff56ede2b98e7ac0d9ae0a6;p=inkscape.git Fix by Adib for 353847 --- diff --git a/src/extension/output.h b/src/extension/output.h index b52a96211..584fafda8 100644 --- a/src/extension/output.h +++ b/src/extension/output.h @@ -31,6 +31,7 @@ public: class save_failed {}; /**< Generic failure for an undescribed reason */ class save_cancelled {}; /**< Saving was cancelled */ class no_extension_found {}; /**< Failed because we couldn't find an extension to match the filename */ + class file_read_only {}; /**< The existing file can not be opened for writing */ Output (Inkscape::XML::Node * in_repr, Implementation::Implementation * in_imp); diff --git a/src/extension/system.cpp b/src/extension/system.cpp index 365ea925b..43e7af494 100644 --- a/src/extension/system.cpp +++ b/src/extension/system.cpp @@ -32,6 +32,7 @@ #include "implementation/script.h" #include "implementation/xslt.h" #include "xml/rebase-hrefs.h" +#include "io/sys.h" /* #include "implementation/plugin.h" */ namespace Inkscape { @@ -248,6 +249,13 @@ save(Extension *key, SPDocument *doc, gchar const *filename, bool setextension, throw Output::no_overwrite(); } + // test if the file exists and is writable + // the test only checks the file attributes and might pass where ACL does not allow to write + if (Inkscape::IO::file_test(filename, G_FILE_TEST_EXISTS) && !Inkscape::IO::file_is_writable(filename)) { + g_free(fileName); + throw Output::file_read_only(); + } + Inkscape::XML::Node *repr = sp_document_repr_root(doc); diff --git a/src/file.cpp b/src/file.cpp index fd1438eb6..924ddc53d 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -591,6 +591,14 @@ file_save(Gtk::Window &parentWindow, SPDocument *doc, const Glib::ustring &uri, g_free(text); g_free(safeUri); return FALSE; + } catch (Inkscape::Extension::Output::file_read_only &e) { + gchar *safeUri = Inkscape::IO::sanitizeString(uri.c_str()); + gchar *text = g_strdup_printf(_("File %s is write protected. Please remove write protection and try again."), safeUri); + SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved.")); + sp_ui_error_dialog(text); + g_free(text); + g_free(safeUri); + return FALSE; } catch (Inkscape::Extension::Output::save_failed &e) { gchar *safeUri = Inkscape::IO::sanitizeString(uri.c_str()); gchar *text = g_strdup_printf(_("File %s could not be saved."), safeUri); @@ -604,6 +612,9 @@ file_save(Gtk::Window &parentWindow, SPDocument *doc, const Glib::ustring &uri, return FALSE; } catch (Inkscape::Extension::Output::no_overwrite &e) { return sp_file_save_dialog(parentWindow, doc, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_AS); + } catch (...) { + SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved.")); + return FALSE; } SP_ACTIVE_DESKTOP->event_log->rememberFileSave(); @@ -837,8 +848,8 @@ sp_file_save_document(Gtk::Window &parentWindow, SPDocument *doc) if (doc->isModifiedSinceSave()) { if ( doc->uri == NULL ) { - // Hier sollte in Argument mitgegeben werden, das anzeigt, daß das Dokument das erste - // Mal gespeichert wird, so daß als default .svg ausgewählt wird und nicht die zuletzt + // Hier sollte in Argument mitgegeben werden, das anzeigt, da� das Dokument das erste + // Mal gespeichert wird, so da� als default .svg ausgew�hlt wird und nicht die zuletzt // benutzte "Save as ..."-Endung return sp_file_save_dialog(parentWindow, doc, Inkscape::Extension::FILE_SAVE_METHOD_INKSCAPE_SVG); } else { diff --git a/src/io/sys.cpp b/src/io/sys.cpp index a5158c587..2841f0af8 100644 --- a/src/io/sys.cpp +++ b/src/io/sys.cpp @@ -15,6 +15,8 @@ # include "config.h" #endif +#include +#include #include #include #if GLIB_CHECK_VERSION(2,6,0) @@ -269,6 +271,38 @@ bool Inkscape::IO::file_test( char const *utf8name, GFileTest test ) return exists; } +bool Inkscape::IO::file_is_writable( char const *utf8name) +{ + bool success = true; + + if ( utf8name) { + gchar *filename = NULL; + if (utf8name && !g_utf8_validate(utf8name, -1, NULL)) { + /* FIXME: Trying to guess whether or not a filename is already in utf8 is unreliable. + If any callers pass non-utf8 data (e.g. using g_get_home_dir), then change caller to + use simple g_file_test. Then add g_return_val_if_fail(g_utf_validate(...), false) + to beginning of this function. */ + filename = g_strdup(utf8name); + // Looks like g_get_home_dir isn't safe. + //g_warning("invalid UTF-8 detected internally. HUNT IT DOWN AND KILL IT!!!"); + } else { + filename = g_filename_from_utf8 ( utf8name, -1, NULL, NULL, NULL ); + } + if ( filename ) { + struct stat st; + if(g_lstat (filename, &st) == 0) { + success = ((st.st_mode & S_IWRITE) != 0); + } + g_free(filename); + filename = NULL; + } else { + g_warning( "Unable to convert filename in IO:file_test" ); + } + } + + return success; +} + /** Wrapper around g_dir_open, but taking a utf8name as first argument. */ GDir * Inkscape::IO::dir_open(gchar const *const utf8name, guint const flags, GError **const error) diff --git a/src/io/sys.h b/src/io/sys.h index 29c33c1c7..8623f6be9 100644 --- a/src/io/sys.h +++ b/src/io/sys.h @@ -38,6 +38,8 @@ int file_open_tmp( std::string& name_used, const std::string& prefix ); bool file_test( char const *utf8name, GFileTest test ); +bool file_is_writable( char const *utf8name); + GDir *dir_open(gchar const *utf8name, guint flags, GError **error); gchar *dir_read_utf8name(GDir *dir);