[geany/geany-plugins] 9de784: projectorganizer: Change the way symlinks are handled
Jiří Techet
git-noreply at xxxxx
Sun Mar 29 19:38:39 UTC 2015
Branch: refs/heads/master
Author: Jiří Techet <techet at gmail.com>
Committer: Jiří Techet <techet at gmail.com>
Date: Sun, 29 Mar 2015 19:38:39 UTC
Commit: 9de7847797069ad10a3c30308e68e6d0a30c95f8
https://github.com/geany/geany-plugins/commit/9de7847797069ad10a3c30308e68e6d0a30c95f8
Log Message:
-----------
projectorganizer: Change the way symlinks are handled
Previously all file names and directories were resolved to real path using
tm_get_real_path(). This caused some problems because Geany itself
doesn't resolve things like base_path so when something in base_path
is a symlink, geany path differs from path used by ProjectOrganizer.
Additional problem is when symlink points somewhere outside base_path
which causes that there are ".." entries in the project tree.
Don't resolve symlinks and only resolve real path for cases when
file identity has to be checked and also to avoid symlink cycles.
Simplify relative path creation - we don't need the ".." relative paths
any more.
Modified Paths:
--------------
projectorganizer/src/prjorg-project.c
projectorganizer/src/prjorg-sidebar.c
projectorganizer/src/prjorg-utils.c
projectorganizer/src/prjorg-utils.h
Modified: projectorganizer/src/prjorg-project.c
26 lines changed, 23 insertions(+), 3 deletions(-)
===================================================================
@@ -93,6 +93,19 @@ static GSList *get_file_list(const gchar * path, GSList *patterns, GSList *ignor
if (g_file_test(filename, G_FILE_TEST_IS_DIR))
{
GSList *lst;
+ gchar *parent_realpath, *child_realpath, *relative;
+
+ /* symlink cycle avoidance - test if directory within parent directory */
+ parent_realpath = tm_get_real_path(path);
+ child_realpath = tm_get_real_path(filename);
+ relative = get_relative_path(parent_realpath, child_realpath);
+ g_free(parent_realpath);
+ g_free(child_realpath);
+
+ if (!relative)
+ continue;
+
+ g_free(relative);
if (patterns_match(ignored_dirs_patterns, name))
{
@@ -152,9 +165,8 @@ static gint prjorg_project_rescan_root(PrjOrgRoot *root)
foreach_slist(elem, lst)
{
- char *path;
+ char *path = g_strdup(elem->data);
- path = tm_get_real_path(elem->data);
if (path)
{
SETPTR(path, utils_get_utf8_from_locale(path));
@@ -371,7 +383,15 @@ static void close_root(PrjOrgRoot *root, gpointer user_data)
static gint root_comparator(PrjOrgRoot *a, PrjOrgRoot *b)
{
- return g_strcmp0(a->base_dir, b->base_dir);
+ gchar *a_realpath, *b_realpath;
+ gint res;
+
+ a_realpath = tm_get_real_path(a->base_dir);
+ b_realpath = tm_get_real_path(b->base_dir);
+ res = g_strcmp0(a_realpath, b_realpath);
+ g_free(a_realpath);
+ g_free(b_realpath);
+ return res;
}
Modified: projectorganizer/src/prjorg-sidebar.c
16 lines changed, 8 insertions(+), 8 deletions(-)
===================================================================
@@ -358,7 +358,7 @@ static void find_file_recursive(GtkTreeIter *iter, gboolean case_sensitive, gboo
gchar *path;
path = build_path(iter);
- name = get_file_relative_path(geany_data->app->project->base_path, path);
+ name = get_relative_path(geany_data->app->project->base_path, path);
g_free(path);
}
else
@@ -372,7 +372,7 @@ static void find_file_recursive(GtkTreeIter *iter, gboolean case_sensitive, gboo
gchar *path, *rel_path;
path = build_path(iter);
- rel_path = get_file_relative_path(geany_data->app->project->base_path, path);
+ rel_path = get_relative_path(geany_data->app->project->base_path, path);
msgwin_msg_add(COLOR_BLACK, -1, NULL, "%s", rel_path ? rel_path : path);
g_free(path);
g_free(rel_path);
@@ -558,8 +558,8 @@ static gboolean match(TMTag *tag, const gchar *name, gboolean declaration, gbool
{
gchar *relpath;
- relpath = get_file_relative_path(path, tag->file->file_name);
- matches = relpath && !g_str_has_prefix(relpath, "..");
+ relpath = get_relative_path(path, tag->file->file_name);
+ matches = relpath != NULL;
g_free(relpath);
}
@@ -592,7 +592,7 @@ static void find_tags(const gchar *name, gboolean declaration, gboolean case_sen
gchar *scopestr = tag->scope ? g_strconcat(tag->scope, "::", NULL) : g_strdup("");
gchar *relpath;
- relpath = get_file_relative_path(geany_data->app->project->base_path, tag->file->file_name);
+ relpath = get_relative_path(geany_data->app->project->base_path, tag->file->file_name);
msgwin_msg_add(COLOR_BLACK, -1, NULL, "%s:%lu:\n\t[%s]\t %s%s%s", relpath,
tag->line, tm_tag_type_name(tag), scopestr, tag->name, tag->arglist ? tag->arglist : "");
g_free(scopestr);
@@ -1006,7 +1006,7 @@ static void load_project_root(PrjOrgRoot *root, GtkTreeIter *parent, GSList *hea
g_hash_table_iter_init(&iter, root->file_table);
while (g_hash_table_iter_next(&iter, &key, &value))
{
- gchar *path = get_file_relative_path(root->base_dir, key);
+ gchar *path = get_relative_path(root->base_dir, key);
lst = g_slist_prepend(lst, path);
}
lst = g_slist_sort(lst, (GCompareFunc) strcmp);
@@ -1152,8 +1152,8 @@ static gboolean follow_editor_on_idle(gpointer foo)
{
PrjOrgRoot *root = elem->data;
- path = get_file_relative_path(root->base_dir, doc->file_name);
- if (path != NULL && !g_str_has_prefix(path, ".."))
+ path = get_relative_path(root->base_dir, doc->file_name);
+ if (path)
break;
g_free(path);
Modified: projectorganizer/src/prjorg-utils.c
71 lines changed, 8 insertions(+), 63 deletions(-)
===================================================================
@@ -26,75 +26,20 @@
extern GeanyData *geany_data;
extern GeanyFunctions *geany_functions;
-static gchar *relpath(const gchar *origin_dir, const gchar *dest_dir)
-{
- gchar *origin, *dest;
- gchar **originv, **destv;
- gchar *ret = NULL;
- guint i, j;
-
- origin = tm_get_real_path(origin_dir);
- dest = tm_get_real_path(dest_dir);
-
- if (EMPTY(origin) || EMPTY(dest) || origin[0] != dest[0])
- {
- g_free(origin);
- g_free(dest);
- return NULL;
- }
-
- originv = g_strsplit_set(g_path_skip_root(origin), "/\\", -1);
- destv = g_strsplit_set(g_path_skip_root(dest), "/\\", -1);
-
- for (i = 0; originv[i] != NULL && destv[i] != NULL; i++)
- if (g_strcmp0(originv[i], destv[i]) != 0)
- break;
-
- ret = g_strdup("");
-
- for (j = i; originv[j] != NULL; j++)
- SETPTR(ret, g_build_filename(ret, "..", NULL));
- for (j = i; destv[j] != NULL; j++)
- SETPTR(ret, g_build_filename(ret, destv[j], NULL));
-
- if (strlen(ret) == 0)
- SETPTR(ret, g_strdup("."G_DIR_SEPARATOR_S));
-
- g_free(origin);
- g_free(dest);
- g_strfreev(originv);
- g_strfreev(destv);
-
- return ret;
-}
-
-
-gchar *get_file_relative_path(const gchar *origin_dir, const gchar *dest_file)
+gchar *get_relative_path(const gchar *parent, const gchar *descendant)
{
- gchar *dest_dir, *ret;
+ GFile *gf_parent, *gf_descendant;
+ gchar *ret;
- dest_dir = g_path_get_dirname(dest_file);
- ret = relpath(origin_dir, dest_dir);
- if (ret)
- {
- gchar *dest_basename;
+ gf_parent = g_file_new_for_path(parent);
+ gf_descendant = g_file_new_for_path(descendant);
- dest_basename = g_path_get_basename(dest_file);
+ ret = g_file_get_relative_path(gf_parent, gf_descendant);
- if (g_strcmp0(ret, "."G_DIR_SEPARATOR_S) != 0)
- {
- SETPTR(ret, g_build_filename(ret, dest_basename, NULL));
- }
- else
- {
- SETPTR(ret, g_strdup(dest_basename));
- }
-
- g_free(dest_basename);
- }
+ g_object_unref(gf_parent);
+ g_object_unref(gf_descendant);
- g_free(dest_dir);
return ret;
}
Modified: projectorganizer/src/prjorg-utils.h
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -19,7 +19,7 @@
#ifndef __PRJORG_UTILS_H__
#define __PRJORG_UTILS_H__
-gchar *get_file_relative_path(const gchar *origin_dir, const gchar *dest_file);
+gchar *get_relative_path(const gchar *parent, const gchar *descendant);
gboolean patterns_match(GSList *patterns, const gchar *str);
GSList *get_precompiled_patterns(gchar **patterns);
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Plugins-Commits
mailing list