| diff -up thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp.moz-694870-backout thunderbird-45.0/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp |
| |
| |
| @@ -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 <glib.h> |
| +#include <glib-object.h> |
| +#endif |
| + |
| /* static */ bool |
| nsGNOMERegistry::HandlerExists(const char *aProtocolScheme) |
| { |
| nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); |
| - if (!giovfs) { |
| - return false; |
| - } |
| + nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); |
| + if (giovfs) { |
| + nsCOMPtr<nsIGIOMimeApp> 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<nsIGIOMimeApp> 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<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); |
| - if (!giovfs) { |
| - return NS_ERROR_FAILURE; |
| - } |
| + if (giovfs) |
| + return giovfs->ShowURI(aURL); |
| + nsCOMPtr<nsIGnomeVFSService> 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<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); |
| nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); |
| - if (!giovfs) |
| + if (!gconf && !giovfs) |
| return; |
| |
| nsAutoCString name; |
| - nsCOMPtr<nsIGIOMimeApp> app; |
| - if (NS_FAILED(giovfs->GetAppForURIScheme(aScheme, getter_AddRefs(app)))) |
| - return; |
| - |
| - app->GetName(name); |
| + if (giovfs) { |
| + nsCOMPtr<nsIGIOMimeApp> 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<nsIGIOService> 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<nsIGnomeVFSService> 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<nsMIMEInfoBase> mi = GetFromType(mimeType); |
| @@ -89,17 +141,28 @@ nsGNOMERegistry::GetFromType(const nsACS |
| nsAutoCString description; |
| |
| nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); |
| - if (!giovfs) { |
| - return nullptr; |
| - } |
| - |
| - nsCOMPtr<nsIGIOMimeApp> gioHandlerApp; |
| - if (NS_FAILED(giovfs->GetAppForMimeType(aMIMEType, getter_AddRefs(gioHandlerApp))) || |
| - !gioHandlerApp) { |
| - return nullptr; |
| + if (giovfs) { |
| + nsCOMPtr<nsIGIOMimeApp> 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<nsIGnomeVFSService> gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID); |
| + if (!gnomevfs) |
| + return nullptr; |
| + |
| + nsCOMPtr<nsIGnomeVFSMimeApp> 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 |
| |
| |
| @@ -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<nsIGIOService> 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<nsIIOService> ioservice = do_GetService(NS_IOSERVICE_CONTRACTID, &rv); |
| - NS_ENSURE_SUCCESS(rv, rv); |
| - nsCOMPtr<nsIURI> 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<nsIIOService> ioservice = do_GetService(NS_IOSERVICE_CONTRACTID, &rv); |
| + NS_ENSURE_SUCCESS(rv, rv); |
| + nsCOMPtr<nsIURI> uri; |
| + rv = ioservice->NewFileURI(aFile, getter_AddRefs(uri)); |
| + NS_ENSURE_SUCCESS(rv, rv); |
| + uri->GetSpec(uriSpec); |
| + } |
| + |
| + nsCOMPtr<nsIGnomeVFSService> gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID); |
| + if (giovfs) { |
| + nsCOMPtr<nsIGIOMimeApp> app; |
| + if (NS_SUCCEEDED(giovfs->GetAppForMimeType(mSchemeOrType, getter_AddRefs(app))) && app) |
| + return app->Launch(uriSpec); |
| + } else if (gnomevfs) { |
| + /* Fallback to GnomeVFS */ |
| + nsCOMPtr<nsIGnomeVFSMimeApp> 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<nsMIMEInfoBase> mimeInfo = nsGNOMERegistry::GetFromExtension(nativePath); |
| + if (mimeInfo) { |
| + nsAutoCString type; |
| + mimeInfo->GetType(type); |
| + if (giovfs) { |
| + nsCOMPtr<nsIGIOMimeApp> app; |
| + if (NS_SUCCEEDED(giovfs->GetAppForMimeType(type, getter_AddRefs(app))) && app) |
| + return app->Launch(uriSpec); |
| + } else if (gnomevfs) { |
| + nsCOMPtr<nsIGnomeVFSMimeApp> app; |
| + if (NS_SUCCEEDED(gnomevfs->GetAppForMimeType(type, getter_AddRefs(app))) && app) |
| + return app->Launch(nativePath); |
| + } |
| + } |
| |
| - nsCOMPtr<nsIGIOMimeApp> 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 |
| |
| |
| @@ -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<nsMIMEInfoBase> 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<nsMIMEInfoBase> 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)) |