On Mon, Jul 20, 2020 at 09:25:23AM +0200, Landry Breuil wrote:
> On Fri, Jul 17, 2020 at 07:16:32PM +0200, Caspar Schutijser wrote:
> > Hi,
> <snip>
> > > issues i havent thought about but it works for me using 79.0b3.
> > >
> > > To test, drop the attached patch in
> > > /usr/ports/www/mozilla-firefox/patches/patch-toolkit_system_gnome_nsGIOService_cpp
> > > and use G_MESSAGES_DEBUG=all firefox if you want to see the g_debug()
> > > msgs.
> >
> > I gave this a spin on my system. If I add the appropriate binaries to
> > unveil.main it seems to work fine, but if for instance
> > /usr/local/bin/evince is not present in unveil.main even though it is
> > the default for a PDF file, the following happens:
> >
> > (firefox:35438): GLib-GIO-CRITICAL **: 17:22:52.848:
> > g_app_info_get_executable: assertion 'G_IS_APP_INFO (appinfo)' failed
> > ** Message: 17:22:52.848: ShowURIForInput: spawning (null)
> > /tmp/mozilla_caspar0/somefile.pdf for
> > file:///tmp/mozilla_caspar0/somefile.pdf (content type application/pdf)
> > Exiting due to channel error.
> > Exiting due to channel error.
> > Exiting due to channel error.
> > Exiting due to channel error.
> > Segmentation fault (core dumped)
> >
> > I assume the problem is that g_app_info_get_executable() returned NULL.
>
> Ah, thanks for spotting this one, that's a case i probably havent tested
> :) will try to work on this again in the coming days..
Here's a new patch (to put under www/mozilla-firefox/patches ofc) that
should gracefully handle the g_app_info_get_executable() returning NULL
case - fwiw i plan to commit this partch (or a variation) along firefox
79 next week, more testing always welcome !
Landry
$OpenBSD$
Try to fix opening downloaded files with registered external mimetype handlers
after gio-launch-desktop removal in glib 2.64.
more or less replaces g_app_info_launch_uris() (which relies on /bin/sh in
2.64) calls by g_spawn_async() using a handler that should be previously
unveiled.
Index: toolkit/system/gnome/nsGIOService.cpp
--- toolkit/system/gnome/nsGIOService.cpp.orig
+++ toolkit/system/gnome/nsGIOService.cpp
@@ -243,10 +243,21 @@ nsGIOMimeApp::LaunchWithURI(nsIURI* aUri,
uris.data = const_cast<char*>(spec.get());
GError* error = nullptr;
- gboolean result = g_app_info_launch_uris(mApp, &uris, nullptr, &error);
+ gchar *path = g_filename_from_uri(spec.get(), NULL, NULL);
+ const gchar *bin = g_app_info_get_executable(mApp);
+ if (!bin) {
+ g_warning("no executable found for %s, maybe not unveiled ?",
g_app_info_get_name(mApp));
+ return NS_ERROR_FAILURE;
+ }
+ g_message("LaunchWithURI: spawning %s %s for %s", bin, path, spec.get());
+ const gchar * const argv[] = { bin, path, NULL };
+ GSpawnFlags flags = static_cast<GSpawnFlags>(G_SPAWN_SEARCH_PATH |
+ G_SPAWN_DO_NOT_REAP_CHILD);
+ gboolean result = g_spawn_async( NULL, (char**) argv, NULL, flags, NULL,
NULL, NULL, &error);
+
if (!result) {
- g_warning("Cannot launch application: %s", error->message);
+ g_warning("Cannot launch application %s with arg %s: %s", bin, path,
error->message);
g_error_free(error);
return NS_ERROR_FAILURE;
}
@@ -501,20 +512,15 @@ nsGIOService::GetAppForMimeType(const nsACString& aMim
return NS_ERROR_NOT_AVAILABLE;
}
-#if defined(__OpenBSD__) && defined(MOZ_SANDBOX)
- // g_app_info_get_default_for_type will fail on OpenBSD's veiled filesystem
- // since we most likely don't have direct access to the binaries that are
- // registered as defaults for this type. Fake it up by just executing
- // xdg-open via gio-launch-desktop (which we do have access to) and letting
- // it figure out which program to execute for this MIME type
- GAppInfo* app_info = g_app_info_create_from_commandline(
- "/usr/local/bin/xdg-open",
- nsPrintfCString("System default for %s", content_type).get(),
- G_APP_INFO_CREATE_NONE, NULL);
-#else
GAppInfo* app_info = g_app_info_get_default_for_type(content_type, false);
-#endif
if (app_info) {
+ char *t;
+ t = g_find_program_in_path(g_app_info_get_executable(app_info));
+ if (t != NULL) {
+ g_debug("%s is registered as handler for %s, binary available as %s",
g_app_info_get_executable(app_info), content_type, t);
+ } else {
+ g_warning("%s is registered as handler for %s but not available in PATH
(missing unveil ?)", g_app_info_get_executable(app_info), content_type);
+ }
nsGIOMimeApp* mozApp = new nsGIOMimeApp(app_info);
NS_ENSURE_TRUE(mozApp, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*aApp = mozApp);
@@ -551,7 +557,24 @@ nsGIOService::ShowURI(nsIURI* aURI) {
nsresult rv = aURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
GError* error = nullptr;
- if (!g_app_info_launch_default_for_uri(spec.get(), nullptr, &error)) {
+ gboolean result_uncertain;
+ gchar *path = g_filename_from_uri(spec.get(), NULL, NULL);
+ gchar *content_type = g_content_type_guess(path, NULL, 0, &result_uncertain);
+ if (content_type != NULL && !result_uncertain) {
+ GAppInfo* app_info = g_app_info_get_default_for_type(content_type, false);
+ const gchar *bin = g_app_info_get_executable(app_info);
+ if (!bin) {
+ g_warning("no executable found for %s, maybe not unveiled ?",
g_app_info_get_name(app_info));
+ return NS_ERROR_FAILURE;
+ }
+ g_message("ShowURI: spawning %s %s for %s (content type %s)", bin, path,
spec.get(), content_type);
+ const gchar * const argv[] = { bin, path, NULL };
+ GSpawnFlags flags = static_cast<GSpawnFlags>(G_SPAWN_SEARCH_PATH |
+ G_SPAWN_DO_NOT_REAP_CHILD);
+ g_spawn_async( NULL, (char**) argv, NULL, flags, NULL, NULL, NULL, &error);
+ }
+ g_free(content_type);
+ if (error) {
g_warning("Could not launch default application for URI: %s",
error->message);
g_error_free(error);
@@ -567,7 +590,22 @@ nsGIOService::ShowURIForInput(const nsACString& aUri)
nsresult rv = NS_ERROR_FAILURE;
GError* error = nullptr;
- g_app_info_launch_default_for_uri(spec, nullptr, &error);
+ gboolean result_uncertain;
+ gchar *path = g_filename_from_uri(spec, NULL, NULL);
+ gchar *content_type = g_content_type_guess(path, NULL, 0, &result_uncertain);
+ if (content_type != NULL && !result_uncertain) {
+ GAppInfo* app_info = g_app_info_get_default_for_type(content_type, false);
+ const gchar *bin = g_app_info_get_executable(app_info);
+ if (!bin) {
+ g_warning("no executable found for %s, maybe not unveiled ?",
g_app_info_get_name(app_info));
+ return NS_ERROR_FAILURE;
+ }
+ g_message("ShowURIForInput: spawning %s %s for %s (content type %s)", bin,
path, spec, content_type);
+ const gchar * const argv[] = { bin, path, NULL };
+ GSpawnFlags flags = static_cast<GSpawnFlags>(G_SPAWN_SEARCH_PATH |
+ G_SPAWN_DO_NOT_REAP_CHILD);
+ g_spawn_async( NULL, (char**) argv, NULL, flags, NULL, NULL, NULL, &error);
+ }
if (error) {
g_warning("Cannot launch default application: %s", error->message);
g_error_free(error);
@@ -576,6 +614,7 @@ nsGIOService::ShowURIForInput(const nsACString& aUri)
}
g_object_unref(file);
g_free(spec);
+ g_free(content_type);
return rv;
}