Skip to content

Commit

Permalink
compose: Allow file discovery even in symlinked directories
Browse files Browse the repository at this point in the history
This was discovered to be an issue on Flathub with some component
localizations being placed in symlinked directories.

CC: flathub/flathub#5272
  • Loading branch information
ximion committed Jun 5, 2024
1 parent 9ddb404 commit 6f6986c
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 21 deletions.
69 changes: 56 additions & 13 deletions compose/asc-directory-unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,12 @@ asc_directory_unit_class_init (AscDirectoryUnitClass *klass)
}

static gboolean
asc_directory_unit_find_files_recursive (GPtrArray *files,
const gchar *path_orig,
guint path_orig_len,
const gchar *path,
GError **error)
asc_directory_unit_find_files_recursive_internal (GPtrArray *files,
const gchar *path_orig,
guint path_orig_len,
const gchar *path,
GHashTable *visited_dirs,
GError **error)
{
const gchar *tmp;
g_autoptr(GDir) dir = NULL;
Expand All @@ -104,14 +105,38 @@ asc_directory_unit_find_files_recursive (GPtrArray *files,
g_autofree gchar *path_new = NULL;
path_new = g_build_filename (path, tmp, NULL);

/* search recursively, don't follow symlinks */
if (g_file_test (path_new, G_FILE_TEST_IS_DIR) &&
!g_file_test (path_new, G_FILE_TEST_IS_SYMLINK)) {
if (!asc_directory_unit_find_files_recursive (files,
path_orig,
path_orig_len,
path_new,
error))
/* search recursively */
if (g_file_test (path_new, G_FILE_TEST_IS_DIR)) {
if (g_file_test (path_new, G_FILE_TEST_IS_SYMLINK)) {
g_autofree gchar *real_path = realpath (path_new, NULL);

if (!real_path) {
/* error if realpath fails (like memory allocation error or invalid path) */
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
"Failed to resolve real path");
return FALSE;
}

/* don't visit paths twice to avoid loops */
if (g_hash_table_contains (visited_dirs, real_path))
return TRUE;

g_hash_table_add (visited_dirs, g_steal_pointer (&real_path));
} else {
if (g_hash_table_contains (visited_dirs, path_new))
return TRUE;

g_hash_table_add (visited_dirs, g_strdup (path_new));
}

if (!asc_directory_unit_find_files_recursive_internal (files,
path_orig,
path_orig_len,
path_new,
visited_dirs,
error))
return FALSE;
} else {
g_ptr_array_add (files, g_strdup (path_new + path_orig_len));
Expand All @@ -121,6 +146,24 @@ asc_directory_unit_find_files_recursive (GPtrArray *files,
return TRUE;
}

static gboolean
asc_directory_unit_find_files_recursive (GPtrArray *files,
const gchar *path_orig,
guint path_orig_len,
const gchar *path,
GError **error)
{
g_autoptr(GHashTable) visited_dirs = NULL;
visited_dirs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

return asc_directory_unit_find_files_recursive_internal (files,
path_orig,
path_orig_len,
path,
visited_dirs,
error);
}

static gboolean
asc_directory_unit_open (AscUnit *unit, GError **error)
{
Expand Down
1 change: 1 addition & 0 deletions tests/samples/compose/usr/share/locale/dir_loop/loop
2 changes: 1 addition & 1 deletion tests/test-compose.c
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ test_compose_directory_unit (void)
g_assert_true (ret);

contents = asc_unit_get_contents (ASC_UNIT (dirunit));
g_assert_cmpint (contents->len, ==, 15);
g_assert_cmpint (contents->len, ==, 16);
as_sort_strings (contents);

g_assert_cmpstr (g_ptr_array_index (contents, 0), ==, "/Raleway-Regular.ttf");
Expand Down
13 changes: 6 additions & 7 deletions tests/test-xmldata.c
Original file line number Diff line number Diff line change
Expand Up @@ -2293,13 +2293,12 @@ test_xml_rw_branding (void)
static void
test_xml_rw_developer (void)
{
static const gchar
*xmldata_tags = "<component>\n"
" <id>org.example.DeveloperTest</id>\n"
" <developer id=\"freedesktop.org\">\n"
" <name>FreeDesktop.org Project</name>\n"
" </developer>\n"
"</component>\n";
static const gchar *xmldata_tags = "<component>\n"
" <id>org.example.DeveloperTest</id>\n"
" <developer id=\"freedesktop.org\">\n"
" <name>FreeDesktop.org Project</name>\n"
" </developer>\n"
"</component>\n";
g_autoptr(AsComponent) cpt = NULL;
g_autofree gchar *res = NULL;
AsDeveloper *devp;
Expand Down

0 comments on commit 6f6986c

Please sign in to comment.