Skip to content

Commit

Permalink
Try harder to find the host path for the documents
Browse files Browse the repository at this point in the history
When the access to the directory is provided by the portal (like
browser download directory) the stored files in the directory
are not found by xdp_get_real_path_for_doc_path and /run/user/...
path is opened instead of host path by the OpenFile or OpenDirectory portal.
This fix tries to recreate host path from the document id and
rest of the given path.
  • Loading branch information
xhorak committed Jan 20, 2025
1 parent 1c902cc commit 27194b7
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 40 deletions.
41 changes: 3 additions & 38 deletions src/file-chooser.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,41 +155,6 @@ send_response_in_thread_func (GTask *task,
g_task_return_boolean (task, TRUE);
}

/* Calling Lookup on a nonexisting path does not work, so we
* pull the doc id out of the path manually.
*/
static gboolean
looks_like_document_portal_path (const char *path,
char **guessed_docid)
{
const char *prefix = "/run/user/";
char *docid;
char *p, *q;

if (!g_str_has_prefix (path, prefix))
return FALSE;

p = strstr (path, "/doc/");
if (!p)
return FALSE;

p += strlen ("/doc/");
q = strchr (p, '/');
if (q)
docid = g_strndup (p, q - p);
else
docid = g_strdup (p);

if (docid[0] == '\0')
{
g_free (docid);
return FALSE;
}

*guessed_docid = docid;
return TRUE;
}

static char *
get_host_folder_for_doc_id (const char *doc_id)
{
Expand Down Expand Up @@ -555,7 +520,7 @@ handle_open_file (XdpDbusFileChooser *object,
const char *path_from_app = g_variant_get_bytestring (value);
g_autofree char *host_path = g_strdup (path_from_app);
g_autofree char *doc_id_from_app = NULL;
if (looks_like_document_portal_path (host_path, &doc_id_from_app))
if (xdp_looks_like_document_portal_path (host_path, &doc_id_from_app))
{
char *real_path = get_host_folder_for_doc_id (doc_id_from_app);
if (real_path)
Expand Down Expand Up @@ -696,7 +661,7 @@ handle_save_file (XdpDbusFileChooser *object,
g_autofree char *doc_id = NULL;

if (strcmp (path, host_path) == 0 &&
looks_like_document_portal_path (path, &doc_id))
xdp_looks_like_document_portal_path (path, &doc_id))
{
char *real_path = xdp_get_real_path_for_doc_id (doc_id);

Expand All @@ -721,7 +686,7 @@ handle_save_file (XdpDbusFileChooser *object,
const char *path_from_app = g_variant_get_bytestring (value);
g_autofree char *host_path = g_strdup (path_from_app);
g_autofree char *doc_id_from_app = NULL;
if (looks_like_document_portal_path (host_path, &doc_id_from_app))
if (xdp_looks_like_document_portal_path (host_path, &doc_id_from_app))
{
char *real_path = get_host_folder_for_doc_id (doc_id_from_app);
if (real_path)
Expand Down
31 changes: 29 additions & 2 deletions src/open-uri.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,23 @@ app_exists (const char *app_id)
return (info != NULL);
}

static char*
build_host_path_from_doc_id(const char* doc_id, const char* doc_path)
{
gchar *result;
g_autofree char *host_path = xdp_get_real_path_for_doc_id (doc_id);
g_autofree char *doc_path_regex = g_strconcat("/run/user/[0-9]+/doc/", doc_id, "/[^/]+(.*)", NULL);
gchar **path_postfix = g_regex_split_simple(doc_path_regex, doc_path, 0, 0);

if (path_postfix[0] && path_postfix[1]) {
result = g_strconcat(host_path, path_postfix[1], NULL);
} else {
result = g_strdup(host_path);
}
g_strfreev (path_postfix);
return result;
}

static void
handle_open_in_thread_func (GTask *task,
gpointer source_object,
Expand Down Expand Up @@ -688,7 +705,11 @@ handle_open_in_thread_func (GTask *task,

if (path != NULL)
{
host_path = xdp_get_real_path_for_doc_path (path, request->app_info);
g_autofree char *guessed_docid = NULL;
if (xdp_looks_like_document_portal_path(path, &guessed_docid))
{
host_path = build_host_path_from_doc_id(guessed_docid, path);
}
if (host_path)
{
g_debug ("OpenFile: translating path value '%s' to host path '%s'", path, host_path);
Expand Down Expand Up @@ -724,7 +745,13 @@ handle_open_in_thread_func (GTask *task,

if (open_dir)
{
g_autofree char *real_path = xdp_get_real_path_for_doc_path (path, request->app_info);
g_autofree char *guessed_docid = NULL;
g_autofree char *real_path = NULL;
if (xdp_looks_like_document_portal_path(path, &guessed_docid)) {
real_path = build_host_path_from_doc_id(guessed_docid, path);
} else {
real_path = g_strdup(path);
}
/* Try opening the directory via the file manager interface, then
fall back to a plain URI open */
g_autoptr(GError) local_error = NULL;
Expand Down
37 changes: 37 additions & 0 deletions src/xdp-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,43 @@ is_valid_name_character (gint c, gboolean allow_dash)
(c == '_') || (allow_dash && c == '-');
}


/* Get the document id from the path, if there's any.
* Returns TRUE when path seems to point to the documents
* storage.
*/
gboolean
xdp_looks_like_document_portal_path (const char *path,
char **guessed_docid)
{
const char *prefix = "/run/user/";
char *docid;
char *p, *q;

if (!g_str_has_prefix (path, prefix))
return FALSE;

p = strstr (path, "/doc/");
if (!p)
return FALSE;

p += strlen ("/doc/");
q = strchr (p, '/');
if (q)
docid = g_strndup (p, q - p);
else
docid = g_strdup (p);

if (docid[0] == '\0')
{
g_free (docid);
return FALSE;
}

*guessed_docid = docid;
return TRUE;
}

/* This is the same as flatpak apps, except we also allow
names to start with digits, and two-element names so that ids of the form
snap.$snapname is allowed for all snap names. */
Expand Down
1 change: 1 addition & 0 deletions src/xdp-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ G_DEFINE_AUTO_CLEANUP_FREE_FUNC(XdpFd, close, -1)
void xdp_set_documents_mountpoint (const char *path);
const char * xdp_get_documents_mountpoint (void);
char * xdp_get_alternate_document_path (const char *path, const char *app_id);
gboolean xdp_looks_like_document_portal_path (const char *path, char **guessed_docid);

void xdp_connection_track_name_owners (GDBusConnection *connection,
XdpPeerDiedCallback peer_died_cb);
Expand Down

0 comments on commit 27194b7

Please sign in to comment.