Skip to content

Commit

Permalink
Merge branch 'uri-is-descendant' into 'master'
Browse files Browse the repository at this point in the history
add rb_uri_is_descendant

Closes #1769

See merge request GNOME/rhythmbox!107
  • Loading branch information
Jonathan Matthew committed Apr 10, 2021
2 parents 5475530 + 8b7309c commit e57da35
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 4 deletions.
42 changes: 42 additions & 0 deletions lib/rb-file-helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,48 @@ rb_file_find_extant_parent (GFile *file)
return file;
}

/**
* rb_uri_is_descendant:
* @uri: URI to check
* @ancestor: a URI to check against
*
* Checks if @uri refers to a path beneath @ancestor, such that removing some number
* of path segments of @uri would result in @ancestor.
* It doesn't do any filesystem operations, it just looks at the URIs as strings.
* The URI strings should be built by looking at a filesystem rather than user input,
* and must not have path segments that are empty (multiple slashes) or '.' or '..'.
*
* Given this input, checking if one URI is a descendant of another is pretty simple.
* A descendant URI must have the ancestor as a prefix, and if the ancestor ends with
* a slash, there must be at least one character after that, otherwise the following
* character must be a slash with at least one character after it.
*
* Return value: %TRUE if @uri is a descendant of @ancestor
*/
gboolean
rb_uri_is_descendant (const char *uri, const char *ancestor)
{
int len;

if (g_str_has_prefix (uri, ancestor) == FALSE)
return FALSE;

len = strlen(ancestor);
if (ancestor[len - 1] == '/') {
/*
* following character in uri must be a new path segment, not
* the end of the uri. not considering multiple slashes here.
*/
return (uri[len] != '\0');
} else {
/*
* following character in uri must be a separator, with something after it.
* not considering multiple slashes here.
*/
return ((uri[len] == '/') && strlen(uri) > (len + 1));
}
}

/**
* rb_uri_get_filesystem_type:
* @uri: URI to get filesystem type for
Expand Down
1 change: 1 addition & 0 deletions lib/rb-file-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ gboolean rb_uri_is_writable (const char *uri);
gboolean rb_uri_is_local (const char *uri);
gboolean rb_uri_is_hidden (const char *uri);
gboolean rb_uri_could_be_podcast (const char *uri, gboolean *is_opml);
gboolean rb_uri_is_descendant (const char *uri, const char *ancestor);
char * rb_uri_make_hidden (const char *uri);
char * rb_uri_get_dir_name (const char *uri);
char * rb_uri_get_short_path_name (const char *uri);
Expand Down
4 changes: 2 additions & 2 deletions plugins/generic-player/rb-generic-player-source.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ default_uri_from_playlist_uri (RBGenericPlayerSource *source, const char *uri)
char *full_uri;

mount_uri = rb_generic_player_source_get_mount_path (source);
if (g_str_has_prefix (uri, mount_uri)) {
if (rb_uri_is_descendant (uri, mount_uri)) {
return g_strdup (uri);
}

Expand All @@ -704,7 +704,7 @@ default_uri_to_playlist_uri (RBGenericPlayerSource *source, const char *uri, Tot
case TOTEM_PL_PARSER_IRIVER_PLA:
/* we need absolute paths within the device filesystem for this format */
mount_uri = rb_generic_player_source_get_mount_path (source);
if (g_str_has_prefix (uri, mount_uri) == FALSE) {
if (rb_uri_is_descendant (uri, mount_uri) == FALSE) {
rb_debug ("uri %s is not under device mount uri %s", uri, mount_uri);
return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion rhythmdb/rhythmdb-monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ rhythmdb_directory_change_cb (GFileMonitor *monitor,

/* ignore new files outside of the library locations */
for (i = 0; db->priv->library_locations[i] != NULL; i++) {
if (g_str_has_prefix (canon_uri, db->priv->library_locations[i])) {
if (rb_uri_is_descendant (canon_uri, db->priv->library_locations[i])) {
in_library = TRUE;
break;
}
Expand Down
17 changes: 17 additions & 0 deletions tests/test-file-helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@ START_TEST (test_rb_check_dir_has_space)
}
END_TEST

START_TEST (test_rb_uri_is_descendant)
{
ck_assert (rb_uri_is_descendant ("file:///tmp", "file:///"));
ck_assert (rb_uri_is_descendant ("file:///tmp/2", "file:///"));
ck_assert (rb_uri_is_descendant ("file:///tmp/2", "file:///tmp"));
ck_assert (rb_uri_is_descendant ("file:///tmp/2", "file:///tmp/"));
ck_assert (rb_uri_is_descendant ("file:///tmp/", "file:///tmp") == FALSE);
ck_assert (rb_uri_is_descendant ("file:///tmp", "file:///tmp/") == FALSE);
ck_assert (rb_uri_is_descendant ("file:///tmp/", "file:///tmp/") == FALSE);
ck_assert (rb_uri_is_descendant ("file:///tmp", "file:///tmp") == FALSE);
ck_assert (rb_uri_is_descendant ("file:///tmp2", "file:///tmp") == FALSE);
ck_assert (rb_uri_is_descendant ("file:///tmp/2", "file:///tmp2") == FALSE);
ck_assert (rb_uri_is_descendant ("file:///tmp/22", "file:///tmp/2") == FALSE);
}
END_TEST

static Suite *
rb_file_helpers_suite ()
{
Expand All @@ -110,6 +126,7 @@ rb_file_helpers_suite ()

tcase_add_test (tc_chain, test_rb_uri_get_short_path_name);
tcase_add_test (tc_chain, test_rb_check_dir_has_space);
tcase_add_test (tc_chain, test_rb_uri_is_descendant);

return s;
}
Expand Down
2 changes: 1 addition & 1 deletion widgets/rb-import-dialog.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ current_folder_changed_cb (GtkFileChooser *chooser, RBImportDialog *dialog)
locations = g_settings_get_strv (settings, "locations");
gtk_widget_set_sensitive (dialog->priv->copy_check, TRUE);
for (i = 0; locations[i] != NULL; i++) {
if (g_str_has_prefix (uri, locations[i])) {
if ((g_strcmp0 (uri, locations[i]) == 0) || rb_uri_is_descendant (uri, locations[i])) {
gtk_widget_set_sensitive (dialog->priv->copy_check, FALSE);
break;
}
Expand Down

0 comments on commit e57da35

Please sign in to comment.