Code

Fix by Adib for 353847
authorscislac <scislac@users.sourceforge.net>
Wed, 16 Sep 2009 02:04:50 +0000 (02:04 +0000)
committerscislac <scislac@users.sourceforge.net>
Wed, 16 Sep 2009 02:04:50 +0000 (02:04 +0000)
src/extension/output.h
src/extension/system.cpp
src/file.cpp
src/io/sys.cpp
src/io/sys.h

index b52a96211c9c36d468ecadd03cd380febc2ba46c..584fafda8a276f9477d52265ed27f999633b94d4 100644 (file)
@@ -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);
index 365ea925bb5628aebd5ba0e2d59331d4f5af8c4c..43e7af494430ec6ae43f276960b203c64017ec69 100644 (file)
@@ -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);
 
 
index fd1438eb6cf1446ed0073ba6aaf141b56857b8e3..924ddc53d7595e7b54cdeb66faba007b66e500fd 100644 (file)
@@ -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 {
index a5158c58792e3db23028c26bb25ff240beb7fd0e..2841f0af8a7fd88f59b0b3cd687f7e829b6458fc 100644 (file)
@@ -15,6 +15,8 @@
 # include "config.h"
 #endif
 
+#include <glib.h>
+#include <glib/gstdio.h>
 #include <glib/gutils.h>
 #include <glibmm/fileutils.h>
 #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)
index 29c33c1c7c24919829e0923f19b23c028af46ce0..8623f6be9b18657e73b22bc5674cec4edb6dd3fb 100644 (file)
@@ -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);