Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XdpAppInfo refactoring, Part 3 #1411

Merged
merged 3 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 11 additions & 17 deletions src/dynamic-launcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ get_launcher_data_and_revoke_token (const char *token)
}

static gboolean
validate_desktop_file_id (const char *app_id,
validate_desktop_file_id (XdpAppInfo *app_info,
const char *desktop_file_id,
GError **error)
{
const char *after_app_id;
g_autofree char *no_dot_desktop = NULL;

if (!g_str_has_suffix (desktop_file_id, ".desktop"))
{
Expand All @@ -123,16 +123,14 @@ validate_desktop_file_id (const char *app_id,
return FALSE;
}

if (app_id == NULL || *app_id == '\0')
return TRUE;
no_dot_desktop = g_strndup (desktop_file_id,
strlen(desktop_file_id) - strlen (".desktop"));

after_app_id = desktop_file_id + strlen (app_id);
if (!g_str_has_prefix (desktop_file_id, app_id) || *after_app_id != '.')
if (!xdp_app_info_is_valid_sub_app_id (app_info, no_dot_desktop))
{
g_set_error (error,
XDG_DESKTOP_PORTAL_ERROR, XDG_DESKTOP_PORTAL_ERROR_INVALID_ARGUMENT,
_("Desktop file id missing app id prefix '%s.': %s"),
app_id, desktop_file_id);
_("Desktop file id is not valid"));
return FALSE;
}

Expand Down Expand Up @@ -372,7 +370,7 @@ handle_install (XdpDbusDynamicLauncher *object,
g_assert (icon_extension != NULL && icon_extension[0] != '\0');
g_assert (icon_size != NULL && icon_size[0] != '\0');

if (!validate_desktop_file_id (app_id, arg_desktop_file_id, &error))
if (!validate_desktop_file_id (call->app_info, arg_desktop_file_id, &error))
{
g_dbus_method_invocation_return_gerror (invocation, error);
return G_DBUS_METHOD_INVOCATION_HANDLED;
Expand Down Expand Up @@ -754,7 +752,6 @@ handle_uninstall (XdpDbusDynamicLauncher *object,
GVariant *arg_options)
{
Call *call = call_from_invocation (invocation);
const char *app_id = xdp_app_info_get_id (call->app_info);
g_autoptr(GError) error = NULL;
g_autoptr(GError) desktop_file_error = NULL;
g_autofree char *icon_dir = NULL;
Expand All @@ -765,7 +762,7 @@ handle_uninstall (XdpDbusDynamicLauncher *object,
g_autoptr(GFile) link_file = NULL;
g_autoptr(GKeyFile) desktop_keyfile = NULL;

if (!validate_desktop_file_id (app_id, arg_desktop_file_id, &error))
if (!validate_desktop_file_id (call->app_info, arg_desktop_file_id, &error))
{
g_dbus_method_invocation_return_gerror (invocation, error);
return G_DBUS_METHOD_INVOCATION_HANDLED;
Expand Down Expand Up @@ -813,14 +810,13 @@ handle_get_desktop_entry (XdpDbusDynamicLauncher *object,
const gchar *arg_desktop_file_id)
{
Call *call = call_from_invocation (invocation);
const char *app_id = xdp_app_info_get_id (call->app_info);
g_autoptr(GError) error = NULL;
g_autofree char *desktop_dir = NULL;
g_autofree char *contents = NULL;
g_autofree char *desktop_path = NULL;
gsize length;

if (!validate_desktop_file_id (app_id, arg_desktop_file_id, &error))
if (!validate_desktop_file_id (call->app_info, arg_desktop_file_id, &error))
goto error;

desktop_dir = g_build_filename (g_get_user_data_dir (), XDG_PORTAL_APPLICATIONS_DIR, NULL);
Expand Down Expand Up @@ -851,7 +847,6 @@ handle_get_icon (XdpDbusDynamicLauncher *object,
const gchar *arg_desktop_file_id)
{
Call *call = call_from_invocation (invocation);
const char *app_id = xdp_app_info_get_id (call->app_info);
g_autoptr(GError) error = NULL;
g_autofree char *desktop_dir = NULL;
g_autofree char *contents = NULL;
Expand All @@ -869,7 +864,7 @@ handle_get_icon (XdpDbusDynamicLauncher *object,
const gchar *icon_format = NULL;
int icon_size = 0;

if (!validate_desktop_file_id (app_id, arg_desktop_file_id, &error))
if (!validate_desktop_file_id (call->app_info, arg_desktop_file_id, &error))
goto error;

desktop_dir = g_build_filename (g_get_user_data_dir (), XDG_PORTAL_APPLICATIONS_DIR, NULL);
Expand Down Expand Up @@ -966,7 +961,6 @@ handle_launch (XdpDbusDynamicLauncher *object,
GVariant *arg_options)
{
Call *call = call_from_invocation (invocation);
const char *app_id = xdp_app_info_get_id (call->app_info);
g_autoptr(GError) error = NULL;
g_autofree char *desktop_dir = NULL;
g_autofree char *desktop_path = NULL;
Expand All @@ -975,7 +969,7 @@ handle_launch (XdpDbusDynamicLauncher *object,
GAppLaunchContext *launch_context = NULL;
g_autoptr(GDesktopAppInfo) app_info = NULL;

if (!validate_desktop_file_id (app_id, arg_desktop_file_id, &error))
if (!validate_desktop_file_id (call->app_info, arg_desktop_file_id, &error))
goto error;

desktop_dir = g_build_filename (g_get_user_data_dir (), XDG_PORTAL_APPLICATIONS_DIR, NULL);
Expand Down
128 changes: 128 additions & 0 deletions src/xdp-app-info-flatpak.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,134 @@ struct _XdpAppInfoFlatpak

G_DEFINE_FINAL_TYPE (XdpAppInfoFlatpak, xdp_app_info_flatpak, XDP_TYPE_APP_INFO)

static gboolean
is_valid_initial_name_character (gint c, gboolean allow_dash)
{
return
(c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') ||
(c == '_') || (allow_dash && c == '-');
}

static gboolean
is_valid_name_character (gint c, gboolean allow_dash)
{
return
is_valid_initial_name_character (c, allow_dash) ||
(c >= '0' && c <= '9');
}

static const char *
find_last_char (const char *str, gsize len, int c)
{
const char *p = str + len - 1;
while (p >= str)
{
if (*p == c)
return p;
p--;
}
return NULL;
}

/**
* flatpak_is_valid_name:
* @string: The string to check
*
* Checks if @string is a valid application name.
*
* App names are composed of 3 or more elements separated by a period
* ('.') character. All elements must contain at least one character.
*
* Each element must only contain the ASCII characters
* "[A-Z][a-z][0-9]_-". Elements may not begin with a digit.
* Additionally "-" is only allowed in the last element.
*
* App names must not begin with a '.' (period) character.
*
* App names must not exceed 255 characters in length.
*
* The above means that any app name is also a valid DBus well known
* bus name, but not all DBus names are valid app names. The difference are:
* 1) DBus name elements may contain '-' in the non-last element.
* 2) DBus names require only two elements
*
* Returns: %TRUE if valid, %FALSE otherwise.
*/
static gboolean
flatpak_is_valid_name (const char *string)
{
gssize len;
const gchar *s;
const gchar *end;
const gchar *last_dot;
int dot_count;
gboolean last_element;

g_return_val_if_fail (string != NULL, FALSE);

len = strlen (string);
if (G_UNLIKELY (len == 0))
return FALSE;

if (G_UNLIKELY (len > 255))
return FALSE;

end = string + len;

last_dot = find_last_char (string, len, '.');
last_element = FALSE;

s = string;
if (G_UNLIKELY (*s == '.'))
return FALSE;

if (G_UNLIKELY (!is_valid_initial_name_character (*s, last_element)))
return FALSE;

s += 1;
dot_count = 0;
while (s != end)
{
if (*s == '.')
{
if (s == last_dot)
last_element = TRUE;
s += 1;
if (G_UNLIKELY (s == end))
return FALSE;
if (!is_valid_initial_name_character (*s, last_element))
return FALSE;
dot_count++;
}
else if (G_UNLIKELY (!is_valid_name_character (*s, last_element)))
return FALSE;
s += 1;
}

if (G_UNLIKELY (dot_count < 2))
return FALSE;

return TRUE;
}

gboolean
xdp_app_info_flatpak_is_valid_sub_app_id (XdpAppInfo *app_info,
const char *sub_app_id)
{
const char *app_id = xdp_app_info_get_id (app_info);

g_assert (app_id);

if (!g_str_has_prefix (sub_app_id, app_id))
return FALSE;

if (sub_app_id[strlen (app_id)] != '.')
return FALSE;

return flatpak_is_valid_name (sub_app_id);
}

static char *
xdp_app_info_flatpak_remap_path (XdpAppInfo *app_info,
const char *path)
Expand Down
7 changes: 7 additions & 0 deletions src/xdp-app-info-host.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ struct _XdpAppInfoHost

G_DEFINE_FINAL_TYPE (XdpAppInfoHost, xdp_app_info_host, XDP_TYPE_APP_INFO)

gboolean
xdp_app_info_host_is_valid_sub_app_id (XdpAppInfo *app_info,
const char *sub_app_id)
{
return TRUE;
}

gboolean
xdp_app_info_host_validate_autostart (XdpAppInfo *app_info,
GKeyFile *keyfile,
Expand Down
3 changes: 3 additions & 0 deletions src/xdp-app-info-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ struct _XdpAppInfoClass
{
GObjectClass parent_class;

gboolean (*is_valid_sub_app_id) (XdpAppInfo *app_info,
const char *sub_app_id);

char * (*remap_path) (XdpAppInfo *app_info,
const char *path);

Expand Down
24 changes: 18 additions & 6 deletions src/xdp-app-info.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,17 @@ xdp_app_info_get_gappinfo (XdpAppInfo *app_info)
return priv->gappinfo;
}

gboolean
xdp_app_info_is_valid_sub_app_id (XdpAppInfo *app_info,
const char *sub_app_id)
{
if (!XDP_APP_INFO_GET_CLASS (app_info)->is_valid_sub_app_id)
return FALSE;

return XDP_APP_INFO_GET_CLASS (app_info)->is_valid_sub_app_id (app_info,
sub_app_id);
}

gboolean
xdp_app_info_has_network (XdpAppInfo *app_info)
{
Expand Down Expand Up @@ -717,6 +728,7 @@ xdp_connection_lookup_app_info_sync (GDBusConnection *connection,
g_autoptr(XdpAppInfo) app_info = NULL;
xdp_autofd int pidfd = -1;
uint32_t pid;
const char *test_override_app_id;
g_autoptr(GError) local_error = NULL;

app_info = cache_lookup_app_info_by_sender (sender);
Expand All @@ -726,7 +738,12 @@ xdp_connection_lookup_app_info_sync (GDBusConnection *connection,
if (!xdp_connection_get_pidfd (connection, sender, cancellable, &pidfd, &pid, error))
return NULL;

app_info = xdp_app_info_flatpak_new (pid, pidfd, &local_error);
test_override_app_id = g_getenv ("XDG_DESKTOP_PORTAL_TEST_APP_ID");
if (test_override_app_id)
app_info = xdp_app_info_test_new (test_override_app_id);

if (app_info == NULL)
app_info = xdp_app_info_flatpak_new (pid, pidfd, &local_error);

if (!app_info && !g_error_matches (local_error, XDP_APP_INFO_ERROR,
XDP_APP_INFO_ERROR_WRONG_APP_KIND))
Expand Down Expand Up @@ -766,11 +783,6 @@ xdp_invocation_lookup_app_info_sync (GDBusMethodInvocation *invocation,
{
GDBusConnection *connection = g_dbus_method_invocation_get_connection (invocation);
const gchar *sender = g_dbus_method_invocation_get_sender (invocation);
const char *test_override_app_id;

test_override_app_id = g_getenv ("XDG_DESKTOP_PORTAL_TEST_APP_ID");
if (test_override_app_id)
return xdp_app_info_test_new (test_override_app_id);

return xdp_connection_lookup_app_info_sync (connection, sender, cancellable, error);
}
3 changes: 3 additions & 0 deletions src/xdp-app-info.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ const char * xdp_app_info_get_instance (XdpAppInfo *app_info);

GAppInfo * xdp_app_info_get_gappinfo (XdpAppInfo *app_info);

gboolean xdp_app_info_is_valid_sub_app_id (XdpAppInfo *app_info,
const char *sub_app_id);

gboolean xdp_app_info_has_network (XdpAppInfo *app_info);

gboolean xdp_app_info_get_pidns (XdpAppInfo *app_info,
Expand Down
Loading