[evolution-data-server] Bug #655252 - Need to escape the comp_uid part of a path



commit d120b737500158104f20409287878ef595201d7e
Author: Milan Crha <mcrha redhat com>
Date:   Mon Sep 26 11:00:35 2011 +0200

    Bug #655252 - Need to escape the comp_uid part of a path

 calendar/backends/caldav/e-cal-backend-caldav.c |   83 ++++++++++++-----------
 calendar/backends/file/e-cal-backend-file.c     |   19 ++----
 calendar/libedata-cal/e-cal-backend.c           |   21 ++++++
 calendar/libedata-cal/e-cal-backend.h           |    1 +
 configure.ac                                    |    4 +-
 libedataserver/e-data-server-util.c             |   52 ++++++++++++++
 libedataserver/e-data-server-util.h             |    4 +
 7 files changed, 127 insertions(+), 57 deletions(-)
---
diff --git a/calendar/backends/caldav/e-cal-backend-caldav.c b/calendar/backends/caldav/e-cal-backend-caldav.c
index 694a410..0acc6a3 100644
--- a/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -3073,16 +3073,14 @@ convert_to_url_attachment (ECalBackendCalDAV *cbdav,
 {
 	ECalBackend *backend;
 	GSList *to_remove = NULL, *to_remove_after_download = NULL;
-	const gchar *cache_dir;
 	icalcomponent *cclone;
 	icalproperty *p;
+	gint fileindex;
 
 	g_return_if_fail (cbdav != NULL);
 	g_return_if_fail (icalcomp != NULL);
 
 	backend = E_CAL_BACKEND (cbdav);
-	cache_dir = e_cal_backend_get_cache_dir (backend);
-
 	cclone = icalcomponent_new_clone (icalcomp);
 
 	/* Remove all inline attachments first */
@@ -3101,13 +3099,13 @@ convert_to_url_attachment (ECalBackendCalDAV *cbdav,
 	g_slist_free (to_remove);
 
 	/* convert inline attachments to url attachments now */
-	for (p = icalcomponent_get_first_property (cclone, ICAL_ATTACH_PROPERTY);
+	for (p = icalcomponent_get_first_property (cclone, ICAL_ATTACH_PROPERTY), fileindex = 0;
 	     p;
-	     p = icalcomponent_get_next_property (cclone, ICAL_ATTACH_PROPERTY)) {
+	     p = icalcomponent_get_next_property (cclone, ICAL_ATTACH_PROPERTY), fileindex++) {
 		icalattach *attach;
-		gchar *dir;
 		gsize len = -1;
 		gchar *decoded = NULL;
+		gchar *basename, *local_filename;
 
 		attach = icalproperty_get_attach ((const icalproperty *) p);
 		if (icalattach_get_is_url (attach)) {
@@ -3124,17 +3122,12 @@ convert_to_url_attachment (ECalBackendCalDAV *cbdav,
 			}
 		}
 
-		dir = g_build_filename (
-			cache_dir, icalcomponent_get_uid (icalcomp), NULL);
-		if (g_mkdir_with_parents (dir, 0700) >= 0) {
-			GError *error = NULL;
-			gchar *basename;
-			gchar *dest;
+		basename = icalproperty_get_parameter_as_string_r (p, X_E_CALDAV_ATTACHMENT_NAME);
+		local_filename = e_cal_backend_create_cache_filename (backend, icalcomponent_get_uid (icalcomp), basename, fileindex);
+		g_free (basename);
 
-			basename = icalproperty_get_parameter_as_string_r (p,
-					X_E_CALDAV_ATTACHMENT_NAME);
-			dest = g_build_filename (dir, basename, NULL);
-			g_free (basename);
+		if (local_filename) {
+			GError *error = NULL;
 
 			if (decoded == NULL) {
 				gchar *content;
@@ -3143,11 +3136,11 @@ convert_to_url_attachment (ECalBackendCalDAV *cbdav,
 				decoded = (gchar *) g_base64_decode (content, &len);
 			}
 
-			if (g_file_set_contents (dest, decoded, len, &error)) {
+			if (g_file_set_contents (local_filename, decoded, len, &error)) {
 				icalproperty *prop;
 				gchar *url;
 
-				url = g_filename_to_uri (dest, NULL, NULL);
+				url = g_filename_to_uri (local_filename, NULL, NULL);
 				attach = icalattach_new_from_url (url);
 				prop = icalproperty_new_attach (attach);
 				icalattach_unref (attach);
@@ -3157,10 +3150,9 @@ convert_to_url_attachment (ECalBackendCalDAV *cbdav,
 				g_warning ("%s\n", error->message);
 				g_clear_error (&error);
 			}
-			g_free (decoded);
-			g_free (dest);
+
+			g_free (local_filename);
 		}
-		g_free (dir);
 	}
 
 	icalcomponent_free (cclone);
@@ -3170,32 +3162,31 @@ convert_to_url_attachment (ECalBackendCalDAV *cbdav,
 }
 
 static void
-remove_dir (const gchar *dir)
+remove_files (const gchar *dir, const gchar *fileprefix)
 {
 	GDir *d;
 
-	/*
-	 * remove all files in the direcory first
-	 * and call rmdir to remove the empty directory
-	 * because ZFS does not support unlinking a directory.
-	 */
+	g_return_if_fail (dir != NULL);
+	g_return_if_fail (fileprefix != NULL);
+	g_return_if_fail (*fileprefix != '\0');
+
 	d = g_dir_open (dir, 0, NULL);
 	if (d) {
 		const gchar *entry;
+		gint len = strlen (fileprefix);
 
 		while ((entry = g_dir_read_name (d)) != NULL) {
-			gchar *path;
+			if (entry && strncmp (entry, fileprefix, len) == 0) {
+				gchar *path;
 
-			path = g_build_filename (dir, entry, NULL);
-			if (g_file_test (path, G_FILE_TEST_IS_DIR))
-				remove_dir (path);
-			else
-				g_unlink (path);
-			g_free (path);
+				path = g_build_filename (dir, entry, NULL);
+				if (!g_file_test (path, G_FILE_TEST_IS_DIR))
+					g_unlink (path);
+				g_free (path);
+			}
 		}
 		g_dir_close (d);
 	}
-	g_rmdir (dir);
 }
 
 static void
@@ -3203,11 +3194,10 @@ remove_cached_attachment (ECalBackendCalDAV *cbdav,
                           const gchar *uid)
 {
 	ECalBackendCalDAVPrivate *priv;
-	ECalBackend *backend;
-	const gchar *cache_dir;
 	GSList *l;
 	guint len;
 	gchar *dir;
+	gchar *fileprefix;
 
 	g_return_if_fail (cbdav != NULL);
 	g_return_if_fail (uid != NULL);
@@ -3220,10 +3210,21 @@ remove_cached_attachment (ECalBackendCalDAV *cbdav,
 	if (len > 0)
 		return;
 
-	backend = E_CAL_BACKEND (cbdav);
-	cache_dir = e_cal_backend_get_cache_dir (backend);
-	dir = g_build_filename (cache_dir, uid, NULL);
-	remove_dir (dir);
+	dir = e_cal_backend_create_cache_filename (E_CAL_BACKEND (cbdav), uid, "a", 0);
+	if (!dir)
+		return;
+
+	fileprefix = g_strrstr (dir, G_DIR_SEPARATOR_S);
+	if (fileprefix) {
+		*fileprefix = '\0';
+		fileprefix++;
+
+		if (*fileprefix)
+			fileprefix[strlen(fileprefix) - 1] = '\0';
+
+		remove_files (dir, fileprefix);
+	}
+
 	g_free (dir);
 }
 
diff --git a/calendar/backends/file/e-cal-backend-file.c b/calendar/backends/file/e-cal-backend-file.c
index 40fcf92..5002ab4 100644
--- a/calendar/backends/file/e-cal-backend-file.c
+++ b/calendar/backends/file/e-cal-backend-file.c
@@ -2916,23 +2916,16 @@ fetch_attachments (ECalBackendSync *backend,
 {
 	GSList *attach_list = NULL, *new_attach_list = NULL;
 	GSList *l;
-	gchar  *attach_store;
 	gchar *dest_url, *dest_file;
-	gint fd;
-	const gchar *user_data_dir;
+	gint fd, fileindex;
 	const gchar *uid;
 
 	e_cal_component_get_attachment_list (comp, &attach_list);
 	e_cal_component_get_uid (comp, &uid);
 
-	/*FIXME  get the uri rather than computing the path */
-	user_data_dir = e_get_user_data_dir ();
-	attach_store = g_build_filename (
-		user_data_dir, "calendar", "system", NULL);
-
-	for (l = attach_list; l; l = l->next) {
+	for (l = attach_list, fileindex = 0; l; l = l->next, fileindex++) {
 		gchar *sfname = g_filename_from_uri ((const gchar *) l->data, NULL, NULL);
-		gchar *filename, *new_filename;
+		gchar *filename;
 		GMappedFile *mapped_file;
 		GError *error = NULL;
 
@@ -2948,10 +2941,8 @@ fetch_attachments (ECalBackendSync *backend,
 			continue;
 		}
 		filename = g_path_get_basename (sfname);
-		new_filename = g_strconcat (uid, "-", filename, NULL);
+		dest_file = e_cal_backend_create_cache_filename (E_CAL_BACKEND (backend), uid, filename, fileindex);
 		g_free (filename);
-		dest_file = g_build_filename (attach_store, new_filename, NULL);
-		g_free (new_filename);
 		fd = g_open (dest_file, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0600);
 		if (fd == -1) {
 			/* TODO handle error conditions */
@@ -2975,7 +2966,7 @@ fetch_attachments (ECalBackendSync *backend,
 		new_attach_list = g_slist_append (new_attach_list, dest_url);
 		g_free (sfname);
 	}
-	g_free (attach_store);
+
 	e_cal_component_set_attachment_list (comp, new_attach_list);
 }
 
diff --git a/calendar/libedata-cal/e-cal-backend.c b/calendar/libedata-cal/e-cal-backend.c
index b21f085..a6aa88a 100644
--- a/calendar/libedata-cal/e-cal-backend.c
+++ b/calendar/libedata-cal/e-cal-backend.c
@@ -624,6 +624,27 @@ e_cal_backend_set_cache_dir (ECalBackend *backend,
 }
 
 /**
+ * e_cal_backend_create_cache_filename:
+ * @backend: an #ECalBackend
+ * @uid: a component UID
+ * @filename: a filename to use; can be NULL
+ * @fileindex: index of a file; used only when @filename is NULL
+ *
+ * Returns: a filename for an attachment in a local cache dir. Free returned
+ * pointer with a g_free().
+ *
+ * Since: 3.4
+ **/
+gchar *
+e_cal_backend_create_cache_filename (ECalBackend *backend, const gchar *uid, const gchar *filename, gint fileindex)
+{
+	g_return_val_if_fail (backend != NULL, NULL);
+	g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
+
+	return e_filename_mkdir_encoded (e_cal_backend_get_cache_dir (backend), uid, filename, fileindex);
+}
+
+/**
  * e_cal_backend_get_backend_property:
  * @backend: an #ECalBackend
  * @cal: an #EDataCal
diff --git a/calendar/libedata-cal/e-cal-backend.h b/calendar/libedata-cal/e-cal-backend.h
index 75721f6..981d9fb 100644
--- a/calendar/libedata-cal/e-cal-backend.h
+++ b/calendar/libedata-cal/e-cal-backend.h
@@ -183,6 +183,7 @@ gboolean	e_cal_backend_is_removed		(ECalBackend *backend);
 
 const gchar *	e_cal_backend_get_cache_dir		(ECalBackend *backend);
 void		e_cal_backend_set_cache_dir		(ECalBackend *backend, const gchar *cache_dir);
+gchar *		e_cal_backend_create_cache_filename	(ECalBackend *backend, const gchar *uid, const gchar *filename, gint fileindex);
 
 void		e_cal_backend_add_client		(ECalBackend *backend, EDataCal *cal);
 void		e_cal_backend_remove_client		(ECalBackend *backend, EDataCal *cal);
diff --git a/configure.ac b/configure.ac
index 275d3b2..191c590 100644
--- a/configure.ac
+++ b/configure.ac
@@ -77,7 +77,7 @@ AC_SUBST(CALENDAR_DBUS_SERVICE_NAME)
 dnl ******************************
 dnl Libtool versioning
 dnl ******************************
-LIBEDATASERVER_CURRENT=15
+LIBEDATASERVER_CURRENT=16
 LIBEDATASERVER_REVISION=0
 LIBEDATASERVER_AGE=0
 
@@ -85,7 +85,7 @@ LIBEDATASERVERUI_CURRENT=1
 LIBEDATASERVERUI_REVISION=0
 LIBEDATASERVERUI_AGE=0
 
-LIBECAL_CURRENT=12
+LIBECAL_CURRENT=13
 LIBECAL_REVISION=2
 LIBECAL_AGE=2
 
diff --git a/libedataserver/e-data-server-util.c b/libedataserver/e-data-server-util.c
index 3f2ff02..7597476 100644
--- a/libedataserver/e-data-server-util.c
+++ b/libedataserver/e-data-server-util.c
@@ -769,6 +769,58 @@ e_filename_make_safe (gchar *string)
 	}
 }
 
+/**
+ * e_filename_mkdir_encoded:
+ * @basepath: base path of a file name; this is left unchanged
+ * @fileprefix: prefix for the filename; this is encoded
+ * @filename: file name to use; this is encoded; can be %NULL
+ * @fileindex: used when @filename is NULL, then the filename
+ *        is generated as "file" + fileindex
+ *
+ * Creates a local path constructed from @basepath / @fileprefix + "-" + @filename,
+ * and makes sure the path @basepath exists. If creation of
+ * the path fails, then NULL is returned.
+ *
+ * Returns: Full local path like g_build_filename() except that @fileprefix
+ * and @filename are encoded to create a proper file elements for
+ * a file system. Free returned pointer with g_free().
+ *
+ * Since: 3.4
+ **/
+gchar *
+e_filename_mkdir_encoded (const gchar *basepath, const gchar *fileprefix, const gchar *filename, gint fileindex)
+{
+	gchar *elem1, *elem2, *res, *fn;
+
+	g_return_val_if_fail (basepath != NULL, NULL);
+	g_return_val_if_fail (*basepath != 0, NULL);
+	g_return_val_if_fail (fileprefix != NULL, NULL);
+	g_return_val_if_fail (*fileprefix != 0, NULL);
+	g_return_val_if_fail (!filename || *filename, NULL);
+
+	if (g_mkdir_with_parents (basepath, 0700) < 0)
+		return NULL;
+
+	elem1 = g_strdup (fileprefix);
+	if (filename)
+		elem2 = g_strdup (filename);
+	else
+		elem2 = g_strdup_printf ("file%d", fileindex);
+
+	e_filename_make_safe (elem1);
+	e_filename_make_safe (elem2);
+
+	fn = g_strconcat (elem1, "-", elem2, NULL);
+
+	res = g_build_filename (basepath, fn, NULL);
+
+	g_free (fn);
+	g_free (elem1);
+	g_free (elem2);
+
+	return res;
+}
+
 #ifdef G_OS_WIN32
 
 #include <windows.h>
diff --git a/libedataserver/e-data-server-util.h b/libedataserver/e-data-server-util.h
index 9355d5b..9feeedc 100644
--- a/libedataserver/e-data-server-util.h
+++ b/libedataserver/e-data-server-util.h
@@ -49,6 +49,10 @@ const gchar *   e_util_ensure_gdbus_string	(const gchar *str,
 						 gchar **gdbus_str);
 guint64		e_util_gthread_id		(GThread *thread);
 void		e_filename_make_safe		(gchar *string);
+gchar *		e_filename_mkdir_encoded	(const gchar *basepath,
+						 const gchar *fileprefix,
+						 const gchar *filename,
+						 gint fileindex);
 
 gsize		e_utf8_strftime			(gchar *string,
 						 gsize max,



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