diff -up thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp.moz-694870-backout thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp --- thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp.moz-694870-backout 2016-04-07 23:33:34.000000000 +0200 +++ thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp 2016-05-10 15:17:28.973860591 +0200 @@ -6,50 +6,95 @@ #include "nsGNOMERegistry.h" #include "nsString.h" #include "nsIComponentManager.h" +#include "nsIFile.h" #include "nsMIMEInfoUnix.h" #include "nsAutoPtr.h" +#include "nsIGConfService.h" +#include "nsIGnomeVFSService.h" #include "nsIGIOService.h" +#ifdef MOZ_WIDGET_GTK +#include +#include +#endif + /* static */ bool nsGNOMERegistry::HandlerExists(const char *aProtocolScheme) { nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); - if (!giovfs) { - return false; - } + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); + if (giovfs) { + nsCOMPtr app; + if (NS_FAILED(giovfs->GetAppForURIScheme(nsDependentCString(aProtocolScheme), + getter_AddRefs(app)))) + return false; + else + return true; + } else if (gconf) { + bool isEnabled; + nsAutoCString handler; + if (NS_FAILED(gconf->GetAppForProtocol(nsDependentCString(aProtocolScheme), &isEnabled, handler))) + return false; - nsCOMPtr app; - return NS_SUCCEEDED(giovfs->GetAppForURIScheme(nsDependentCString(aProtocolScheme), - getter_AddRefs(app))); + return isEnabled; + } + return false; } // XXX Check HandlerExists() before calling LoadURL. +// +// If there is not a registered handler for the protocol, gnome_url_show() +// falls back to using gnomevfs modules. See bug 389632. We don't want +// this fallback to happen as we are not sure of the safety of all gnomevfs +// modules and MIME-default applications. (gnomevfs should be handled in +// nsGnomeVFSProtocolHandler.) /* static */ nsresult nsGNOMERegistry::LoadURL(nsIURI *aURL) { nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); - if (!giovfs) { - return NS_ERROR_FAILURE; - } + if (giovfs) + return giovfs->ShowURI(aURL); + nsCOMPtr gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID); + if (gnomevfs) + return gnomevfs->ShowURI(aURL); - return giovfs->ShowURI(aURL); + return NS_ERROR_FAILURE; } /* static */ void nsGNOMERegistry::GetAppDescForScheme(const nsACString& aScheme, nsAString& aDesc) { + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); - if (!giovfs) + if (!gconf && !giovfs) return; nsAutoCString name; - nsCOMPtr app; - if (NS_FAILED(giovfs->GetAppForURIScheme(aScheme, getter_AddRefs(app)))) - return; - - app->GetName(name); + if (giovfs) { + nsCOMPtr app; + if (NS_FAILED(giovfs->GetAppForURIScheme(aScheme, getter_AddRefs(app)))) + return; + + app->GetName(name); + } else { + bool isEnabled; + if (NS_FAILED(gconf->GetAppForProtocol(aScheme, &isEnabled, name))) + return; + + if (!name.IsEmpty()) { + // Try to only provide the executable name, as it is much simpler than with the path and arguments + int32_t firstSpace = name.FindChar(' '); + if (firstSpace != kNotFound) { + name.Truncate(firstSpace); + int32_t lastSlash = name.RFindChar('/'); + if (lastSlash != kNotFound) { + name.Cut(0, lastSlash + 1); + } + } + } + } CopyUTF8toUTF16(name, aDesc); } @@ -60,15 +105,22 @@ nsGNOMERegistry::GetFromExtension(const { nsAutoCString mimeType; nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); - if (!giovfs) { - return nullptr; - } - - // Get the MIME type from the extension, then call GetFromType to - // fill in the MIMEInfo. - if (NS_FAILED(giovfs->GetMimeTypeFromExtension(aFileExt, mimeType)) || - mimeType.EqualsLiteral("application/octet-stream")) { - return nullptr; + if (giovfs) { + // Get the MIME type from the extension, then call GetFromType to + // fill in the MIMEInfo. + if (NS_FAILED(giovfs->GetMimeTypeFromExtension(aFileExt, mimeType)) || + mimeType.EqualsLiteral("application/octet-stream")) { + return nullptr; + } + } else { + /* Fallback to GnomeVFS */ + nsCOMPtr gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID); + if (!gnomevfs) + return nullptr; + + if (NS_FAILED(gnomevfs->GetMimeTypeFromExtension(aFileExt, mimeType)) || + mimeType.EqualsLiteral("application/octet-stream")) + return nullptr; } RefPtr mi = GetFromType(mimeType); @@ -89,17 +141,28 @@ nsGNOMERegistry::GetFromType(const nsACS nsAutoCString description; nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); - if (!giovfs) { - return nullptr; - } - - nsCOMPtr gioHandlerApp; - if (NS_FAILED(giovfs->GetAppForMimeType(aMIMEType, getter_AddRefs(gioHandlerApp))) || - !gioHandlerApp) { - return nullptr; + if (giovfs) { + nsCOMPtr gioHandlerApp; + if (NS_FAILED(giovfs->GetAppForMimeType(aMIMEType, getter_AddRefs(gioHandlerApp))) || + !gioHandlerApp) { + return nullptr; + } + gioHandlerApp->GetName(name); + giovfs->GetDescriptionForMimeType(aMIMEType, description); + } else { + /* Fallback to GnomeVFS*/ + nsCOMPtr gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID); + if (!gnomevfs) + return nullptr; + + nsCOMPtr gnomeHandlerApp; + if (NS_FAILED(gnomevfs->GetAppForMimeType(aMIMEType, getter_AddRefs(gnomeHandlerApp))) || + !gnomeHandlerApp) { + return nullptr; + } + gnomeHandlerApp->GetName(name); + gnomevfs->GetDescriptionForMimeType(aMIMEType, description); } - gioHandlerApp->GetName(name); - giovfs->GetDescriptionForMimeType(aMIMEType, description); mimeInfo->SetDefaultDescription(NS_ConvertUTF8toUTF16(name)); mimeInfo->SetPreferredAction(nsIMIMEInfo::useSystemDefault); diff -up thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp.moz-694870-backout thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp --- thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp.moz-694870-backout 2016-04-07 23:33:34.000000000 +0200 +++ thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp 2016-05-11 08:24:13.869018683 +0200 @@ -16,6 +16,7 @@ #include "nsIGIOService.h" #include "nsNetCID.h" #include "nsIIOService.h" +#include "nsIGnomeVFSService.h" #include "nsAutoPtr.h" #ifdef MOZ_ENABLE_DBUS #include "nsDBusHandlerApp.h" @@ -103,26 +104,51 @@ nsMIMEInfoUnix::LaunchDefaultWithFile(ns #endif nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); - if (!giovfs) { - return NS_ERROR_FAILURE; - } - - // nsGIOMimeApp->Launch wants a URI string instead of local file - nsresult rv; - nsCOMPtr ioservice = do_GetService(NS_IOSERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr uri; - rv = ioservice->NewFileURI(aFile, getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv, rv); nsAutoCString uriSpec; - uri->GetSpec(uriSpec); + if (giovfs) { + // nsGIOMimeApp->Launch wants a URI string instead of local file + nsresult rv; + nsCOMPtr ioservice = do_GetService(NS_IOSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr uri; + rv = ioservice->NewFileURI(aFile, getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, rv); + uri->GetSpec(uriSpec); + } + + nsCOMPtr gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID); + if (giovfs) { + nsCOMPtr app; + if (NS_SUCCEEDED(giovfs->GetAppForMimeType(mSchemeOrType, getter_AddRefs(app))) && app) + return app->Launch(uriSpec); + } else if (gnomevfs) { + /* Fallback to GnomeVFS */ + nsCOMPtr app; + if (NS_SUCCEEDED(gnomevfs->GetAppForMimeType(mSchemeOrType, getter_AddRefs(app))) && app) + return app->Launch(nativePath); + } + + // If we haven't got an app we try to get a valid one by searching for the + // extension mapped type + RefPtr mimeInfo = nsGNOMERegistry::GetFromExtension(nativePath); + if (mimeInfo) { + nsAutoCString type; + mimeInfo->GetType(type); + if (giovfs) { + nsCOMPtr app; + if (NS_SUCCEEDED(giovfs->GetAppForMimeType(type, getter_AddRefs(app))) && app) + return app->Launch(uriSpec); + } else if (gnomevfs) { + nsCOMPtr app; + if (NS_SUCCEEDED(gnomevfs->GetAppForMimeType(type, getter_AddRefs(app))) && app) + return app->Launch(nativePath); + } + } - nsCOMPtr app; - if (NS_FAILED(giovfs->GetAppForMimeType(mSchemeOrType, getter_AddRefs(app))) || !app) { + if (!mDefaultApplication) return NS_ERROR_FILE_NOT_FOUND; - } - return app->Launch(uriSpec); + return LaunchWithIProcess(mDefaultApplication, nativePath); } #if defined(MOZ_ENABLE_CONTENTACTION) diff -up thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp.moz-694870-backout thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp --- thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp.moz-694870-backout 2016-04-07 23:33:34.000000000 +0200 +++ thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp 2016-05-10 15:17:28.974860591 +0200 @@ -1150,7 +1150,7 @@ nsresult nsOSHelperAppService::OSProtoco #endif #ifdef MOZ_WIDGET_GTK - // Check the GNOME registry for a protocol handler + // Check the GConf registry for a protocol handler *aHandlerExists = nsGNOMERegistry::HandlerExists(aProtocolScheme); #endif @@ -1369,6 +1369,22 @@ nsOSHelperAppService::GetFromType(const NS_LossyConvertUTF16toASCII(handler).get(), NS_LossyConvertUTF16toASCII(mailcap_description).get())); +#ifdef MOZ_WIDGET_GTK + RefPtr gnomeInfo; + if (handler.IsEmpty()) { + // No useful data yet. Check the GNOME registry. Unfortunately, newer + // GNOME versions no longer have type-to-extension mappings, so we might + // get back a MIMEInfo without any extensions set. In that case we'll have + // to look in our mime.types files for the extensions. + LOG(("Looking in GNOME registry\n")); + gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType); + if (gnomeInfo && gnomeInfo->HasExtensions()) { + LOG(("Got MIMEInfo from GNOME registry, and it has extensions set\n")); + return gnomeInfo.forget(); + } + } +#endif + // Now look up our extensions nsAutoString extensions, mime_types_description; LookUpExtensionsAndDescription(majorType, @@ -1377,16 +1393,13 @@ nsOSHelperAppService::GetFromType(const mime_types_description); #ifdef MOZ_WIDGET_GTK - if (handler.IsEmpty()) { - RefPtr gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType); - if (gnomeInfo) { - LOG(("Got MIMEInfo from GNOME registry without extensions; setting them " - "to %s\n", NS_LossyConvertUTF16toASCII(extensions).get())); - - NS_ASSERTION(!gnomeInfo->HasExtensions(), "How'd that happen?"); - gnomeInfo->SetFileExtensions(NS_ConvertUTF16toUTF8(extensions)); - return gnomeInfo.forget(); - } + if (gnomeInfo) { + LOG(("Got MIMEInfo from GNOME registry without extensions; setting them " + "to %s\n", NS_LossyConvertUTF16toASCII(extensions).get())); + + NS_ASSERTION(!gnomeInfo->HasExtensions(), "How'd that happen?"); + gnomeInfo->SetFileExtensions(NS_ConvertUTF16toUTF8(extensions)); + return gnomeInfo.forget(); } #endif @@ -1513,6 +1526,9 @@ nsOSHelperAppService::GetProtocolHandler { NS_ASSERTION(!aScheme.IsEmpty(), "No scheme was specified!"); + // We must check that a registered handler exists so that gnome_url_show + // doesn't fallback to gnomevfs. + // See nsGNOMERegistry::LoadURL and bug 389632. nsresult rv = OSProtocolHandlerExists(nsPromiseFlatCString(aScheme).get(), found); if (NS_FAILED(rv))