blob: afc3db758cbc48e36a8ae50890c4227c37329b39 [file] [log] [blame]
/*
Copyright (C) 2000 Harri Porten (porten@kde.org)
Copyright (C) 2000 Daniel Molkentin (molkentin@kde.org)
Copyright (C) 2000 Stefan Schimanski (schimmi@kde.org)
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2015 Apple Inc. All Rights Reserved.
Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "PluginData.h"
#include "Document.h"
#include "Frame.h"
#include "LocalizedStrings.h"
#include "Page.h"
#include "PluginInfoProvider.h"
namespace WebCore {
PluginData::PluginData(Page& page)
: m_page(page)
{
initPlugins();
}
void PluginData::initPlugins()
{
ASSERT(m_plugins.isEmpty());
m_plugins = m_page.pluginInfoProvider().pluginInfo(m_page, m_supportedPluginIdentifiers);
}
const Vector<PluginInfo>& PluginData::webVisiblePlugins() const
{
auto documentURL = m_page.mainFrame().document() ? m_page.mainFrame().document()->url() : URL { };
if (!documentURL.isNull() && !protocolHostAndPortAreEqual(m_cachedVisiblePlugins.pageURL, documentURL)) {
m_cachedVisiblePlugins.pageURL = WTFMove(documentURL);
m_cachedVisiblePlugins.pluginList = std::nullopt;
}
if (!m_cachedVisiblePlugins.pluginList)
m_cachedVisiblePlugins.pluginList = m_page.pluginInfoProvider().webVisiblePluginInfo(m_page, m_cachedVisiblePlugins.pageURL);
return *m_cachedVisiblePlugins.pluginList;
}
#if PLATFORM(COCOA)
static inline bool isBuiltInPDFPlugIn(const PluginInfo& plugin)
{
return equalLettersIgnoringASCIICase(plugin.bundleIdentifier, "com.apple.webkit.builtinpdfplugin"_s);
}
#else
static inline bool isBuiltInPDFPlugIn(const PluginInfo&)
{
return false;
}
#endif
static bool shouldBePubliclyVisible(const PluginInfo& plugin)
{
// We can greatly reduce fingerprinting opportunities by only advertising plug-ins
// that are widely needed for general website compatibility. Since many users
// will have these plug-ins, we are not revealing much user-specific information.
//
// Web compatibility data indicate that Flash, QuickTime, Java, and PDF support
// are frequently accessed through the bad practice of iterating over the contents
// of the navigator.plugins list. Luckily, these plug-ins happen to be the least
// user-specific.
return plugin.name.containsIgnoringASCIICase("Shockwave"_s)
|| plugin.name.containsIgnoringASCIICase("QuickTime"_s)
|| plugin.name.containsIgnoringASCIICase("Java"_s)
|| isBuiltInPDFPlugIn(plugin);
}
std::pair<Vector<PluginInfo>, Vector<PluginInfo>> PluginData::publiclyVisiblePluginsAndAdditionalWebVisiblePlugins() const
{
auto plugins = webVisiblePlugins();
if (m_page.showAllPlugins())
return { plugins, { } };
Vector<PluginInfo> additionalWebVisiblePlugins;
plugins.removeAllMatching([&](auto& plugin) {
if (!shouldBePubliclyVisible(plugin)) {
additionalWebVisiblePlugins.append(plugin);
return true;
}
return false;
});
return { plugins, additionalWebVisiblePlugins };
}
Vector<MimeClassInfo> PluginData::webVisibleMimeTypes() const
{
Vector<MimeClassInfo> result;
for (auto& plugin : webVisiblePlugins())
result.appendVector(plugin.mimes);
return result;
}
static bool supportsMimeTypeForPlugins(const String& mimeType, const PluginData::AllowedPluginTypes allowedPluginTypes, const Vector<PluginInfo>& plugins)
{
for (auto& plugin : plugins) {
for (auto& type : plugin.mimes) {
if (type.type == mimeType && (allowedPluginTypes == PluginData::AllPlugins || plugin.isApplicationPlugin))
return true;
}
}
return false;
}
bool PluginData::supportsMimeType(const String& mimeType, const AllowedPluginTypes allowedPluginTypes) const
{
return supportsMimeTypeForPlugins(mimeType, allowedPluginTypes, plugins());
}
bool PluginData::supportsWebVisibleMimeType(const String& mimeType, const AllowedPluginTypes allowedPluginTypes) const
{
return supportsMimeTypeForPlugins(mimeType, allowedPluginTypes, webVisiblePlugins());
}
bool PluginData::supportsWebVisibleMimeTypeForURL(const String& mimeType, const AllowedPluginTypes allowedPluginTypes, const URL& url) const
{
if (!protocolHostAndPortAreEqual(m_cachedVisiblePlugins.pageURL, url))
m_cachedVisiblePlugins = { url, m_page.pluginInfoProvider().webVisiblePluginInfo(m_page, url) };
if (!m_cachedVisiblePlugins.pluginList)
return false;
return supportsMimeTypeForPlugins(mimeType, allowedPluginTypes, *m_cachedVisiblePlugins.pluginList);
}
String PluginData::pluginFileForWebVisibleMimeType(const String& mimeType) const
{
for (auto& plugin : webVisiblePlugins()) {
for (auto& type : plugin.mimes) {
if (type.type == mimeType)
return plugin.file;
}
}
return { };
}
} // namespace WebCore