diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index 68b8988f0c4d..69db7c959392 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -146,7 +146,28 @@ static const char *kPrefJavaMIME = "plugin.java.mime"; static const char *kPrefUnloadPluginTimeoutSecs = "dom.ipc.plugins.unloadTimeoutSecs"; static const uint32_t kDefaultPluginUnloadingTimeout = 30; -static const char *kPluginRegistryVersion = "0.18"; +// Version of cached plugin info +// 0.01 first implementation +// 0.02 added caching of CanUnload to fix bug 105935 +// 0.03 changed name, description and mime desc from string to bytes, bug 108246 +// 0.04 added new mime entry point on Mac, bug 113464 +// 0.05 added new entry point check for the default plugin, bug 132430 +// 0.06 strip off suffixes in mime description strings, bug 53895 +// 0.07 changed nsIRegistry to flat file support for caching plugins info +// 0.08 mime entry point on MachO, bug 137535 +// 0.09 the file encoding is changed to UTF-8, bug 420285 +// 0.10 added plugin versions on appropriate platforms, bug 427743 +// 0.11 file name and full path fields now store expected values on all platforms, bug 488181 +// 0.12 force refresh due to quicktime pdf claim fix, bug 611197 +// 0.13 add architecture and list of invalid plugins, bug 616271 +// 0.14 force refresh due to locale comparison fix, bug 611296 +// 0.15 force refresh due to bug in reading Java plist MIME data, bug 638171 +// 0.16 version bump to avoid importing the plugin flags in newer versions +// 0.17 added flag on whether plugin is loaded from an XPI +// The current plugin registry version (and the maximum version we know how to read) +static const char *kPluginRegistryVersion = "0.17"; +// The minimum registry version we know how to read +static const char *kMinimumRegistryVersion = "0.9"; static const char kDirectoryServiceContractID[] = "@mozilla.org/file/directory_service;1"; @@ -2075,7 +2096,7 @@ nsPluginHost::AddPluginTag(nsPluginTag* aPluginTag) static bool PluginInfoIsFlash(const nsPluginInfo& info) { - if (strcmp(info.fName, "Shockwave Flash") != 0) { + if (strcmp(info.fDescription, "Shockwave Flash") != 0) { return false; } for (uint32_t i = 0; i < info.fVariantCount; ++i) { @@ -2969,6 +2990,10 @@ nsPluginHost::ReadPluginInfo() const long PLUGIN_REG_MIMETYPES_ARRAY_SIZE = 12; const long PLUGIN_REG_MAX_MIMETYPES = 1000; + // we need to import the legacy flags from the plugin registry once + const bool pluginStateImported = + Preferences::GetDefaultBool("plugin.importedState", false); + nsresult rv; nsCOMPtr directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID,&rv)); @@ -3060,67 +3085,128 @@ nsPluginHost::ReadPluginInfo() if (PL_strcmp(values[0], "Version")) return rv; - // If we're reading an old registry, ignore it - if (!strcmp(values[1], kPluginRegistryVersion)) { + // kPluginRegistryVersion + int32_t vdiff = mozilla::CompareVersions(values[1], kPluginRegistryVersion); + mozilla::Version version(values[1]); + // If this is a registry from some future version then don't attempt to read it + if (vdiff > 0) return rv; + // If this is a registry from before the minimum then don't attempt to read it + if (version < kMinimumRegistryVersion) + return rv; + + // Registry v0.10 and upwards includes the plugin version field + bool regHasVersion = (version >= "0.10"); + + // Registry v0.13 and upwards includes the architecture + if (version >= "0.13") { + char* archValues[6]; + + if (!reader.NextLine()) { + return rv; + } + + // ArchLiteral, Architecture + if (2 != reader.ParseLine(archValues, 2)) { + return rv; + } + + // ArchLiteral + if (PL_strcmp(archValues[0], "Arch")) { + return rv; + } + + nsCOMPtr runtime = do_GetService("@mozilla.org/xre/runtime;1"); + if (!runtime) { + return rv; + } + + nsAutoCString arch; + if (NS_FAILED(runtime->GetXPCOMABI(arch))) { + return rv; + } + + // If this is a registry from a different architecture then don't attempt to read it + if (PL_strcmp(archValues[1], arch.get())) { + return rv; + } } - char* archValues[6]; - if (!reader.NextLine()) { - return rv; - } + // Registry v0.13 and upwards includes the list of invalid plugins + const bool hasInvalidPlugins = (version >= "0.13"); - // ArchLiteral, Architecture - if (2 != reader.ParseLine(archValues, 2)) { - return rv; - } + // Registry v0.16 and upwards always have 0 for their plugin flags, prefs are used instead + const bool hasValidFlags = (version < "0.16"); - // ArchLiteral - if (PL_strcmp(archValues[0], "Arch")) { - return rv; - } + // Registry v0.17 and upwards store whether the plugin comes from an XPI. + const bool hasFromExtension = (version >= "0.17"); - nsCOMPtr runtime = do_GetService("@mozilla.org/xre/runtime;1"); - if (!runtime) { - return rv; - } - - nsAutoCString arch; - if (NS_FAILED(runtime->GetXPCOMABI(arch))) { - return rv; - } - - // If this is a registry from a different architecture then don't attempt to read it - if (PL_strcmp(archValues[1], arch.get())) { - return rv; - } +#if defined(XP_MACOSX) + const bool hasFullPathInFileNameField = false; +#else + const bool hasFullPathInFileNameField = (version < "0.11"); +#endif if (!ReadSectionHeader(reader, "PLUGINS")) return rv; while (reader.NextLine()) { - if (*reader.LinePtr() == '[') { + const char *filename; + const char *fullpath; + nsAutoCString derivedFileName; + + if (hasInvalidPlugins && *reader.LinePtr() == '[') { break; } - const char* filename = reader.LinePtr(); - if (!reader.NextLine()) - return rv; + if (hasFullPathInFileNameField) { + fullpath = reader.LinePtr(); + if (!reader.NextLine()) + return rv; + // try to derive a file name from the full path + if (fullpath) { + nsCOMPtr file = do_CreateInstance("@mozilla.org/file/local;1"); + file->InitWithNativePath(nsDependentCString(fullpath)); + file->GetNativeLeafName(derivedFileName); + filename = derivedFileName.get(); + } else { + filename = nullptr; + } - const char* fullpath = reader.LinePtr(); - if (!reader.NextLine()) - return rv; + // skip the next line, useless in this version + if (!reader.NextLine()) + return rv; + } else { + filename = reader.LinePtr(); + if (!reader.NextLine()) + return rv; + + fullpath = reader.LinePtr(); + if (!reader.NextLine()) + return rv; + } const char *version; - version = reader.LinePtr(); - if (!reader.NextLine()) + if (regHasVersion) { + version = reader.LinePtr(); + if (!reader.NextLine()) + return rv; + } else { + version = "0"; + } // lastModifiedTimeStamp|canUnload|tag.mFlag|fromExtension - if (4 != reader.ParseLine(values, 4)) + const int count = hasFromExtension ? 4 : 3; + if (reader.ParseLine(values, count) != count) return rv; - int64_t lastmod = nsCRT::atoll(values[0]); - bool fromExtension = atoi(values[3]); + // If this is an old plugin registry mark this plugin tag to be refreshed + int64_t lastmod = (vdiff == 0) ? nsCRT::atoll(values[0]) : -1; + uint32_t tagflag = atoi(values[2]); + bool fromExtension = false; + if (hasFromExtension) { + fromExtension = atoi(values[3]); + } if (!reader.NextLine()) return rv; @@ -3196,6 +3282,10 @@ nsPluginHost::ReadPluginInfo() delete [] heapalloced; // Import flags from registry into prefs for old registry versions + if (hasValidFlags && !pluginStateImported) { + tag->ImportFlagsToPrefs(tagflag); + } + MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC, ("LoadCachedPluginsInfo : Loading Cached plugininfo for %s\n", tag->FileName().get())); @@ -3209,29 +3299,34 @@ nsPluginHost::ReadPluginInfo() // On Android we always want to try to load a plugin again (Flash). Bug 935676. #ifndef MOZ_WIDGET_ANDROID - if (!ReadSectionHeader(reader, "INVALID")) { - return rv; - } - - while (reader.NextLine()) { - const char *fullpath = reader.LinePtr(); - if (!reader.NextLine()) { + if (hasInvalidPlugins) { + if (!ReadSectionHeader(reader, "INVALID")) { return rv; } - const char *lastModifiedTimeStamp = reader.LinePtr(); - int64_t lastmod = nsCRT::atoll(lastModifiedTimeStamp); + while (reader.NextLine()) { + const char *fullpath = reader.LinePtr(); + if (!reader.NextLine()) { + return rv; + } - RefPtr invalidTag = new nsInvalidPluginTag(fullpath, lastmod); + const char *lastModifiedTimeStamp = reader.LinePtr(); + int64_t lastmod = (vdiff == 0) ? nsCRT::atoll(lastModifiedTimeStamp) : -1; - invalidTag->mNext = mInvalidPlugins; - if (mInvalidPlugins) { - mInvalidPlugins->mPrev = invalidTag; + RefPtr invalidTag = new nsInvalidPluginTag(fullpath, lastmod); + + invalidTag->mNext = mInvalidPlugins; + if (mInvalidPlugins) { + mInvalidPlugins->mPrev = invalidTag; + } + mInvalidPlugins = invalidTag; } - mInvalidPlugins = invalidTag; } #endif + // flip the pref so we don't import the legacy flags again + Preferences::SetBool("plugin.importedState", true); + return NS_OK; } diff --git a/dom/plugins/base/nsPluginTags.cpp b/dom/plugins/base/nsPluginTags.cpp index ab75790240a2..53762f3e9906 100644 --- a/dom/plugins/base/nsPluginTags.cpp +++ b/dom/plugins/base/nsPluginTags.cpp @@ -757,6 +757,13 @@ nsPluginTag::GetNiceName(nsACString & aResult) return NS_OK; } +void nsPluginTag::ImportFlagsToPrefs(uint32_t flags) +{ + if (!(flags & NS_PLUGIN_FLAG_ENABLED)) { + SetPluginState(ePluginState_Disabled); + } +} + NS_IMETHODIMP nsPluginTag::GetBlocklistState(uint32_t *aResult) { diff --git a/dom/plugins/base/nsPluginTags.h b/dom/plugins/base/nsPluginTags.h index f1f03169b068..f74b4f49bf44 100644 --- a/dom/plugins/base/nsPluginTags.h +++ b/dom/plugins/base/nsPluginTags.h @@ -151,6 +151,9 @@ public: PluginState GetPluginState(); void SetPluginState(PluginState state); + // import legacy flags from plugin registry into the preferences + void ImportFlagsToPrefs(uint32_t flag); + bool HasSameNameAndMimes(const nsPluginTag *aPluginTag) const; const nsCString& GetNiceFileName() override;