2001-09-28 20:14:13 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 11:12:37 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
1998-07-28 02:07:25 +00:00
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
/* nsPluginHost.cpp - top-level plugin management code */
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2001-08-14 07:59:59 +00:00
|
|
|
#include "nscore.h"
|
2009-07-02 05:48:08 +00:00
|
|
|
#include "nsPluginHost.h"
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2013-03-06 18:06:24 +00:00
|
|
|
#include <cstdlib>
|
1998-07-28 02:07:25 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include "prio.h"
|
|
|
|
#include "prmem.h"
|
2008-09-15 12:45:01 +00:00
|
|
|
#include "nsNPAPIPlugin.h"
|
|
|
|
#include "nsNPAPIPluginStreamListener.h"
|
2009-06-29 18:53:52 +00:00
|
|
|
#include "nsNPAPIPluginInstance.h"
|
2012-06-05 13:58:39 +00:00
|
|
|
#include "nsPluginInstanceOwner.h"
|
|
|
|
#include "nsObjectLoadingContent.h"
|
2004-10-11 04:01:49 +00:00
|
|
|
#include "nsIHTTPHeaderListener.h"
|
|
|
|
#include "nsIHttpHeaderVisitor.h"
|
2001-03-12 02:07:15 +00:00
|
|
|
#include "nsIObserverService.h"
|
2001-05-11 21:05:08 +00:00
|
|
|
#include "nsIHttpProtocolHandler.h"
|
|
|
|
#include "nsIHttpChannel.h"
|
2001-09-05 03:52:26 +00:00
|
|
|
#include "nsIUploadChannel.h"
|
2001-05-22 22:32:45 +00:00
|
|
|
#include "nsIByteRangeRequest.h"
|
1998-08-05 04:21:36 +00:00
|
|
|
#include "nsIStreamListener.h"
|
|
|
|
#include "nsIInputStream.h"
|
1999-03-11 22:48:58 +00:00
|
|
|
#include "nsIOutputStream.h"
|
1999-06-18 17:34:08 +00:00
|
|
|
#include "nsIURL.h"
|
2012-12-12 07:56:25 +00:00
|
|
|
#include "nsTArray.h"
|
2001-09-29 08:28:41 +00:00
|
|
|
#include "nsReadableUtils.h"
|
2015-01-21 20:13:00 +00:00
|
|
|
#include "nsProtocolProxyService.h"
|
2001-05-22 22:32:45 +00:00
|
|
|
#include "nsIStreamConverterService.h"
|
2000-08-19 05:44:34 +00:00
|
|
|
#include "nsIFile.h"
|
2012-04-10 15:56:49 +00:00
|
|
|
#if defined(XP_MACOSX)
|
|
|
|
#include "nsILocalFileMac.h"
|
|
|
|
#endif
|
2003-03-15 01:04:32 +00:00
|
|
|
#include "nsISeekableStream.h"
|
1999-11-30 04:50:42 +00:00
|
|
|
#include "nsNetUtil.h"
|
2015-07-07 02:17:00 +00:00
|
|
|
#include "nsIFileStreams.h"
|
|
|
|
#include "nsISimpleEnumerator.h"
|
|
|
|
#include "nsIStringStream.h"
|
1999-07-07 08:08:40 +00:00
|
|
|
#include "nsIProgressEventSink.h"
|
1999-07-09 21:18:47 +00:00
|
|
|
#include "nsIDocument.h"
|
2001-08-16 02:59:03 +00:00
|
|
|
#include "nsPluginLogging.h"
|
2007-03-02 08:38:31 +00:00
|
|
|
#include "nsIScriptChannel.h"
|
2008-11-02 12:13:48 +00:00
|
|
|
#include "nsIBlocklistService.h"
|
2008-11-02 15:49:03 +00:00
|
|
|
#include "nsVersionComparator.h"
|
2010-01-13 16:42:41 +00:00
|
|
|
#include "nsIObjectLoadingContent.h"
|
2010-02-10 01:05:31 +00:00
|
|
|
#include "nsIWritablePropertyBag2.h"
|
2012-06-29 22:28:45 +00:00
|
|
|
#include "nsICategoryManager.h"
|
2010-07-13 20:48:00 +00:00
|
|
|
#include "nsPluginStreamListenerPeer.h"
|
2014-10-29 15:05:36 +00:00
|
|
|
#include "mozilla/dom/ContentChild.h"
|
2015-05-20 13:30:05 +00:00
|
|
|
#include "mozilla/dom/FakePluginTagInitBinding.h"
|
2014-07-10 06:56:37 +00:00
|
|
|
#include "mozilla/LoadInfo.h"
|
2014-12-29 23:12:40 +00:00
|
|
|
#include "mozilla/plugins/PluginAsyncSurrogate.h"
|
2014-10-29 15:05:36 +00:00
|
|
|
#include "mozilla/plugins/PluginBridge.h"
|
|
|
|
#include "mozilla/plugins/PluginTypes.h"
|
2012-04-04 04:09:20 +00:00
|
|
|
#include "mozilla/Preferences.h"
|
2001-04-17 10:47:22 +00:00
|
|
|
|
2000-07-22 01:34:13 +00:00
|
|
|
#include "nsEnumeratorUtils.h"
|
2002-09-03 23:36:13 +00:00
|
|
|
#include "nsXPCOM.h"
|
2003-02-27 13:51:55 +00:00
|
|
|
#include "nsXPCOMCID.h"
|
2001-05-22 22:32:45 +00:00
|
|
|
#include "nsISupportsPrimitives.h"
|
2009-02-09 18:48:06 +00:00
|
|
|
|
2011-10-07 17:46:02 +00:00
|
|
|
#include "nsXULAppAPI.h"
|
2010-12-09 22:28:15 +00:00
|
|
|
#include "nsIXULRuntime.h"
|
|
|
|
|
2000-06-20 21:04:52 +00:00
|
|
|
// for the dialog
|
2001-04-07 03:33:56 +00:00
|
|
|
#include "nsIWindowWatcher.h"
|
2013-08-22 06:30:55 +00:00
|
|
|
#include "nsIDOMElement.h"
|
2013-02-11 16:28:08 +00:00
|
|
|
#include "nsIDOMWindow.h"
|
2000-07-20 22:53:32 +00:00
|
|
|
|
2003-10-30 02:59:31 +00:00
|
|
|
#include "nsNetCID.h"
|
2016-08-15 06:43:21 +00:00
|
|
|
#include "mozilla/Sprintf.h"
|
2006-05-10 17:30:15 +00:00
|
|
|
#include "nsThreadUtils.h"
|
2001-06-19 01:38:20 +00:00
|
|
|
#include "nsIInputStreamTee.h"
|
2015-04-15 16:47:03 +00:00
|
|
|
#include "nsQueryObject.h"
|
2001-10-11 20:55:12 +00:00
|
|
|
|
2001-06-09 01:03:53 +00:00
|
|
|
#include "nsDirectoryServiceDefs.h"
|
2002-06-13 18:19:10 +00:00
|
|
|
#include "nsAppDirectoryServiceDefs.h"
|
2001-11-17 15:26:02 +00:00
|
|
|
#include "nsPluginDirServiceProvider.h"
|
2001-06-09 01:03:53 +00:00
|
|
|
|
2002-02-19 22:49:12 +00:00
|
|
|
#include "nsUnicharUtils.h"
|
2002-08-14 22:31:59 +00:00
|
|
|
#include "nsPluginManifestLineReader.h"
|
2002-02-19 22:49:12 +00:00
|
|
|
|
2010-02-24 02:58:27 +00:00
|
|
|
#include "nsIWeakReferenceUtils.h"
|
2002-07-03 21:03:51 +00:00
|
|
|
#include "nsIPresShell.h"
|
2002-09-26 02:53:27 +00:00
|
|
|
#include "nsPluginNativeWindow.h"
|
2005-09-07 02:39:51 +00:00
|
|
|
#include "nsIContentPolicy.h"
|
|
|
|
#include "nsContentPolicyUtils.h"
|
2010-01-27 01:30:58 +00:00
|
|
|
#include "mozilla/TimeStamp.h"
|
2011-07-01 19:06:12 +00:00
|
|
|
#include "mozilla/Telemetry.h"
|
2012-01-31 21:55:54 +00:00
|
|
|
#include "nsIImageLoadingContent.h"
|
2011-12-10 17:23:05 +00:00
|
|
|
#include "mozilla/Preferences.h"
|
2012-06-14 02:51:21 +00:00
|
|
|
#include "nsVersionComparator.h"
|
2015-04-13 18:47:41 +00:00
|
|
|
#include "nsNullPrincipal.h"
|
2002-03-26 06:30:33 +00:00
|
|
|
|
2009-02-09 18:48:06 +00:00
|
|
|
#if defined(XP_WIN)
|
2010-11-05 15:18:07 +00:00
|
|
|
#include "nsIWindowMediator.h"
|
|
|
|
#include "nsIBaseWindow.h"
|
2009-02-09 18:48:06 +00:00
|
|
|
#include "windows.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#endif
|
|
|
|
|
2011-09-16 21:34:31 +00:00
|
|
|
#ifdef ANDROID
|
|
|
|
#include <android/log.h>
|
|
|
|
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
|
|
|
#endif
|
|
|
|
|
2013-02-12 20:33:38 +00:00
|
|
|
#if MOZ_CRASHREPORTER
|
|
|
|
#include "nsExceptionHandler.h"
|
|
|
|
#endif
|
|
|
|
|
2015-05-01 15:07:19 +00:00
|
|
|
#include "npapi.h"
|
|
|
|
|
2011-02-08 22:16:07 +00:00
|
|
|
using namespace mozilla;
|
2010-01-27 01:30:58 +00:00
|
|
|
using mozilla::TimeStamp;
|
2014-10-29 15:05:36 +00:00
|
|
|
using mozilla::plugins::PluginTag;
|
2014-12-29 23:12:40 +00:00
|
|
|
using mozilla::plugins::PluginAsyncSurrogate;
|
2015-05-20 13:30:05 +00:00
|
|
|
using mozilla::dom::FakePluginTagInit;
|
2010-01-27 01:30:58 +00:00
|
|
|
|
2009-08-19 00:25:36 +00:00
|
|
|
// Null out a strong ref to a linked list iteratively to avoid
|
|
|
|
// exhausting the stack (bug 486349).
|
|
|
|
#define NS_ITERATIVE_UNREF_LIST(type_, list_, mNext_) \
|
|
|
|
{ \
|
|
|
|
while (list_) { \
|
|
|
|
type_ temp = list_->mNext_; \
|
2015-02-25 16:36:39 +00:00
|
|
|
list_->mNext_ = nullptr; \
|
2009-08-19 00:25:36 +00:00
|
|
|
list_ = temp; \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
2001-10-18 12:26:23 +00:00
|
|
|
// this is the name of the directory which will be created
|
|
|
|
// to cache temporary files.
|
2002-04-27 05:33:09 +00:00
|
|
|
#define kPluginTmpDirName NS_LITERAL_CSTRING("plugtmp")
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2012-07-02 20:44:39 +00:00
|
|
|
static const char *kPrefWhitelist = "plugin.allowed_types";
|
2016-01-06 01:57:11 +00:00
|
|
|
static const char *kPrefLoadInParentPrefix = "plugin.load_in_parent_process.";
|
2012-06-29 22:28:45 +00:00
|
|
|
static const char *kPrefDisableFullPage = "plugin.disable_full_page_plugin_for_types";
|
2014-02-10 23:50:53 +00:00
|
|
|
static const char *kPrefJavaMIME = "plugin.java.mime";
|
2012-07-02 20:44:39 +00:00
|
|
|
|
2014-05-15 13:37:00 +00:00
|
|
|
// How long we wait before unloading an idle plugin process.
|
|
|
|
// Defaults to 30 seconds.
|
|
|
|
static const char *kPrefUnloadPluginTimeoutSecs = "dom.ipc.plugins.unloadTimeoutSecs";
|
|
|
|
static const uint32_t kDefaultPluginUnloadingTimeout = 30;
|
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
static const char *kPluginRegistryVersion = "0.18";
|
2008-11-03 19:23:07 +00:00
|
|
|
|
2001-11-17 15:26:02 +00:00
|
|
|
static const char kDirectoryServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
2000-07-07 00:10:54 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
#define kPluginRegistryFilename NS_LITERAL_CSTRING("pluginreg.dat")
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
2015-11-23 19:09:25 +00:00
|
|
|
LazyLogModule nsPluginLogging::gNPNLog(NPN_LOG_NAME);
|
|
|
|
LazyLogModule nsPluginLogging::gNPPLog(NPP_LOG_NAME);
|
|
|
|
LazyLogModule nsPluginLogging::gPluginLog(PLUGIN_LOG_NAME);
|
2001-08-16 02:59:03 +00:00
|
|
|
#endif
|
|
|
|
|
2011-11-12 01:10:31 +00:00
|
|
|
// #defines for plugin cache and prefs
|
|
|
|
#define NS_PREF_MAX_NUM_CACHED_INSTANCES "browser.plugins.max_num_cached_plugins"
|
2011-12-08 23:28:07 +00:00
|
|
|
// Raise this from '10' to '50' to work around a bug in Apple's current Java
|
|
|
|
// plugins on OS X Lion and SnowLeopard. See bug 705931.
|
|
|
|
#define DEFAULT_NUMBER_OF_STOPPED_INSTANCES 50
|
2011-11-12 01:10:31 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
nsIFile *nsPluginHost::sPluginTempDir;
|
|
|
|
nsPluginHost *nsPluginHost::sInst;
|
1998-08-05 04:21:36 +00:00
|
|
|
|
2015-07-07 15:29:00 +00:00
|
|
|
/* to cope with short read */
|
|
|
|
/* we should probably put this into a global library now that this is the second
|
|
|
|
time we need this. */
|
|
|
|
static
|
2015-12-31 03:52:50 +00:00
|
|
|
int32_t
|
|
|
|
busy_beaver_PR_Read(PRFileDesc *fd, void * start, int32_t len)
|
2015-07-07 15:29:00 +00:00
|
|
|
{
|
|
|
|
int n;
|
2015-12-31 03:52:50 +00:00
|
|
|
int32_t remaining = len;
|
2015-07-07 15:29:00 +00:00
|
|
|
|
|
|
|
while (remaining > 0)
|
|
|
|
{
|
|
|
|
n = PR_Read(fd, start, remaining);
|
|
|
|
if (n < 0)
|
|
|
|
{
|
|
|
|
/* may want to repeat if errno == EINTR */
|
|
|
|
if( (len - remaining) == 0 ) // no octet is ever read
|
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
remaining -= n;
|
|
|
|
char *cp = (char *) start;
|
|
|
|
cp += n;
|
|
|
|
start = cp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return len - remaining;
|
|
|
|
}
|
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
NS_IMPL_ISUPPORTS0(nsInvalidPluginTag)
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
nsInvalidPluginTag::nsInvalidPluginTag(const char* aFullPath, int64_t aLastModifiedTime)
|
2010-12-09 22:28:15 +00:00
|
|
|
: mFullPath(aFullPath),
|
|
|
|
mLastModifiedTime(aLastModifiedTime),
|
2010-12-20 23:38:04 +00:00
|
|
|
mSeen(false)
|
2012-11-29 23:00:04 +00:00
|
|
|
{}
|
2010-12-09 22:28:15 +00:00
|
|
|
|
|
|
|
nsInvalidPluginTag::~nsInvalidPluginTag()
|
2012-11-29 23:00:04 +00:00
|
|
|
{}
|
2010-12-09 22:28:15 +00:00
|
|
|
|
2012-07-02 20:44:39 +00:00
|
|
|
// Helper to check for a MIME in a comma-delimited preference
|
|
|
|
static bool
|
2015-05-20 13:30:05 +00:00
|
|
|
IsTypeInList(const nsCString& aMimeType, nsCString aTypeList)
|
2012-07-02 20:44:39 +00:00
|
|
|
{
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString searchStr;
|
2012-07-02 20:44:39 +00:00
|
|
|
searchStr.Assign(',');
|
2012-07-09 21:50:42 +00:00
|
|
|
searchStr.Append(aTypeList);
|
2012-07-02 20:44:39 +00:00
|
|
|
searchStr.Append(',');
|
|
|
|
|
|
|
|
nsACString::const_iterator start, end;
|
|
|
|
|
|
|
|
searchStr.BeginReading(start);
|
|
|
|
searchStr.EndReading(end);
|
|
|
|
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString commaSeparated;
|
2012-07-02 20:44:39 +00:00
|
|
|
commaSeparated.Assign(',');
|
|
|
|
commaSeparated += aMimeType;
|
|
|
|
commaSeparated.Append(',');
|
|
|
|
|
2015-07-23 17:41:57 +00:00
|
|
|
// Lower-case the search string and MIME type to properly handle a mixed-case
|
|
|
|
// type, as MIME types are case insensitive.
|
|
|
|
ToLowerCase(searchStr);
|
|
|
|
ToLowerCase(commaSeparated);
|
|
|
|
|
2012-07-02 20:44:39 +00:00
|
|
|
return FindInReadable(commaSeparated, start, end);
|
|
|
|
}
|
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
// flat file reg funcs
|
|
|
|
static
|
2011-09-29 06:19:26 +00:00
|
|
|
bool ReadSectionHeader(nsPluginManifestLineReader& reader, const char *token)
|
1998-08-05 04:21:36 +00:00
|
|
|
{
|
2010-07-13 20:48:00 +00:00
|
|
|
do {
|
|
|
|
if (*reader.LinePtr() == '[') {
|
|
|
|
char* p = reader.LinePtr() + (reader.LineLength() - 1);
|
|
|
|
if (*p != ']')
|
|
|
|
break;
|
|
|
|
*p = 0;
|
2002-03-27 03:41:43 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
char* values[1];
|
|
|
|
if (1 != reader.ParseLine(values, 1))
|
|
|
|
break;
|
|
|
|
// ignore the leading '['
|
|
|
|
if (PL_strcmp(values[0]+1, token)) {
|
|
|
|
break; // it's wrong token
|
2002-03-27 03:41:43 +00:00
|
|
|
}
|
2011-09-30 06:02:59 +00:00
|
|
|
return true;
|
2002-03-27 03:41:43 +00:00
|
|
|
}
|
2010-07-13 20:48:00 +00:00
|
|
|
} while (reader.NextLine());
|
2011-09-30 06:02:59 +00:00
|
|
|
return false;
|
1998-08-05 04:21:36 +00:00
|
|
|
}
|
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
static bool UnloadPluginsASAP()
|
2010-08-18 00:05:48 +00:00
|
|
|
{
|
2014-05-15 13:37:00 +00:00
|
|
|
return (Preferences::GetUint(kPrefUnloadPluginTimeoutSecs, kDefaultPluginUnloadingTimeout) == 0);
|
2010-08-18 00:05:48 +00:00
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::nsPluginHost()
|
2012-07-30 14:20:58 +00:00
|
|
|
// No need to initialize members to nullptr, false etc because this class
|
2009-08-19 00:25:36 +00:00
|
|
|
// has a zeroing operator new.
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2014-10-30 18:52:30 +00:00
|
|
|
// Bump the pluginchanged epoch on startup. This insures content gets a
|
|
|
|
// good plugin list the first time it requests it. Normally we'd just
|
|
|
|
// init this to 1, but due to the unique nature of our ctor we need to do
|
|
|
|
// this manually.
|
2015-07-04 01:29:00 +00:00
|
|
|
if (XRE_IsParentProcess()) {
|
2014-10-30 18:52:30 +00:00
|
|
|
IncrementChromeEpoch();
|
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// check to see if pref is set at startup to let plugins take over in
|
2002-03-26 06:30:33 +00:00
|
|
|
// full page mode for certain image mime types that we handle internally
|
2012-04-04 04:09:20 +00:00
|
|
|
mOverrideInternalTypes =
|
|
|
|
Preferences::GetBool("plugin.override_internal_types", false);
|
2005-01-05 00:21:06 +00:00
|
|
|
|
2012-04-04 04:09:20 +00:00
|
|
|
mPluginsDisabled = Preferences::GetBool("plugin.disable", false);
|
2001-03-12 02:07:15 +00:00
|
|
|
|
2012-01-06 00:02:51 +00:00
|
|
|
Preferences::AddStrongObserver(this, "plugin.disable");
|
|
|
|
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 16:59:13 +00:00
|
|
|
nsCOMPtr<nsIObserverService> obsService =
|
|
|
|
mozilla::services::GetObserverService();
|
2009-01-30 21:40:14 +00:00
|
|
|
if (obsService) {
|
2011-09-30 06:02:59 +00:00
|
|
|
obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
|
2013-06-19 15:07:28 +00:00
|
|
|
obsService->AddObserver(this, "blocklist-updated", false);
|
2012-02-15 20:34:31 +00:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
|
|
|
obsService->AddObserver(this, "application-foreground", false);
|
|
|
|
obsService->AddObserver(this, "application-background", false);
|
|
|
|
#endif
|
2001-03-31 02:26:51 +00:00
|
|
|
}
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
#ifdef PLUGIN_LOGGING
|
2015-05-21 20:22:04 +00:00
|
|
|
MOZ_LOG(nsPluginLogging::gNPNLog, PLUGIN_LOG_ALWAYS,("NPN Logging Active!\n"));
|
|
|
|
MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_ALWAYS,("General Plugin Logging Active! (nsPluginHost::ctor)\n"));
|
|
|
|
MOZ_LOG(nsPluginLogging::gNPPLog, PLUGIN_LOG_ALWAYS,("NPP Logging Active!\n"));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("nsPluginHost::ctor\n"));
|
2001-08-16 02:59:03 +00:00
|
|
|
PR_LogFlush();
|
|
|
|
#endif
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::~nsPluginHost()
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2009-07-02 05:48:08 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("nsPluginHost::dtor\n"));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2012-01-06 00:02:51 +00:00
|
|
|
UnloadPlugins();
|
2012-07-30 14:20:58 +00:00
|
|
|
sInst = nullptr;
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2014-04-27 07:06:00 +00:00
|
|
|
NS_IMPL_ISUPPORTS(nsPluginHost,
|
|
|
|
nsIPluginHost,
|
|
|
|
nsIObserver,
|
|
|
|
nsITimerCallback,
|
|
|
|
nsISupportsWeakReference)
|
2008-11-03 19:23:07 +00:00
|
|
|
|
2013-03-20 18:29:00 +00:00
|
|
|
already_AddRefed<nsPluginHost>
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::GetInst()
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2005-11-06 18:34:03 +00:00
|
|
|
if (!sInst) {
|
2009-07-02 05:48:08 +00:00
|
|
|
sInst = new nsPluginHost();
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!sInst)
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr;
|
2005-11-06 18:34:03 +00:00
|
|
|
NS_ADDREF(sInst);
|
|
|
|
}
|
1998-07-28 02:07:25 +00:00
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginHost> inst = sInst;
|
2013-04-22 11:15:59 +00:00
|
|
|
return inst.forget();
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2012-04-03 22:08:07 +00:00
|
|
|
bool nsPluginHost::IsRunningPlugin(nsPluginTag * aPluginTag)
|
2001-02-02 23:48:17 +00:00
|
|
|
{
|
2012-04-03 22:08:07 +00:00
|
|
|
if (!aPluginTag || !aPluginTag->mPlugin) {
|
2011-09-30 06:02:59 +00:00
|
|
|
return false;
|
2011-03-29 20:43:18 +00:00
|
|
|
}
|
2001-02-02 23:48:17 +00:00
|
|
|
|
2014-10-29 15:05:36 +00:00
|
|
|
if (aPluginTag->mContentProcessRunningCount) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
for (uint32_t i = 0; i < mInstances.Length(); i++) {
|
2011-03-29 20:43:18 +00:00
|
|
|
nsNPAPIPluginInstance *instance = mInstances[i].get();
|
|
|
|
if (instance &&
|
2012-04-03 22:08:07 +00:00
|
|
|
instance->GetPlugin() == aPluginTag->mPlugin &&
|
2011-03-29 20:43:18 +00:00
|
|
|
instance->IsRunning()) {
|
2011-09-30 06:02:59 +00:00
|
|
|
return true;
|
2011-03-29 20:43:18 +00:00
|
|
|
}
|
2001-02-02 23:48:17 +00:00
|
|
|
}
|
|
|
|
|
2011-09-30 06:02:59 +00:00
|
|
|
return false;
|
2001-02-02 23:48:17 +00:00
|
|
|
}
|
|
|
|
|
2013-04-23 20:02:12 +00:00
|
|
|
nsresult nsPluginHost::ReloadPlugins()
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
2013-04-23 20:02:12 +00:00
|
|
|
("nsPluginHost::ReloadPlugins Begin\n"));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
2002-05-16 20:47:29 +00:00
|
|
|
// this will create the initial plugin list out of cache
|
|
|
|
// if it was not created yet
|
2002-07-01 20:36:57 +00:00
|
|
|
if (!mPluginsLoaded)
|
|
|
|
return LoadPlugins();
|
2002-05-16 20:47:29 +00:00
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
// we are re-scanning plugins. New plugins may have been added, also some
|
|
|
|
// plugins may have been removed, so we should probably shut everything down
|
2011-07-08 16:39:22 +00:00
|
|
|
// but don't touch running (active and not stopped) plugins
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2002-05-16 20:47:29 +00:00
|
|
|
// check if plugins changed, no need to do anything else
|
|
|
|
// if no changes to plugins have been made
|
2011-09-30 06:02:59 +00:00
|
|
|
// false instructs not to touch the plugin list, just to
|
2002-05-16 20:47:29 +00:00
|
|
|
// look for possible changes
|
2011-09-29 06:19:26 +00:00
|
|
|
bool pluginschanged = true;
|
2011-09-30 06:02:59 +00:00
|
|
|
FindPlugins(false, &pluginschanged);
|
2002-05-16 20:47:29 +00:00
|
|
|
|
|
|
|
// if no changed detected, return an appropriate error code
|
|
|
|
if (!pluginschanged)
|
|
|
|
return NS_ERROR_PLUGINS_PLUGINSNOTCHANGED;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
// shutdown plugins and kill the list if there are no running plugins
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginTag> prev;
|
|
|
|
RefPtr<nsPluginTag> next;
|
2001-02-02 23:48:17 +00:00
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
for (RefPtr<nsPluginTag> p = mPlugins; p != nullptr;) {
|
2001-02-02 23:48:17 +00:00
|
|
|
next = p->mNext;
|
|
|
|
|
2009-06-11 17:40:38 +00:00
|
|
|
// only remove our plugin from the list if it's not running.
|
|
|
|
if (!IsRunningPlugin(p)) {
|
2008-11-03 19:23:07 +00:00
|
|
|
if (p == mPlugins)
|
2001-02-02 23:48:17 +00:00
|
|
|
mPlugins = next;
|
|
|
|
else
|
|
|
|
prev->mNext = next;
|
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
p->mNext = nullptr;
|
2009-12-03 05:14:13 +00:00
|
|
|
|
|
|
|
// attempt to unload plugins whenever they are removed from the list
|
2012-02-14 18:03:24 +00:00
|
|
|
p->TryUnloadPlugin(false);
|
2009-12-03 05:14:13 +00:00
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
p = next;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
prev = p;
|
|
|
|
p = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set flags
|
2011-09-30 06:02:59 +00:00
|
|
|
mPluginsLoaded = false;
|
2000-11-30 22:01:45 +00:00
|
|
|
|
|
|
|
// load them again
|
2002-01-29 21:22:13 +00:00
|
|
|
rv = LoadPlugins();
|
2001-02-02 23:48:17 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
2013-04-23 20:02:12 +00:00
|
|
|
("nsPluginHost::ReloadPlugins End\n"));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
return rv;
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2000-10-31 20:25:19 +00:00
|
|
|
#define NS_RETURN_UASTRING_SIZE 128
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsresult nsPluginHost::UserAgent(const char **retstring)
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2000-10-31 20:25:19 +00:00
|
|
|
static char resultString[NS_RETURN_UASTRING_SIZE];
|
1998-11-22 00:22:35 +00:00
|
|
|
nsresult res;
|
|
|
|
|
2006-06-18 21:18:22 +00:00
|
|
|
nsCOMPtr<nsIHttpProtocolHandler> http = do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &res);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_FAILED(res))
|
2000-10-31 20:25:19 +00:00
|
|
|
return res;
|
1998-10-28 21:16:00 +00:00
|
|
|
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString uaString;
|
2002-03-20 22:50:33 +00:00
|
|
|
res = http->GetUserAgent(uaString);
|
1999-06-18 17:34:08 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_SUCCEEDED(res)) {
|
|
|
|
if (NS_RETURN_UASTRING_SIZE > uaString.Length()) {
|
2002-03-20 22:50:33 +00:00
|
|
|
PL_strcpy(resultString, uaString.get());
|
2008-11-03 19:23:07 +00:00
|
|
|
} else {
|
2008-08-04 21:24:50 +00:00
|
|
|
// Copy as much of UA string as we can (terminate at right-most space).
|
|
|
|
PL_strncpy(resultString, uaString.get(), NS_RETURN_UASTRING_SIZE);
|
2008-11-03 19:23:07 +00:00
|
|
|
for (int i = NS_RETURN_UASTRING_SIZE - 1; i >= 0; i--) {
|
|
|
|
if (i == 0) {
|
2008-08-04 21:24:50 +00:00
|
|
|
resultString[NS_RETURN_UASTRING_SIZE - 1] = '\0';
|
2008-11-03 19:23:07 +00:00
|
|
|
}
|
|
|
|
else if (resultString[i] == ' ') {
|
2008-08-04 21:24:50 +00:00
|
|
|
resultString[i] = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2000-10-31 20:25:19 +00:00
|
|
|
}
|
2008-08-04 21:24:50 +00:00
|
|
|
*retstring = resultString;
|
2004-10-11 04:01:49 +00:00
|
|
|
}
|
2008-11-03 19:23:07 +00:00
|
|
|
else {
|
2012-07-30 14:20:58 +00:00
|
|
|
*retstring = nullptr;
|
2008-11-03 19:23:07 +00:00
|
|
|
}
|
1998-11-22 00:22:35 +00:00
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsPluginHost::UserAgent return=%s\n", *retstring));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
1998-10-28 21:16:00 +00:00
|
|
|
return res;
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2011-05-21 13:28:54 +00:00
|
|
|
nsresult nsPluginHost::GetURL(nsISupports* pluginInst,
|
|
|
|
const char* url,
|
|
|
|
const char* target,
|
2012-05-17 23:54:26 +00:00
|
|
|
nsNPAPIPluginStreamListener* streamListener,
|
2011-05-21 13:28:54 +00:00
|
|
|
const char* altHost,
|
|
|
|
const char* referrer,
|
2011-09-29 06:19:26 +00:00
|
|
|
bool forceJSEnabled)
|
r=vidur, av
a=brendan
bug=49525
This simple fix just adds parameters to an existing method in an XPCOM
safe way, by defining a new method at the end of the interface
definition with the additional parameters.
Original method:
NS_IMETHOD
GetURL(nsISupports* pluginInst,
const char* url,
const char* target = NULL,
nsIPluginStreamListener* streamListener = NULL,
const char* altHost = NULL,
const char* referrer = NULL,
PRBool forceJSEnabled = PR_FALSE) = 0;
New method:
NS_IMETHOD
GetURLWithHeaders(nsISupports* pluginInst,
const char* url,
const char* target = NULL,
nsIPluginStreamListener* streamListener = NULL,
const char* altHost = NULL,
const char* referrer = NULL,
PRBool forceJSEnabled = PR_FALSE,
PRUint32 getHeadersLength = 0,
const char* getHeaders = NULL) = 0;
I have modified nsPluginHostImpl.h to include this new method, and
modified nsPluginHostImpl.cpp so that its GetURL calls GetURLWithHeaders
with null values for the last two params.
M modules/plugin/public/nsIPluginManager.h
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-14 22:57:56 +00:00
|
|
|
{
|
2010-07-16 19:55:54 +00:00
|
|
|
return GetURLWithHeaders(static_cast<nsNPAPIPluginInstance*>(pluginInst),
|
|
|
|
url, target, streamListener, altHost, referrer,
|
2012-07-30 14:20:58 +00:00
|
|
|
forceJSEnabled, 0, nullptr);
|
r=vidur, av
a=brendan
bug=49525
This simple fix just adds parameters to an existing method in an XPCOM
safe way, by defining a new method at the end of the interface
definition with the additional parameters.
Original method:
NS_IMETHOD
GetURL(nsISupports* pluginInst,
const char* url,
const char* target = NULL,
nsIPluginStreamListener* streamListener = NULL,
const char* altHost = NULL,
const char* referrer = NULL,
PRBool forceJSEnabled = PR_FALSE) = 0;
New method:
NS_IMETHOD
GetURLWithHeaders(nsISupports* pluginInst,
const char* url,
const char* target = NULL,
nsIPluginStreamListener* streamListener = NULL,
const char* altHost = NULL,
const char* referrer = NULL,
PRBool forceJSEnabled = PR_FALSE,
PRUint32 getHeadersLength = 0,
const char* getHeaders = NULL) = 0;
I have modified nsPluginHostImpl.h to include this new method, and
modified nsPluginHostImpl.cpp so that its GetURL calls GetURLWithHeaders
with null values for the last two params.
M modules/plugin/public/nsIPluginManager.h
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-14 22:57:56 +00:00
|
|
|
}
|
|
|
|
|
2010-07-16 19:55:54 +00:00
|
|
|
nsresult nsPluginHost::GetURLWithHeaders(nsNPAPIPluginInstance* pluginInst,
|
2009-07-02 05:48:08 +00:00
|
|
|
const char* url,
|
|
|
|
const char* target,
|
2012-05-17 23:54:26 +00:00
|
|
|
nsNPAPIPluginStreamListener* streamListener,
|
2009-07-02 05:48:08 +00:00
|
|
|
const char* altHost,
|
|
|
|
const char* referrer,
|
2011-09-29 06:19:26 +00:00
|
|
|
bool forceJSEnabled,
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t getHeadersLength,
|
2009-07-02 05:48:08 +00:00
|
|
|
const char* getHeaders)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
2004-10-11 04:01:49 +00:00
|
|
|
// we can only send a stream back to the plugin (as specified by a
|
2012-05-17 23:54:26 +00:00
|
|
|
// null target) if we also have a nsNPAPIPluginStreamListener to talk to
|
2015-08-05 03:06:03 +00:00
|
|
|
if (!target && !streamListener) {
|
2009-10-29 00:29:44 +00:00
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
2015-08-05 03:06:03 +00:00
|
|
|
}
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2015-08-05 03:05:37 +00:00
|
|
|
nsresult rv = NS_OK;
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
if (target) {
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginInstanceOwner> owner = pluginInst->GetOwner();
|
2009-10-29 00:29:44 +00:00
|
|
|
if (owner) {
|
2015-08-05 03:06:03 +00:00
|
|
|
rv = owner->GetURL(url, target, nullptr, nullptr, 0, true);
|
2008-11-03 19:23:07 +00:00
|
|
|
}
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
2015-08-05 03:06:03 +00:00
|
|
|
if (streamListener) {
|
2011-11-22 03:14:00 +00:00
|
|
|
rv = NewPluginURLStream(NS_ConvertUTF8toUTF16(url), pluginInst,
|
2012-07-30 14:20:58 +00:00
|
|
|
streamListener, nullptr,
|
2009-12-27 20:26:00 +00:00
|
|
|
getHeaders, getHeadersLength);
|
2015-08-05 03:06:03 +00:00
|
|
|
}
|
1999-01-25 08:05:00 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-05-21 13:28:54 +00:00
|
|
|
nsresult nsPluginHost::PostURL(nsISupports* pluginInst,
|
2015-02-25 16:36:39 +00:00
|
|
|
const char* url,
|
|
|
|
uint32_t postDataLen,
|
|
|
|
const char* postData,
|
|
|
|
bool isFile,
|
|
|
|
const char* target,
|
|
|
|
nsNPAPIPluginStreamListener* streamListener,
|
|
|
|
const char* altHost,
|
|
|
|
const char* referrer,
|
|
|
|
bool forceJSEnabled,
|
|
|
|
uint32_t postHeadersLength,
|
|
|
|
const char* postHeaders)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
nsresult rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
|
|
|
// we can only send a stream back to the plugin (as specified
|
2012-05-17 23:54:26 +00:00
|
|
|
// by a null target) if we also have a nsNPAPIPluginStreamListener
|
2000-04-22 20:50:22 +00:00
|
|
|
// to talk to also
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!target && !streamListener)
|
2009-10-29 00:29:44 +00:00
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2010-07-16 19:55:54 +00:00
|
|
|
nsNPAPIPluginInstance* instance = static_cast<nsNPAPIPluginInstance*>(pluginInst);
|
2003-04-03 19:11:41 +00:00
|
|
|
|
2009-12-27 20:26:00 +00:00
|
|
|
nsCOMPtr<nsIInputStream> postStream;
|
2009-10-29 00:29:44 +00:00
|
|
|
if (isFile) {
|
2009-12-27 20:26:00 +00:00
|
|
|
nsCOMPtr<nsIFile> file;
|
|
|
|
rv = CreateTempFileToPost(postData, getter_AddRefs(file));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIInputStream> fileStream;
|
|
|
|
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream),
|
|
|
|
file,
|
|
|
|
PR_RDONLY,
|
|
|
|
0600,
|
|
|
|
nsIFileInputStream::DELETE_ON_CLOSE |
|
|
|
|
nsIFileInputStream::CLOSE_ON_EOF);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
rv = NS_NewBufferedInputStream(getter_AddRefs(postStream), fileStream, 8192);
|
|
|
|
if (NS_FAILED(rv))
|
2009-10-29 00:29:44 +00:00
|
|
|
return rv;
|
|
|
|
} else {
|
2009-12-27 20:26:00 +00:00
|
|
|
char *dataToPost;
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t newDataToPostLen;
|
2009-10-29 00:29:44 +00:00
|
|
|
ParsePostBufferToFixHeaders(postData, postDataLen, &dataToPost, &newDataToPostLen);
|
|
|
|
if (!dataToPost)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
2009-12-27 20:26:00 +00:00
|
|
|
nsCOMPtr<nsIStringInputStream> sis = do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
|
|
|
|
if (!sis) {
|
2015-04-01 05:29:55 +00:00
|
|
|
free(dataToPost);
|
2009-12-27 20:26:00 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// data allocated by ParsePostBufferToFixHeaders() is managed and
|
|
|
|
// freed by the string stream.
|
2009-10-29 00:29:44 +00:00
|
|
|
postDataLen = newDataToPostLen;
|
2009-12-27 20:26:00 +00:00
|
|
|
sis->AdoptData(dataToPost, postDataLen);
|
|
|
|
postStream = sis;
|
2009-10-29 00:29:44 +00:00
|
|
|
}
|
2002-01-30 02:40:46 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
if (target) {
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginInstanceOwner> owner = instance->GetOwner();
|
2009-10-29 00:29:44 +00:00
|
|
|
if (owner) {
|
2009-12-27 20:26:00 +00:00
|
|
|
rv = owner->GetURL(url, target, postStream,
|
2015-08-05 03:06:03 +00:00
|
|
|
(void*)postHeaders, postHeadersLength, true);
|
2008-11-03 19:23:07 +00:00
|
|
|
}
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2015-01-12 04:26:40 +00:00
|
|
|
// if we don't have a target, just create a stream.
|
2015-08-05 03:06:03 +00:00
|
|
|
if (streamListener) {
|
2011-11-22 03:14:00 +00:00
|
|
|
rv = NewPluginURLStream(NS_ConvertUTF8toUTF16(url), instance,
|
|
|
|
streamListener,
|
2009-12-27 20:26:00 +00:00
|
|
|
postStream, postHeaders, postHeadersLength);
|
2015-08-05 03:06:03 +00:00
|
|
|
}
|
1999-01-25 08:05:00 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
/* This method queries the prefs for proxy information.
|
1999-10-09 01:18:02 +00:00
|
|
|
* It has been tested and is known to work in the following three cases
|
|
|
|
* when no proxy host or port is specified
|
|
|
|
* when only the proxy host is specified
|
|
|
|
* when only the proxy port is specified
|
2004-10-11 04:01:49 +00:00
|
|
|
* This method conforms to the return code specified in
|
1999-10-09 01:18:02 +00:00
|
|
|
* http://developer.netscape.com/docs/manuals/proxy/adminnt/autoconf.htm#1020923
|
|
|
|
* with the exception that multiple values are not implemented.
|
|
|
|
*/
|
|
|
|
|
2011-05-21 13:28:54 +00:00
|
|
|
nsresult nsPluginHost::FindProxyForURL(const char* url, char* *result)
|
1998-09-01 00:17:25 +00:00
|
|
|
{
|
2000-10-05 07:58:51 +00:00
|
|
|
if (!url || !result) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
nsresult res;
|
|
|
|
|
2015-01-21 20:13:00 +00:00
|
|
|
nsCOMPtr<nsIProtocolProxyService> proxyService =
|
|
|
|
do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &res);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(res) || !proxyService)
|
1999-10-09 01:18:02 +00:00
|
|
|
return res;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsProtocolProxyService> rawProxyService = do_QueryObject(proxyService);
|
2015-01-21 20:13:00 +00:00
|
|
|
if (!rawProxyService) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2012-09-14 20:27:46 +00:00
|
|
|
|
2015-01-21 20:13:00 +00:00
|
|
|
// make a temporary channel from the argument url
|
2016-03-08 23:51:54 +00:00
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
res = NS_NewURI(getter_AddRefs(uri), nsDependentCString(url));
|
|
|
|
NS_ENSURE_SUCCESS(res, res);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPrincipal> nullPrincipal = nsNullPrincipal::Create();
|
|
|
|
// The following channel is never openend, so it does not matter what
|
|
|
|
// securityFlags we pass; let's follow the principle of least privilege.
|
2015-01-21 20:13:00 +00:00
|
|
|
nsCOMPtr<nsIChannel> tempChannel;
|
2016-03-08 23:51:54 +00:00
|
|
|
res = NS_NewChannel(getter_AddRefs(tempChannel), uri, nullPrincipal,
|
|
|
|
nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
|
|
|
|
nsIContentPolicy::TYPE_OTHER);
|
|
|
|
NS_ENSURE_SUCCESS(res, res);
|
1999-10-09 01:18:02 +00:00
|
|
|
|
2001-09-13 02:21:05 +00:00
|
|
|
nsCOMPtr<nsIProxyInfo> pi;
|
|
|
|
|
2015-01-21 20:13:00 +00:00
|
|
|
// Remove this deprecated call in the future (see Bug 778201):
|
|
|
|
res = rawProxyService->DeprecatedBlockingResolve(tempChannel, 0, getter_AddRefs(pi));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(res))
|
2001-05-02 23:38:41 +00:00
|
|
|
return res;
|
2000-10-05 07:58:51 +00:00
|
|
|
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString host, type;
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t port = -1;
|
2005-03-25 03:41:33 +00:00
|
|
|
|
|
|
|
// These won't fail, and even if they do... we'll be ok.
|
2005-03-25 21:33:12 +00:00
|
|
|
if (pi) {
|
|
|
|
pi->GetType(type);
|
|
|
|
pi->GetHost(host);
|
|
|
|
pi->GetPort(&port);
|
|
|
|
}
|
2005-03-25 03:41:33 +00:00
|
|
|
|
|
|
|
if (!pi || host.IsEmpty() || port <= 0 || host.EqualsLiteral("direct")) {
|
2001-09-13 02:21:05 +00:00
|
|
|
*result = PL_strdup("DIRECT");
|
2005-03-25 03:41:33 +00:00
|
|
|
} else if (type.EqualsLiteral("http")) {
|
|
|
|
*result = PR_smprintf("PROXY %s:%d", host.get(), port);
|
|
|
|
} else if (type.EqualsLiteral("socks4")) {
|
|
|
|
*result = PR_smprintf("SOCKS %s:%d", host.get(), port);
|
|
|
|
} else if (type.EqualsLiteral("socks")) {
|
2001-09-13 02:21:05 +00:00
|
|
|
// XXX - this is socks5, but there is no API for us to tell the
|
|
|
|
// plugin that fact. SOCKS for now, in case the proxy server
|
|
|
|
// speaks SOCKS4 as well. See bug 78176
|
|
|
|
// For a long time this was returning an http proxy type, so
|
|
|
|
// very little is probably broken by this
|
2005-03-25 03:41:33 +00:00
|
|
|
*result = PR_smprintf("SOCKS %s:%d", host.get(), port);
|
2001-09-13 02:21:05 +00:00
|
|
|
} else {
|
2011-09-30 06:02:59 +00:00
|
|
|
NS_ASSERTION(false, "Unknown proxy type!");
|
2001-05-02 23:38:41 +00:00
|
|
|
*result = PL_strdup("DIRECT");
|
2001-05-11 21:05:08 +00:00
|
|
|
}
|
2001-05-02 23:38:41 +00:00
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
if (nullptr == *result)
|
2001-05-02 23:38:41 +00:00
|
|
|
res = NS_ERROR_OUT_OF_MEMORY;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
1999-10-09 01:18:02 +00:00
|
|
|
return res;
|
1998-09-27 22:21:39 +00:00
|
|
|
}
|
|
|
|
|
2012-01-06 00:02:51 +00:00
|
|
|
nsresult nsPluginHost::UnloadPlugins()
|
1998-09-15 03:48:58 +00:00
|
|
|
{
|
2012-01-06 00:02:51 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsPluginHost::UnloadPlugins Called\n"));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2012-01-06 00:02:51 +00:00
|
|
|
if (!mPluginsLoaded)
|
2001-03-12 02:07:15 +00:00
|
|
|
return NS_OK;
|
1999-05-17 21:26:48 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// we should call nsIPluginInstance::Stop and nsIPluginInstance::SetWindow
|
2001-04-16 21:26:28 +00:00
|
|
|
// for those plugins who want it
|
2013-04-23 20:02:12 +00:00
|
|
|
DestroyRunningInstances(nullptr);
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2009-12-03 05:14:13 +00:00
|
|
|
nsPluginTag *pluginTag;
|
|
|
|
for (pluginTag = mPlugins; pluginTag; pluginTag = pluginTag->mNext) {
|
2012-02-14 18:03:24 +00:00
|
|
|
pluginTag->TryUnloadPlugin(true);
|
2001-03-31 02:26:51 +00:00
|
|
|
}
|
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsPluginTag>, mPlugins, mNext);
|
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2001-06-19 01:38:20 +00:00
|
|
|
// Lets remove any of the temporary files that we created.
|
2005-02-11 23:37:51 +00:00
|
|
|
if (sPluginTempDir) {
|
2011-09-30 06:02:59 +00:00
|
|
|
sPluginTempDir->Remove(true);
|
2005-02-11 23:37:51 +00:00
|
|
|
NS_RELEASE(sPluginTempDir);
|
|
|
|
}
|
2001-06-19 01:38:20 +00:00
|
|
|
|
2007-07-20 20:34:51 +00:00
|
|
|
#ifdef XP_WIN
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mPrivateDirServiceProvider) {
|
2005-02-11 23:37:51 +00:00
|
|
|
nsCOMPtr<nsIDirectoryService> dirService =
|
|
|
|
do_GetService(kDirectoryServiceContractID);
|
|
|
|
if (dirService)
|
2001-11-17 15:26:02 +00:00
|
|
|
dirService->UnregisterProvider(mPrivateDirServiceProvider);
|
2012-07-30 14:20:58 +00:00
|
|
|
mPrivateDirServiceProvider = nullptr;
|
2001-11-17 15:26:02 +00:00
|
|
|
}
|
2007-07-20 20:34:51 +00:00
|
|
|
#endif /* XP_WIN */
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2012-01-06 00:02:51 +00:00
|
|
|
mPluginsLoaded = false;
|
|
|
|
|
2002-12-26 22:54:46 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-11-17 15:26:02 +00:00
|
|
|
|
2010-01-27 01:30:58 +00:00
|
|
|
void nsPluginHost::OnPluginInstanceDestroyed(nsPluginTag* aPluginTag)
|
|
|
|
{
|
2011-09-29 06:19:26 +00:00
|
|
|
bool hasInstance = false;
|
2012-08-22 15:56:38 +00:00
|
|
|
for (uint32_t i = 0; i < mInstances.Length(); i++) {
|
2010-07-20 02:11:26 +00:00
|
|
|
if (TagForPlugin(mInstances[i]->GetPlugin()) == aPluginTag) {
|
2011-09-30 06:02:59 +00:00
|
|
|
hasInstance = true;
|
2010-01-27 01:30:58 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-14 18:03:24 +00:00
|
|
|
// We have some options for unloading plugins if they have no instances.
|
|
|
|
//
|
|
|
|
// Unloading plugins immediately can be bad - some plugins retain state
|
|
|
|
// between instances even when there are none. This is largely limited to
|
|
|
|
// going from one page to another, so state is retained without an instance
|
|
|
|
// for only a very short period of time. In order to allow this to work
|
|
|
|
// we don't unload plugins immediately by default. This is supported
|
|
|
|
// via a hidden user pref though.
|
|
|
|
//
|
|
|
|
// Another reason not to unload immediately is that loading is expensive,
|
|
|
|
// and it is better to leave popular plugins loaded.
|
|
|
|
//
|
2014-05-30 11:14:00 +00:00
|
|
|
// Our default behavior is to try to unload a plugin after a pref-controlled
|
|
|
|
// delay once its last instance is destroyed. This seems like a reasonable
|
|
|
|
// compromise that allows us to reclaim memory while allowing short state
|
|
|
|
// retention and avoid perf hits for loading popular plugins.
|
2012-02-14 18:03:24 +00:00
|
|
|
if (!hasInstance) {
|
|
|
|
if (UnloadPluginsASAP()) {
|
|
|
|
aPluginTag->TryUnloadPlugin(false);
|
|
|
|
} else {
|
|
|
|
if (aPluginTag->mUnloadTimer) {
|
|
|
|
aPluginTag->mUnloadTimer->Cancel();
|
|
|
|
} else {
|
|
|
|
aPluginTag->mUnloadTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
|
|
|
}
|
2014-05-15 13:37:00 +00:00
|
|
|
uint32_t unloadTimeout = Preferences::GetUint(kPrefUnloadPluginTimeoutSecs,
|
|
|
|
kDefaultPluginUnloadingTimeout);
|
|
|
|
aPluginTag->mUnloadTimer->InitWithCallback(this,
|
|
|
|
1000 * unloadTimeout,
|
|
|
|
nsITimer::TYPE_ONE_SHOT);
|
2012-02-14 18:03:24 +00:00
|
|
|
}
|
2010-01-27 01:30:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-02-11 23:37:51 +00:00
|
|
|
nsresult
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::GetPluginTempDir(nsIFile **aDir)
|
2005-02-11 23:37:51 +00:00
|
|
|
{
|
|
|
|
if (!sPluginTempDir) {
|
|
|
|
nsCOMPtr<nsIFile> tmpDir;
|
|
|
|
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR,
|
|
|
|
getter_AddRefs(tmpDir));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
rv = tmpDir->AppendNative(kPluginTmpDirName);
|
|
|
|
|
|
|
|
// make it unique, and mode == 0700, not world-readable
|
|
|
|
rv = tmpDir->CreateUnique(nsIFile::DIRECTORY_TYPE, 0700);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
tmpDir.swap(sPluginTempDir);
|
|
|
|
}
|
|
|
|
|
|
|
|
return sPluginTempDir->Clone(aDir);
|
|
|
|
}
|
|
|
|
|
2010-10-23 01:16:29 +00:00
|
|
|
nsresult
|
2015-02-25 16:36:39 +00:00
|
|
|
nsPluginHost::InstantiatePluginInstance(const nsACString& aMimeType, nsIURI* aURL,
|
2012-12-13 00:12:41 +00:00
|
|
|
nsObjectLoadingContent *aContent,
|
|
|
|
nsPluginInstanceOwner** aOwner)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
2006-06-03 23:23:45 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aOwner);
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString urlSpec;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aURL)
|
|
|
|
aURL->GetAsciiSpec(urlSpec);
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2015-05-21 20:22:04 +00:00
|
|
|
MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
2012-12-13 00:12:41 +00:00
|
|
|
("nsPluginHost::InstantiatePlugin Begin mime=%s, url=%s\n",
|
2015-02-25 16:36:39 +00:00
|
|
|
PromiseFlatCString(aMimeType).get(), urlSpec.get()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LogFlush();
|
|
|
|
#endif
|
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
if (aMimeType.IsEmpty()) {
|
2012-11-29 22:59:14 +00:00
|
|
|
NS_NOTREACHED("Attempting to spawn a plugin with no mime type");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginInstanceOwner> instanceOwner = new nsPluginInstanceOwner();
|
2012-01-31 21:55:54 +00:00
|
|
|
if (!instanceOwner) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
nsCOMPtr<nsIContent> ourContent = do_QueryInterface(static_cast<nsIImageLoadingContent*>(aContent));
|
|
|
|
nsresult rv = instanceOwner->Init(ourContent);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
nsPluginTagType tagType;
|
2013-12-03 08:36:13 +00:00
|
|
|
rv = instanceOwner->GetTagType(&tagType);
|
2012-01-31 21:55:54 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2015-03-18 01:44:34 +00:00
|
|
|
instanceOwner->Destroy();
|
2000-06-20 21:04:52 +00:00
|
|
|
return rv;
|
|
|
|
}
|
1998-08-21 01:12:53 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
if (tagType != nsPluginTagType_Embed &&
|
|
|
|
tagType != nsPluginTagType_Applet &&
|
|
|
|
tagType != nsPluginTagType_Object) {
|
2015-03-18 01:44:34 +00:00
|
|
|
instanceOwner->Destroy();
|
2012-01-31 21:55:54 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = SetUpPluginInstance(aMimeType, aURL, instanceOwner);
|
|
|
|
if (NS_FAILED(rv)) {
|
2015-03-18 01:44:34 +00:00
|
|
|
instanceOwner->Destroy();
|
2010-05-14 17:08:12 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2012-01-31 21:55:54 +00:00
|
|
|
}
|
2014-12-29 23:12:40 +00:00
|
|
|
const bool isAsyncInit = (rv == NS_PLUGIN_INIT_PENDING);
|
2010-05-13 19:56:19 +00:00
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsNPAPIPluginInstance> instance;
|
2012-01-31 21:55:54 +00:00
|
|
|
rv = instanceOwner->GetInstance(getter_AddRefs(instance));
|
|
|
|
if (NS_FAILED(rv)) {
|
2015-03-18 01:44:34 +00:00
|
|
|
instanceOwner->Destroy();
|
2001-08-16 02:59:03 +00:00
|
|
|
return rv;
|
2012-01-31 21:55:54 +00:00
|
|
|
}
|
1999-03-23 03:18:12 +00:00
|
|
|
|
2014-12-29 23:12:40 +00:00
|
|
|
// Async init plugins will initiate their own widget creation.
|
|
|
|
if (!isAsyncInit && instance) {
|
|
|
|
CreateWidget(instanceOwner);
|
2001-08-10 01:53:38 +00:00
|
|
|
}
|
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
// At this point we consider instantiation to be successful. Do not return an error.
|
|
|
|
instanceOwner.forget(aOwner);
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString urlSpec2;
|
2012-07-30 14:20:58 +00:00
|
|
|
if (aURL != nullptr) aURL->GetAsciiSpec(urlSpec2);
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2015-05-21 20:22:04 +00:00
|
|
|
MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
2012-12-13 00:12:41 +00:00
|
|
|
("nsPluginHost::InstantiatePlugin Finished mime=%s, rv=%d, url=%s\n",
|
2015-02-25 16:36:39 +00:00
|
|
|
PromiseFlatCString(aMimeType).get(), rv, urlSpec2.get()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LogFlush();
|
1999-07-07 00:28:34 +00:00
|
|
|
#endif
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2012-01-31 21:55:54 +00:00
|
|
|
return NS_OK;
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
1998-08-21 01:12:53 +00:00
|
|
|
|
2010-04-05 15:25:59 +00:00
|
|
|
nsPluginTag*
|
|
|
|
nsPluginHost::FindTagForLibrary(PRLibrary* aLibrary)
|
|
|
|
{
|
|
|
|
nsPluginTag* pluginTag;
|
|
|
|
for (pluginTag = mPlugins; pluginTag; pluginTag = pluginTag->mNext) {
|
|
|
|
if (pluginTag->mLibrary == aLibrary) {
|
|
|
|
return pluginTag;
|
|
|
|
}
|
|
|
|
}
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr;
|
2010-04-05 15:25:59 +00:00
|
|
|
}
|
|
|
|
|
2010-01-12 06:45:23 +00:00
|
|
|
nsPluginTag*
|
2010-07-20 02:11:26 +00:00
|
|
|
nsPluginHost::TagForPlugin(nsNPAPIPlugin* aPlugin)
|
2010-01-12 06:45:23 +00:00
|
|
|
{
|
|
|
|
nsPluginTag* pluginTag;
|
|
|
|
for (pluginTag = mPlugins; pluginTag; pluginTag = pluginTag->mNext) {
|
2012-04-03 22:08:07 +00:00
|
|
|
if (pluginTag->mPlugin == aPlugin) {
|
2010-01-12 06:45:23 +00:00
|
|
|
return pluginTag;
|
|
|
|
}
|
|
|
|
}
|
2010-07-20 02:11:26 +00:00
|
|
|
// a plugin should never exist without a corresponding tag
|
2010-12-20 01:37:43 +00:00
|
|
|
NS_ERROR("TagForPlugin has failed");
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr;
|
2010-01-12 06:45:23 +00:00
|
|
|
}
|
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
nsresult nsPluginHost::SetUpPluginInstance(const nsACString &aMimeType,
|
2011-05-21 13:28:54 +00:00
|
|
|
nsIURI *aURL,
|
2012-10-03 02:43:18 +00:00
|
|
|
nsPluginInstanceOwner *aOwner)
|
2002-05-16 20:47:29 +00:00
|
|
|
{
|
2010-12-20 09:13:00 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aOwner);
|
|
|
|
|
2012-04-03 22:11:06 +00:00
|
|
|
nsresult rv = TrySetUpPluginInstance(aMimeType, aURL, aOwner);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2002-05-16 20:47:29 +00:00
|
|
|
|
2012-04-03 22:11:06 +00:00
|
|
|
// If we failed to load a plugin instance we'll try again after
|
|
|
|
// reloading our plugin list. Only do that once per document to
|
|
|
|
// avoid redundant high resource usage on pages with multiple
|
|
|
|
// unkown instance types. We'll do that by caching the document.
|
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
aOwner->GetDocument(getter_AddRefs(document));
|
2002-05-16 20:47:29 +00:00
|
|
|
|
2012-04-03 22:11:06 +00:00
|
|
|
nsCOMPtr<nsIDocument> currentdocument = do_QueryReferent(mCurrentDocument);
|
|
|
|
if (document == currentdocument) {
|
|
|
|
return rv;
|
|
|
|
}
|
2002-05-16 20:47:29 +00:00
|
|
|
|
2012-04-03 22:11:06 +00:00
|
|
|
mCurrentDocument = do_GetWeakReference(document);
|
2002-05-16 20:47:29 +00:00
|
|
|
|
2012-04-03 22:11:06 +00:00
|
|
|
// Don't try to set up an instance again if nothing changed.
|
2013-04-23 20:02:12 +00:00
|
|
|
if (ReloadPlugins() == NS_ERROR_PLUGINS_PLUGINSNOTCHANGED) {
|
2012-04-03 22:11:06 +00:00
|
|
|
return rv;
|
2002-05-16 20:47:29 +00:00
|
|
|
}
|
|
|
|
|
2012-04-03 22:11:06 +00:00
|
|
|
return TrySetUpPluginInstance(aMimeType, aURL, aOwner);
|
2002-05-16 20:47:29 +00:00
|
|
|
}
|
|
|
|
|
2009-06-25 21:06:54 +00:00
|
|
|
nsresult
|
2015-02-25 16:36:39 +00:00
|
|
|
nsPluginHost::TrySetUpPluginInstance(const nsACString &aMimeType,
|
2009-07-02 05:48:08 +00:00
|
|
|
nsIURI *aURL,
|
2012-10-03 02:43:18 +00:00
|
|
|
nsPluginInstanceOwner *aOwner)
|
1999-03-03 04:10:54 +00:00
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
2015-05-21 20:22:04 +00:00
|
|
|
MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
2016-08-26 06:02:31 +00:00
|
|
|
("nsPluginHost::TrySetupPluginInstance Begin mime=%s, owner=%p, url=%s\n",
|
|
|
|
PromiseFlatCString(aMimeType).get(), aOwner,
|
|
|
|
aURL ? aURL->GetSpecOrDefault().get() : ""));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LogFlush();
|
|
|
|
#endif
|
|
|
|
|
2015-02-10 19:58:01 +00:00
|
|
|
#ifdef XP_WIN
|
|
|
|
bool changed;
|
|
|
|
if ((mRegKeyHKLM && NS_SUCCEEDED(mRegKeyHKLM->HasChanged(&changed)) && changed) ||
|
|
|
|
(mRegKeyHKCU && NS_SUCCEEDED(mRegKeyHKCU->HasChanged(&changed)) && changed)) {
|
|
|
|
ReloadPlugins();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsNPAPIPlugin> plugin;
|
2013-03-19 22:38:58 +00:00
|
|
|
GetPlugin(aMimeType, getter_AddRefs(plugin));
|
|
|
|
if (!plugin) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
nsPluginTag* pluginTag = FindNativePluginForType(aMimeType, true);
|
2013-03-19 22:38:58 +00:00
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
NS_ASSERTION(pluginTag, "Must have plugin tag here!");
|
2009-05-07 13:27:08 +00:00
|
|
|
|
2015-06-17 22:08:12 +00:00
|
|
|
plugin->GetLibrary()->SetHasLocalInstance();
|
|
|
|
|
2013-02-12 20:33:38 +00:00
|
|
|
#if defined(MOZ_WIDGET_ANDROID) && defined(MOZ_CRASHREPORTER)
|
|
|
|
if (pluginTag->mIsFlashPlugin) {
|
2015-05-20 13:30:05 +00:00
|
|
|
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FlashVersion"), pluginTag->Version());
|
2013-02-12 20:33:38 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsNPAPIPluginInstance> instance = new nsNPAPIPluginInstance();
|
1999-03-03 04:10:54 +00:00
|
|
|
|
2012-04-02 19:17:34 +00:00
|
|
|
// This will create the owning reference. The connection must be made between the
|
|
|
|
// instance and the instance owner before initialization. Plugins can call into
|
|
|
|
// the browser during initialization.
|
2011-05-18 01:48:34 +00:00
|
|
|
aOwner->SetInstance(instance.get());
|
2000-04-22 00:04:24 +00:00
|
|
|
|
2012-06-14 02:51:21 +00:00
|
|
|
// Add the instance to the instances list before we call NPP_New so that
|
|
|
|
// it is "in play" before NPP_New happens. Take it out if NPP_New fails.
|
|
|
|
mInstances.AppendElement(instance.get());
|
|
|
|
|
2009-12-15 20:28:12 +00:00
|
|
|
// this should not addref the instance or owner
|
|
|
|
// except in some cases not Java, see bug 140931
|
|
|
|
// our COM pointer will free the peer
|
2012-11-29 22:59:14 +00:00
|
|
|
nsresult rv = instance->Initialize(plugin.get(), aOwner, aMimeType);
|
2010-08-18 00:05:48 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2012-06-14 02:51:21 +00:00
|
|
|
mInstances.RemoveElement(instance.get());
|
2012-07-30 14:20:58 +00:00
|
|
|
aOwner->SetInstance(nullptr);
|
2010-08-18 00:05:48 +00:00
|
|
|
return rv;
|
2009-12-15 20:28:12 +00:00
|
|
|
}
|
1999-07-25 23:20:03 +00:00
|
|
|
|
2012-02-14 18:03:24 +00:00
|
|
|
// Cancel the plugin unload timer since we are creating
|
|
|
|
// an instance for it.
|
|
|
|
if (pluginTag->mUnloadTimer) {
|
|
|
|
pluginTag->mUnloadTimer->Cancel();
|
|
|
|
}
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
2015-05-21 20:22:04 +00:00
|
|
|
MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::TrySetupPluginInstance Finished mime=%s, rv=%d, owner=%p, url=%s\n",
|
2016-08-26 06:02:31 +00:00
|
|
|
PromiseFlatCString(aMimeType).get(), rv, aOwner,
|
|
|
|
aURL ? aURL->GetSpecOrDefault().get() : ""));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LogFlush();
|
|
|
|
#endif
|
|
|
|
|
2010-08-18 00:05:48 +00:00
|
|
|
return rv;
|
1999-03-03 04:10:54 +00:00
|
|
|
}
|
|
|
|
|
2013-06-11 14:58:43 +00:00
|
|
|
bool
|
2015-02-25 16:36:39 +00:00
|
|
|
nsPluginHost::HavePluginForType(const nsACString & aMimeType,
|
|
|
|
PluginFilter aFilter)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
2015-02-25 16:36:39 +00:00
|
|
|
bool checkEnabled = aFilter & eExcludeDisabled;
|
2015-05-20 13:30:05 +00:00
|
|
|
bool allowFake = !(aFilter & eExcludeFake);
|
|
|
|
return FindPluginForType(aMimeType, allowFake, checkEnabled);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIInternalPluginTag*
|
|
|
|
nsPluginHost::FindPluginForType(const nsACString& aMimeType,
|
|
|
|
bool aIncludeFake, bool aCheckEnabled)
|
|
|
|
{
|
|
|
|
if (aIncludeFake) {
|
|
|
|
nsFakePluginTag* fakeTag = FindFakePluginForType(aMimeType, aCheckEnabled);
|
|
|
|
if (fakeTag) {
|
|
|
|
return fakeTag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FindNativePluginForType(aMimeType, aCheckEnabled);
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2013-06-24 12:51:07 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHost::GetPluginTagForType(const nsACString& aMimeType,
|
2015-02-25 16:36:39 +00:00
|
|
|
uint32_t aExcludeFlags,
|
2013-06-24 12:51:07 +00:00
|
|
|
nsIPluginTag** aResult)
|
|
|
|
{
|
2015-05-20 13:30:05 +00:00
|
|
|
bool includeFake = !(aExcludeFlags & eExcludeFake);
|
2015-02-25 16:36:39 +00:00
|
|
|
bool includeDisabled = !(aExcludeFlags & eExcludeDisabled);
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
// First look for an enabled plugin.
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsIInternalPluginTag> tag = FindPluginForType(aMimeType, includeFake,
|
2015-05-20 13:30:05 +00:00
|
|
|
true);
|
|
|
|
if (!tag && includeDisabled) {
|
|
|
|
tag = FindPluginForType(aMimeType, includeFake, false);
|
2013-06-24 12:51:07 +00:00
|
|
|
}
|
2015-02-25 16:36:39 +00:00
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
if (tag) {
|
|
|
|
tag.forget(aResult);
|
|
|
|
return NS_OK;
|
2013-06-24 12:51:07 +00:00
|
|
|
}
|
2015-02-25 16:36:39 +00:00
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
2013-06-24 12:51:07 +00:00
|
|
|
}
|
|
|
|
|
2012-11-19 22:03:24 +00:00
|
|
|
NS_IMETHODIMP
|
2015-02-25 16:36:39 +00:00
|
|
|
nsPluginHost::GetStateForType(const nsACString &aMimeType,
|
|
|
|
uint32_t aExcludeFlags,
|
|
|
|
uint32_t* aResult)
|
2012-07-11 15:56:34 +00:00
|
|
|
{
|
2015-02-25 16:36:39 +00:00
|
|
|
nsCOMPtr<nsIPluginTag> tag;
|
|
|
|
nsresult rv = GetPluginTagForType(aMimeType, aExcludeFlags,
|
|
|
|
getter_AddRefs(tag));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2012-11-19 22:03:24 +00:00
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
return tag->GetEnabledState(aResult);
|
2012-07-11 15:56:34 +00:00
|
|
|
}
|
|
|
|
|
2013-06-24 12:51:07 +00:00
|
|
|
NS_IMETHODIMP
|
2015-02-25 16:36:39 +00:00
|
|
|
nsPluginHost::GetBlocklistStateForType(const nsACString &aMimeType,
|
|
|
|
uint32_t aExcludeFlags,
|
|
|
|
uint32_t *aState)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIPluginTag> tag;
|
|
|
|
nsresult rv = GetPluginTagForType(aMimeType,
|
|
|
|
aExcludeFlags,
|
|
|
|
getter_AddRefs(tag));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
return tag->GetBlocklistState(aState);
|
2012-07-11 15:56:34 +00:00
|
|
|
}
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2012-11-27 18:09:10 +00:00
|
|
|
NS_IMETHODIMP
|
2015-02-25 16:36:39 +00:00
|
|
|
nsPluginHost::GetPermissionStringForType(const nsACString &aMimeType,
|
|
|
|
uint32_t aExcludeFlags,
|
|
|
|
nsACString &aPermissionString)
|
2012-11-27 18:09:10 +00:00
|
|
|
{
|
2015-02-25 16:36:39 +00:00
|
|
|
nsCOMPtr<nsIPluginTag> tag;
|
|
|
|
nsresult rv = GetPluginTagForType(aMimeType, aExcludeFlags,
|
|
|
|
getter_AddRefs(tag));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2015-08-03 23:24:35 +00:00
|
|
|
return GetPermissionStringForTag(tag, aExcludeFlags, aPermissionString);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHost::GetPermissionStringForTag(nsIPluginTag* aTag,
|
|
|
|
uint32_t aExcludeFlags,
|
|
|
|
nsACString &aPermissionString)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(aTag, NS_ERROR_FAILURE);
|
2015-02-25 16:36:39 +00:00
|
|
|
|
2012-11-27 18:09:10 +00:00
|
|
|
aPermissionString.Truncate();
|
|
|
|
uint32_t blocklistState;
|
2015-08-03 23:24:35 +00:00
|
|
|
nsresult rv = aTag->GetBlocklistState(&blocklistState);
|
2012-11-27 18:09:10 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (blocklistState == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE ||
|
|
|
|
blocklistState == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {
|
|
|
|
aPermissionString.AssignLiteral("plugin-vulnerable:");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aPermissionString.AssignLiteral("plugin:");
|
|
|
|
}
|
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
nsCString niceName;
|
2015-08-03 23:24:35 +00:00
|
|
|
rv = aTag->GetNiceName(niceName);
|
2015-02-25 16:36:39 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
NS_ENSURE_TRUE(!niceName.IsEmpty(), NS_ERROR_FAILURE);
|
1999-09-01 19:58:22 +00:00
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
aPermissionString.Append(niceName);
|
1999-09-01 19:58:22 +00:00
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
return NS_OK;
|
1999-09-01 19:58:22 +00:00
|
|
|
}
|
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
bool
|
|
|
|
nsPluginHost::HavePluginForExtension(const nsACString & aExtension,
|
|
|
|
/* out */ nsACString & aMimeType,
|
|
|
|
PluginFilter aFilter)
|
1999-03-23 03:18:12 +00:00
|
|
|
{
|
2015-02-25 16:36:39 +00:00
|
|
|
bool checkEnabled = aFilter & eExcludeDisabled;
|
2015-05-20 13:30:05 +00:00
|
|
|
bool allowFake = !(aFilter & eExcludeFake);
|
|
|
|
return FindNativePluginForExtension(aExtension, aMimeType, checkEnabled) ||
|
|
|
|
(allowFake &&
|
|
|
|
FindFakePluginForExtension(aExtension, aMimeType, checkEnabled));
|
1999-03-23 03:18:12 +00:00
|
|
|
}
|
|
|
|
|
2013-07-09 13:58:21 +00:00
|
|
|
void
|
2015-05-20 13:30:05 +00:00
|
|
|
nsPluginHost::GetPlugins(nsTArray<nsCOMPtr<nsIInternalPluginTag>>& aPluginArray,
|
2015-07-14 13:21:14 +00:00
|
|
|
bool aIncludeDisabled)
|
1999-04-20 19:29:28 +00:00
|
|
|
{
|
2013-07-09 13:58:21 +00:00
|
|
|
aPluginArray.Clear();
|
2000-08-17 19:26:15 +00:00
|
|
|
|
2013-07-09 13:58:21 +00:00
|
|
|
LoadPlugins();
|
2000-08-17 19:26:15 +00:00
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
// Append fake plugins, then normal plugins.
|
|
|
|
|
|
|
|
uint32_t numFake = mFakePlugins.Length();
|
|
|
|
for (uint32_t i = 0; i < numFake; i++) {
|
|
|
|
aPluginArray.AppendElement(mFakePlugins[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Regular plugins
|
2000-08-17 19:26:15 +00:00
|
|
|
nsPluginTag* plugin = mPlugins;
|
2012-07-30 14:20:58 +00:00
|
|
|
while (plugin != nullptr) {
|
2015-07-14 13:21:14 +00:00
|
|
|
if (plugin->IsEnabled() || aIncludeDisabled) {
|
2013-07-09 13:58:21 +00:00
|
|
|
aPluginArray.AppendElement(plugin);
|
2006-08-12 02:13:24 +00:00
|
|
|
}
|
2000-08-17 19:26:15 +00:00
|
|
|
plugin = plugin->mNext;
|
|
|
|
}
|
1999-04-20 19:29:28 +00:00
|
|
|
}
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
// FIXME-jsplugins Check users for order of fake v non-fake
|
2007-07-03 21:42:35 +00:00
|
|
|
NS_IMETHODIMP
|
2012-08-22 15:56:38 +00:00
|
|
|
nsPluginHost::GetPluginTags(uint32_t* aPluginCount, nsIPluginTag*** aResults)
|
2007-07-03 21:42:35 +00:00
|
|
|
{
|
|
|
|
LoadPlugins();
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t count = 0;
|
2015-05-20 13:30:05 +00:00
|
|
|
uint32_t fakeCount = mFakePlugins.Length();
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginTag> plugin = mPlugins;
|
2012-07-30 14:20:58 +00:00
|
|
|
while (plugin != nullptr) {
|
2007-07-03 21:42:35 +00:00
|
|
|
count++;
|
|
|
|
plugin = plugin->mNext;
|
|
|
|
}
|
|
|
|
|
2007-07-08 07:08:04 +00:00
|
|
|
*aResults = static_cast<nsIPluginTag**>
|
2015-05-20 13:30:05 +00:00
|
|
|
(moz_xmalloc((fakeCount + count) * sizeof(**aResults)));
|
2007-07-03 21:42:35 +00:00
|
|
|
if (!*aResults)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
*aPluginCount = count + fakeCount;
|
2007-07-03 21:42:35 +00:00
|
|
|
|
|
|
|
plugin = mPlugins;
|
2012-08-22 15:56:38 +00:00
|
|
|
for (uint32_t i = 0; i < count; i++) {
|
2007-07-03 21:42:35 +00:00
|
|
|
(*aResults)[i] = plugin;
|
|
|
|
NS_ADDREF((*aResults)[i]);
|
|
|
|
plugin = plugin->mNext;
|
|
|
|
}
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
for (uint32_t i = 0; i < fakeCount; i++) {
|
|
|
|
(*aResults)[i + count] = static_cast<nsIInternalPluginTag*>(mFakePlugins[i]);
|
|
|
|
NS_ADDREF((*aResults)[i + count]);
|
|
|
|
}
|
|
|
|
|
2007-07-03 21:42:35 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2012-06-14 02:51:21 +00:00
|
|
|
nsPluginTag*
|
|
|
|
nsPluginHost::FindPreferredPlugin(const InfallibleTArray<nsPluginTag*>& matches)
|
|
|
|
{
|
|
|
|
// We prefer the plugin with the highest version number.
|
2012-06-29 22:28:45 +00:00
|
|
|
/// XXX(johns): This seems to assume the only time multiple plugins will have
|
|
|
|
/// the same MIME type is if they're multiple versions of the same
|
|
|
|
/// plugin -- but since plugin filenames and pretty names can both
|
|
|
|
/// update, it's probably less arbitrary than just going at it
|
|
|
|
/// alphabetically.
|
2012-06-14 02:51:21 +00:00
|
|
|
|
|
|
|
if (matches.IsEmpty()) {
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr;
|
2012-06-14 02:51:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsPluginTag *preferredPlugin = matches[0];
|
|
|
|
for (unsigned int i = 1; i < matches.Length(); i++) {
|
2015-05-20 13:30:05 +00:00
|
|
|
if (mozilla::Version(matches[i]->Version().get()) > preferredPlugin->Version().get()) {
|
2012-06-14 02:51:21 +00:00
|
|
|
preferredPlugin = matches[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return preferredPlugin;
|
|
|
|
}
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
nsFakePluginTag*
|
|
|
|
nsPluginHost::FindFakePluginForExtension(const nsACString & aExtension,
|
|
|
|
/* out */ nsACString & aMimeType,
|
|
|
|
bool aCheckEnabled)
|
|
|
|
{
|
|
|
|
if (aExtension.IsEmpty()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t numFakePlugins = mFakePlugins.Length();
|
|
|
|
for (int32_t i = 0; i < numFakePlugins; i++) {
|
|
|
|
nsFakePluginTag *plugin = mFakePlugins[i];
|
|
|
|
bool active;
|
|
|
|
if ((!aCheckEnabled ||
|
|
|
|
(NS_SUCCEEDED(plugin->GetActive(&active)) && active)) &&
|
|
|
|
plugin->HasExtension(aExtension, aMimeType)) {
|
|
|
|
return plugin;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsFakePluginTag*
|
|
|
|
nsPluginHost::FindFakePluginForType(const nsACString & aMimeType,
|
|
|
|
bool aCheckEnabled)
|
|
|
|
{
|
|
|
|
int32_t numFakePlugins = mFakePlugins.Length();
|
|
|
|
for (int32_t i = 0; i < numFakePlugins; i++) {
|
|
|
|
nsFakePluginTag *plugin = mFakePlugins[i];
|
|
|
|
bool active;
|
|
|
|
if ((!aCheckEnabled ||
|
|
|
|
(NS_SUCCEEDED(plugin->GetActive(&active)) && active)) &&
|
|
|
|
plugin->HasMimeType(aMimeType)) {
|
|
|
|
return plugin;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
nsPluginTag*
|
2015-02-25 16:36:39 +00:00
|
|
|
nsPluginHost::FindNativePluginForType(const nsACString & aMimeType,
|
|
|
|
bool aCheckEnabled)
|
1999-03-23 03:18:12 +00:00
|
|
|
{
|
2015-02-25 16:36:39 +00:00
|
|
|
if (aMimeType.IsEmpty()) {
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr;
|
2011-04-28 20:06:15 +00:00
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2000-08-17 19:26:15 +00:00
|
|
|
LoadPlugins();
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2012-06-14 02:51:21 +00:00
|
|
|
InfallibleTArray<nsPluginTag*> matchingPlugins;
|
|
|
|
|
2011-04-28 20:06:15 +00:00
|
|
|
nsPluginTag *plugin = mPlugins;
|
|
|
|
while (plugin) {
|
2015-02-25 16:36:39 +00:00
|
|
|
if ((!aCheckEnabled || plugin->IsActive()) &&
|
|
|
|
plugin->HasMimeType(aMimeType)) {
|
|
|
|
matchingPlugins.AppendElement(plugin);
|
2005-11-06 18:34:03 +00:00
|
|
|
}
|
2011-04-28 20:06:15 +00:00
|
|
|
plugin = plugin->mNext;
|
2005-11-06 18:34:03 +00:00
|
|
|
}
|
|
|
|
|
2012-06-14 02:51:21 +00:00
|
|
|
return FindPreferredPlugin(matchingPlugins);
|
2005-11-06 18:34:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsPluginTag*
|
2015-02-25 16:36:39 +00:00
|
|
|
nsPluginHost::FindNativePluginForExtension(const nsACString & aExtension,
|
|
|
|
/* out */ nsACString & aMimeType,
|
|
|
|
bool aCheckEnabled)
|
2005-11-06 18:34:03 +00:00
|
|
|
{
|
2015-02-25 16:36:39 +00:00
|
|
|
if (aExtension.IsEmpty()) {
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr;
|
2011-05-10 13:47:43 +00:00
|
|
|
}
|
2005-11-06 18:34:03 +00:00
|
|
|
|
|
|
|
LoadPlugins();
|
|
|
|
|
2012-06-14 02:51:21 +00:00
|
|
|
InfallibleTArray<nsPluginTag*> matchingPlugins;
|
2015-02-25 16:36:39 +00:00
|
|
|
nsCString matchingMime; // Don't mutate aMimeType unless returning a match
|
2011-05-10 13:47:43 +00:00
|
|
|
nsPluginTag *plugin = mPlugins;
|
2015-02-25 16:36:39 +00:00
|
|
|
|
2011-05-10 13:47:43 +00:00
|
|
|
while (plugin) {
|
2015-02-25 16:36:39 +00:00
|
|
|
if (!aCheckEnabled || plugin->IsActive()) {
|
|
|
|
if (plugin->HasExtension(aExtension, matchingMime)) {
|
|
|
|
matchingPlugins.AppendElement(plugin);
|
2005-11-06 18:34:03 +00:00
|
|
|
}
|
1999-03-23 03:18:12 +00:00
|
|
|
}
|
2011-05-10 13:47:43 +00:00
|
|
|
plugin = plugin->mNext;
|
1999-03-23 03:18:12 +00:00
|
|
|
}
|
|
|
|
|
2012-06-14 02:51:21 +00:00
|
|
|
nsPluginTag *preferredPlugin = FindPreferredPlugin(matchingPlugins);
|
|
|
|
if (!preferredPlugin) {
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr;
|
2012-06-14 02:51:21 +00:00
|
|
|
}
|
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
// Re-fetch the matching type because of how FindPreferredPlugin works...
|
|
|
|
preferredPlugin->HasExtension(aExtension, aMimeType);
|
2012-06-14 02:51:21 +00:00
|
|
|
return preferredPlugin;
|
1999-03-23 03:18:12 +00:00
|
|
|
}
|
|
|
|
|
2015-08-31 20:51:19 +00:00
|
|
|
static nsresult CreateNPAPIPlugin(nsPluginTag *aPluginTag,
|
|
|
|
nsNPAPIPlugin **aOutNPAPIPlugin)
|
|
|
|
{
|
|
|
|
// If this is an in-process plugin we'll need to load it here if we haven't already.
|
|
|
|
if (!nsNPAPIPlugin::RunPluginOOP(aPluginTag)) {
|
|
|
|
if (aPluginTag->mFullPath.IsEmpty())
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1");
|
|
|
|
file->InitWithPath(NS_ConvertUTF8toUTF16(aPluginTag->mFullPath));
|
|
|
|
nsPluginFile pluginFile(file);
|
|
|
|
PRLibrary* pluginLibrary = nullptr;
|
|
|
|
|
|
|
|
if (NS_FAILED(pluginFile.LoadPlugin(&pluginLibrary)) || !pluginLibrary)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
aPluginTag->mLibrary = pluginLibrary;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
rv = nsNPAPIPlugin::CreatePlugin(aPluginTag, aOutNPAPIPlugin);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2012-04-03 22:08:07 +00:00
|
|
|
nsresult nsPluginHost::EnsurePluginLoaded(nsPluginTag* aPluginTag)
|
2011-02-19 01:05:23 +00:00
|
|
|
{
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsNPAPIPlugin> plugin = aPluginTag->mPlugin;
|
2012-04-03 22:08:07 +00:00
|
|
|
if (!plugin) {
|
2015-08-31 20:51:19 +00:00
|
|
|
nsresult rv = CreateNPAPIPlugin(aPluginTag, getter_AddRefs(plugin));
|
2011-02-19 01:05:23 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2012-04-03 22:08:07 +00:00
|
|
|
aPluginTag->mPlugin = plugin;
|
2011-02-19 01:05:23 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2014-10-29 15:05:36 +00:00
|
|
|
nsresult
|
|
|
|
nsPluginHost::GetPluginForContentProcess(uint32_t aPluginId, nsNPAPIPlugin** aPlugin)
|
|
|
|
{
|
2016-01-14 22:03:11 +00:00
|
|
|
PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
|
2015-07-04 01:29:00 +00:00
|
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
2014-10-29 15:05:36 +00:00
|
|
|
|
|
|
|
// If plugins haven't been scanned yet, do so now
|
|
|
|
LoadPlugins();
|
|
|
|
|
|
|
|
nsPluginTag* pluginTag = PluginWithId(aPluginId);
|
|
|
|
if (pluginTag) {
|
2015-05-01 15:07:19 +00:00
|
|
|
// When setting up a bridge, double check with chrome to see if this plugin
|
|
|
|
// is blocked hard. Note this does not protect against vulnerable plugins
|
|
|
|
// that the user has explicitly allowed. :(
|
|
|
|
if (pluginTag->IsBlocklisted()) {
|
|
|
|
return NS_ERROR_PLUGIN_BLOCKLISTED;
|
|
|
|
}
|
|
|
|
|
2014-10-29 15:05:36 +00:00
|
|
|
nsresult rv = EnsurePluginLoaded(pluginTag);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We only get here if a content process doesn't have a PluginModuleParent
|
|
|
|
// for the given plugin already. Therefore, this counter is counting the
|
|
|
|
// number of outstanding PluginModuleParents for the plugin, excluding the
|
|
|
|
// one from the chrome process.
|
|
|
|
pluginTag->mContentProcessRunningCount++;
|
|
|
|
NS_ADDREF(*aPlugin = pluginTag->mPlugin);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2016-04-26 00:23:21 +00:00
|
|
|
class nsPluginUnloadRunnable : public Runnable
|
2014-10-29 15:05:36 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit nsPluginUnloadRunnable(uint32_t aPluginId) : mPluginId(aPluginId) {}
|
|
|
|
|
2016-08-08 02:18:10 +00:00
|
|
|
NS_IMETHOD Run() override
|
2014-10-29 15:05:36 +00:00
|
|
|
{
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
|
2014-10-29 15:05:36 +00:00
|
|
|
if (!host) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsPluginTag* pluginTag = host->PluginWithId(mPluginId);
|
|
|
|
if (!pluginTag) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(pluginTag->mContentProcessRunningCount > 0);
|
|
|
|
pluginTag->mContentProcessRunningCount--;
|
|
|
|
|
|
|
|
if (!pluginTag->mContentProcessRunningCount) {
|
|
|
|
if (!host->IsRunningPlugin(pluginTag)) {
|
|
|
|
pluginTag->TryUnloadPlugin(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
uint32_t mPluginId;
|
|
|
|
};
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPluginHost::NotifyContentModuleDestroyed(uint32_t aPluginId)
|
|
|
|
{
|
2015-07-04 01:29:00 +00:00
|
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
2014-10-29 15:05:36 +00:00
|
|
|
|
|
|
|
// This is called in response to a message from the plugin. Don't unload the
|
|
|
|
// plugin until the message handler is off the stack.
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginUnloadRunnable> runnable =
|
2014-10-29 15:05:36 +00:00
|
|
|
new nsPluginUnloadRunnable(aPluginId);
|
|
|
|
NS_DispatchToMainThread(runnable);
|
|
|
|
}
|
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
nsresult nsPluginHost::GetPlugin(const nsACString &aMimeType,
|
|
|
|
nsNPAPIPlugin** aPlugin)
|
1999-02-20 02:24:15 +00:00
|
|
|
{
|
2001-04-17 23:30:25 +00:00
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
2013-10-23 20:34:30 +00:00
|
|
|
*aPlugin = nullptr;
|
1999-02-25 04:15:39 +00:00
|
|
|
|
2001-04-17 23:30:25 +00:00
|
|
|
// If plugins haven't been scanned yet, do so now
|
2000-08-17 19:26:15 +00:00
|
|
|
LoadPlugins();
|
1999-02-25 04:15:39 +00:00
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
nsPluginTag* pluginTag = FindNativePluginForType(aMimeType, true);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (pluginTag) {
|
2005-11-06 18:34:03 +00:00
|
|
|
rv = NS_OK;
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_BASIC,
|
2009-07-08 01:00:11 +00:00
|
|
|
("nsPluginHost::GetPlugin Begin mime=%s, plugin=%s\n",
|
2015-05-20 13:30:05 +00:00
|
|
|
PromiseFlatCString(aMimeType).get(), pluginTag->FileName().get()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2012-06-25 19:59:42 +00:00
|
|
|
#ifdef DEBUG
|
2015-05-20 13:30:05 +00:00
|
|
|
if (!pluginTag->FileName().IsEmpty())
|
2015-02-25 16:36:39 +00:00
|
|
|
printf("For %s found plugin %s\n",
|
2015-05-20 13:30:05 +00:00
|
|
|
PromiseFlatCString(aMimeType).get(), pluginTag->FileName().get());
|
2001-02-02 23:48:17 +00:00
|
|
|
#endif
|
1999-07-06 04:14:54 +00:00
|
|
|
|
2011-02-19 01:05:23 +00:00
|
|
|
rv = EnsurePluginLoaded(pluginTag);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
2001-04-17 23:30:25 +00:00
|
|
|
}
|
2009-11-20 15:34:20 +00:00
|
|
|
|
2012-04-03 22:08:07 +00:00
|
|
|
NS_ADDREF(*aPlugin = pluginTag->mPlugin);
|
2009-11-20 15:34:20 +00:00
|
|
|
return NS_OK;
|
2001-04-17 23:30:25 +00:00
|
|
|
}
|
1999-02-20 02:24:15 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
2009-07-08 01:00:11 +00:00
|
|
|
("nsPluginHost::GetPlugin End mime=%s, rv=%d, plugin=%p name=%s\n",
|
2015-02-25 16:36:39 +00:00
|
|
|
PromiseFlatCString(aMimeType).get(), rv, *aPlugin,
|
2015-05-20 13:30:05 +00:00
|
|
|
(pluginTag ? pluginTag->FileName().get() : "(not found)")));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2001-04-17 23:30:25 +00:00
|
|
|
return rv;
|
1999-03-29 22:18:05 +00:00
|
|
|
}
|
1999-02-20 02:24:15 +00:00
|
|
|
|
2011-02-08 22:16:07 +00:00
|
|
|
// Normalize 'host' to ACE.
|
|
|
|
nsresult
|
|
|
|
nsPluginHost::NormalizeHostname(nsCString& host)
|
|
|
|
{
|
|
|
|
if (IsASCII(host)) {
|
|
|
|
ToLowerCase(host);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mIDNService) {
|
|
|
|
nsresult rv;
|
|
|
|
mIDNService = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
return mIDNService->ConvertUTF8toACE(host, host);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Enumerate a 'sites' array returned by GetSitesWithData and determine if
|
|
|
|
// any of them have a base domain in common with 'domain'; if so, append them
|
|
|
|
// to the 'result' array. If 'firstMatchOnly' is true, return after finding the
|
|
|
|
// first match.
|
|
|
|
nsresult
|
|
|
|
nsPluginHost::EnumerateSiteData(const nsACString& domain,
|
2012-11-29 16:14:14 +00:00
|
|
|
const InfallibleTArray<nsCString>& sites,
|
2011-02-08 22:16:07 +00:00
|
|
|
InfallibleTArray<nsCString>& result,
|
|
|
|
bool firstMatchOnly)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(!domain.IsVoid(), "null domain string");
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
if (!mTLDService) {
|
|
|
|
mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the base domain from the domain.
|
|
|
|
nsCString baseDomain;
|
|
|
|
rv = mTLDService->GetBaseDomainFromHost(domain, 0, baseDomain);
|
|
|
|
bool isIP = rv == NS_ERROR_HOST_IS_IP_ADDRESS;
|
|
|
|
if (isIP || rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
|
|
|
// The base domain is the site itself. However, we must be careful to
|
|
|
|
// normalize.
|
|
|
|
baseDomain = domain;
|
|
|
|
rv = NormalizeHostname(baseDomain);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
} else if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Enumerate the array of sites with data.
|
2012-08-22 15:56:38 +00:00
|
|
|
for (uint32_t i = 0; i < sites.Length(); ++i) {
|
2011-02-08 22:16:07 +00:00
|
|
|
const nsCString& site = sites[i];
|
|
|
|
|
|
|
|
// Check if the site is an IP address.
|
|
|
|
bool siteIsIP =
|
|
|
|
site.Length() >= 2 && site.First() == '[' && site.Last() == ']';
|
|
|
|
if (siteIsIP != isIP)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
nsCString siteBaseDomain;
|
|
|
|
if (siteIsIP) {
|
|
|
|
// Strip the '[]'.
|
|
|
|
siteBaseDomain = Substring(site, 1, site.Length() - 2);
|
|
|
|
} else {
|
|
|
|
// Determine the base domain of the site.
|
|
|
|
rv = mTLDService->GetBaseDomainFromHost(site, 0, siteBaseDomain);
|
|
|
|
if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
|
|
|
// The base domain is the site itself. However, we must be careful to
|
|
|
|
// normalize.
|
|
|
|
siteBaseDomain = site;
|
|
|
|
rv = NormalizeHostname(siteBaseDomain);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
} else if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// At this point, we can do an exact comparison of the two domains.
|
|
|
|
if (baseDomain != siteBaseDomain) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Append the site to the result array.
|
|
|
|
result.AppendElement(site);
|
|
|
|
|
|
|
|
// If we're supposed to return early, do so.
|
|
|
|
if (firstMatchOnly) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHost::RegisterFakePlugin(JS::Handle<JS::Value> aInitDictionary,
|
|
|
|
JSContext* aCx,
|
|
|
|
nsIFakePluginTag **aResult)
|
|
|
|
{
|
|
|
|
FakePluginTagInit initDictionary;
|
|
|
|
if (!initDictionary.Init(aCx, aInitDictionary)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsFakePluginTag> newTag;
|
2015-05-20 13:30:05 +00:00
|
|
|
nsresult rv = nsFakePluginTag::Create(initDictionary, getter_AddRefs(newTag));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
for (auto existingTag : mFakePlugins) {
|
|
|
|
if (newTag->HandlerURIMatches(existingTag->HandlerURI())) {
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mFakePlugins.AppendElement(newTag);
|
|
|
|
// FIXME-jsplugins do we need to register with the category manager here? For
|
|
|
|
// shumway, for now, probably not.
|
|
|
|
newTag.forget(aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHost::UnregisterFakePlugin(const nsACString& aHandlerURI)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIURI> handlerURI;
|
|
|
|
nsresult rv = NS_NewURI(getter_AddRefs(handlerURI), aHandlerURI);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < mFakePlugins.Length(); ++i) {
|
|
|
|
if (mFakePlugins[i]->HandlerURIMatches(handlerURI)) {
|
|
|
|
mFakePlugins.RemoveElementAt(i);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME-jsplugins Is this method actually needed?
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHost::GetFakePlugin(const nsACString & aMimeType,
|
|
|
|
nsIFakePluginTag** aResult)
|
|
|
|
{
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsFakePluginTag> result = FindFakePluginForType(aMimeType, false);
|
2015-05-20 13:30:05 +00:00
|
|
|
if (result) {
|
|
|
|
result.forget(aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aResult = nullptr;
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2015-06-30 22:08:19 +00:00
|
|
|
#define ClearDataFromSitesClosure_CID {0x9fb21761, 0x2403, 0x41ad, {0x9e, 0xfd, 0x36, 0x7e, 0xc4, 0x4f, 0xa4, 0x5e}}
|
|
|
|
|
|
|
|
|
|
|
|
// Class to hold all the data we need need for IterateMatchesAndClear and ClearDataFromSites
|
|
|
|
class ClearDataFromSitesClosure : public nsIClearSiteDataCallback, public nsIGetSitesWithDataCallback {
|
|
|
|
public:
|
|
|
|
ClearDataFromSitesClosure(nsIPluginTag* plugin, const nsACString& domain, uint64_t flags,
|
|
|
|
int64_t maxAge, nsCOMPtr<nsIClearSiteDataCallback> callback,
|
|
|
|
nsPluginHost* host) :
|
|
|
|
domain(domain), callback(callback), tag(plugin), flags(flags), maxAge(maxAge), host(host) {}
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// Callback from NPP_ClearSiteData, continue to iterate the matches and clear
|
2015-07-08 04:10:32 +00:00
|
|
|
NS_IMETHOD Callback(nsresult rv) override {
|
2015-06-30 22:08:19 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
callback->Callback(rv);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
if (!matches.Length()) {
|
|
|
|
callback->Callback(NS_OK);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
const nsCString match(matches[0]);
|
|
|
|
matches.RemoveElement(match);
|
|
|
|
PluginLibrary* library = static_cast<nsPluginTag*>(tag)->mPlugin->GetLibrary();
|
|
|
|
rv = library->NPP_ClearSiteData(match.get(), flags, maxAge, this);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
callback->Callback(rv);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Callback from NPP_GetSitesWithData, kick the iteration off to clear the data
|
2015-07-08 04:10:32 +00:00
|
|
|
NS_IMETHOD SitesWithData(InfallibleTArray<nsCString>& sites) override
|
2015-06-30 22:08:19 +00:00
|
|
|
{
|
|
|
|
// Enumerate the sites and build a list of matches.
|
|
|
|
nsresult rv = host->EnumerateSiteData(domain, sites, matches, false);
|
|
|
|
Callback(rv);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCString domain;
|
|
|
|
nsCOMPtr<nsIClearSiteDataCallback> callback;
|
|
|
|
InfallibleTArray<nsCString> matches;
|
|
|
|
nsIPluginTag* tag;
|
|
|
|
uint64_t flags;
|
|
|
|
int64_t maxAge;
|
|
|
|
nsPluginHost* host;
|
|
|
|
NS_DECLARE_STATIC_IID_ACCESSOR(ClearDataFromSitesClosure_CID)
|
|
|
|
private:
|
|
|
|
virtual ~ClearDataFromSitesClosure() {}
|
|
|
|
};
|
|
|
|
|
|
|
|
NS_DEFINE_STATIC_IID_ACCESSOR(ClearDataFromSitesClosure, ClearDataFromSitesClosure_CID)
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF(ClearDataFromSitesClosure)
|
|
|
|
NS_IMPL_RELEASE(ClearDataFromSitesClosure)
|
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN(ClearDataFromSitesClosure)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIClearSiteDataCallback)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIGetSitesWithDataCallback)
|
|
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIClearSiteDataCallback)
|
|
|
|
NS_INTERFACE_MAP_END
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
// FIXME-jsplugins what should this do for fake plugins?
|
2011-02-08 22:16:07 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHost::ClearSiteData(nsIPluginTag* plugin, const nsACString& domain,
|
2015-06-30 22:08:19 +00:00
|
|
|
uint64_t flags, int64_t maxAge, nsIClearSiteDataCallback* callbackFunc)
|
2011-02-08 22:16:07 +00:00
|
|
|
{
|
2015-06-30 22:08:19 +00:00
|
|
|
nsCOMPtr<nsIClearSiteDataCallback> callback(callbackFunc);
|
2011-02-08 22:16:07 +00:00
|
|
|
// maxAge must be either a nonnegative integer or -1.
|
|
|
|
NS_ENSURE_ARG(maxAge >= 0 || maxAge == -1);
|
|
|
|
|
2011-02-19 01:05:23 +00:00
|
|
|
// Caller may give us a tag object that is no longer live.
|
|
|
|
if (!IsLiveTag(plugin)) {
|
2011-02-08 22:16:07 +00:00
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2011-02-19 01:05:23 +00:00
|
|
|
nsPluginTag* tag = static_cast<nsPluginTag*>(plugin);
|
|
|
|
|
2014-12-24 22:50:00 +00:00
|
|
|
if (!tag->IsEnabled()) {
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2011-02-19 01:05:23 +00:00
|
|
|
// We only ensure support for clearing Flash site data for now.
|
|
|
|
// We will also attempt to clear data for any plugin that happens
|
|
|
|
// to be loaded already.
|
2012-04-03 22:08:07 +00:00
|
|
|
if (!tag->mIsFlashPlugin && !tag->mPlugin) {
|
2011-02-19 01:05:23 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure the plugin is loaded.
|
|
|
|
nsresult rv = EnsurePluginLoaded(tag);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2012-04-03 22:08:07 +00:00
|
|
|
PluginLibrary* library = tag->mPlugin->GetLibrary();
|
2011-02-08 22:16:07 +00:00
|
|
|
|
|
|
|
// If 'domain' is the null string, clear everything.
|
|
|
|
if (domain.IsVoid()) {
|
2015-06-30 22:08:19 +00:00
|
|
|
return library->NPP_ClearSiteData(nullptr, flags, maxAge, callback);
|
2015-06-30 22:08:19 +00:00
|
|
|
}
|
2015-06-30 22:08:19 +00:00
|
|
|
nsCOMPtr<nsIGetSitesWithDataCallback> closure(new ClearDataFromSitesClosure(plugin, domain, flags,
|
|
|
|
maxAge, callback, this));
|
|
|
|
rv = library->NPP_GetSitesWithData(closure);
|
2015-07-01 23:25:26 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2015-06-30 22:08:19 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2015-06-30 22:08:19 +00:00
|
|
|
|
2015-06-30 22:08:19 +00:00
|
|
|
#define GetSitesClosure_CID {0x4c9268ac, 0x2fd1, 0x4f2a, {0x9a, 0x10, 0x7a, 0x09, 0xf1, 0xb7, 0x60, 0x3a}}
|
2015-06-30 22:08:19 +00:00
|
|
|
|
2015-06-30 22:08:19 +00:00
|
|
|
// Closure to contain the data needed to handle the callback from NPP_GetSitesWithData
|
|
|
|
class GetSitesClosure : public nsIGetSitesWithDataCallback {
|
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
GetSitesClosure(const nsACString& domain, nsPluginHost* host)
|
|
|
|
: domain(domain), host(host), keepWaiting(true)
|
|
|
|
{
|
|
|
|
}
|
2015-07-08 04:10:32 +00:00
|
|
|
NS_IMETHOD SitesWithData(InfallibleTArray<nsCString>& sites) override {
|
2015-06-30 22:08:19 +00:00
|
|
|
retVal = HandleGetSites(sites);
|
|
|
|
keepWaiting = false;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult HandleGetSites(InfallibleTArray<nsCString>& sites) {
|
|
|
|
// If there's no data, we're done.
|
|
|
|
if (sites.IsEmpty()) {
|
|
|
|
result = false;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If 'domain' is the null string, and there's data for at least one site,
|
|
|
|
// we're done.
|
|
|
|
if (domain.IsVoid()) {
|
|
|
|
result = true;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Enumerate the sites and determine if there's a match.
|
|
|
|
InfallibleTArray<nsCString> matches;
|
|
|
|
nsresult rv = host->EnumerateSiteData(domain, sites, matches, true);
|
2011-02-08 22:16:07 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2015-06-30 22:08:19 +00:00
|
|
|
|
|
|
|
result = !matches.IsEmpty();
|
|
|
|
return NS_OK;
|
2015-06-30 22:08:19 +00:00
|
|
|
}
|
|
|
|
|
2015-06-30 22:08:19 +00:00
|
|
|
nsCString domain;
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginHost> host;
|
2015-06-30 22:08:19 +00:00
|
|
|
bool result;
|
|
|
|
bool keepWaiting;
|
|
|
|
nsresult retVal;
|
|
|
|
NS_DECLARE_STATIC_IID_ACCESSOR(GetSitesClosure_CID)
|
|
|
|
private:
|
|
|
|
virtual ~GetSitesClosure() {
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
NS_DEFINE_STATIC_IID_ACCESSOR(GetSitesClosure, GetSitesClosure_CID)
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(GetSitesClosure, GetSitesClosure, nsIGetSitesWithDataCallback)
|
2011-02-08 22:16:07 +00:00
|
|
|
|
2015-06-30 22:08:19 +00:00
|
|
|
// This will spin the event loop while waiting on an async
|
|
|
|
// call to GetSitesWithData
|
2011-02-08 22:16:07 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHost::SiteHasData(nsIPluginTag* plugin, const nsACString& domain,
|
2011-09-29 06:19:26 +00:00
|
|
|
bool* result)
|
2011-02-08 22:16:07 +00:00
|
|
|
{
|
2011-02-19 01:05:23 +00:00
|
|
|
// Caller may give us a tag object that is no longer live.
|
|
|
|
if (!IsLiveTag(plugin)) {
|
2011-02-08 22:16:07 +00:00
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
// FIXME-jsplugins audit casts
|
2011-02-19 01:05:23 +00:00
|
|
|
nsPluginTag* tag = static_cast<nsPluginTag*>(plugin);
|
|
|
|
|
|
|
|
// We only ensure support for clearing Flash site data for now.
|
|
|
|
// We will also attempt to clear data for any plugin that happens
|
|
|
|
// to be loaded already.
|
2012-04-03 22:08:07 +00:00
|
|
|
if (!tag->mIsFlashPlugin && !tag->mPlugin) {
|
2011-02-19 01:05:23 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure the plugin is loaded.
|
|
|
|
nsresult rv = EnsurePluginLoaded(tag);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2012-04-03 22:08:07 +00:00
|
|
|
PluginLibrary* library = tag->mPlugin->GetLibrary();
|
2011-02-08 22:16:07 +00:00
|
|
|
|
2015-06-30 22:08:19 +00:00
|
|
|
// Get the list of sites from the plugin
|
|
|
|
nsCOMPtr<GetSitesClosure> closure(new GetSitesClosure(domain, this));
|
|
|
|
rv = library->NPP_GetSitesWithData(nsCOMPtr<nsIGetSitesWithDataCallback>(do_QueryInterface(closure)));
|
2011-02-08 22:16:07 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2015-06-30 22:08:19 +00:00
|
|
|
// Spin the event loop while we wait for the async call to GetSitesWithData
|
|
|
|
while (closure->keepWaiting) {
|
|
|
|
NS_ProcessNextEvent(nullptr, true);
|
2011-02-08 22:16:07 +00:00
|
|
|
}
|
2015-06-30 22:08:19 +00:00
|
|
|
*result = closure->result;
|
|
|
|
return closure->retVal;
|
2011-02-08 22:16:07 +00:00
|
|
|
}
|
|
|
|
|
2015-01-30 15:54:19 +00:00
|
|
|
nsPluginHost::SpecialType
|
|
|
|
nsPluginHost::GetSpecialType(const nsACString & aMIMEType)
|
2005-11-06 18:34:03 +00:00
|
|
|
{
|
2015-10-12 19:48:12 +00:00
|
|
|
if (aMIMEType.LowerCaseEqualsASCII("application/x-test")) {
|
|
|
|
return eSpecialType_Test;
|
|
|
|
}
|
|
|
|
|
2015-01-30 15:54:19 +00:00
|
|
|
if (aMIMEType.LowerCaseEqualsASCII("application/x-shockwave-flash") ||
|
2016-01-15 07:45:50 +00:00
|
|
|
aMIMEType.LowerCaseEqualsASCII("application/futuresplash") ||
|
|
|
|
aMIMEType.LowerCaseEqualsASCII("application/x-shockwave-flash-test")) {
|
2015-01-30 15:54:19 +00:00
|
|
|
return eSpecialType_Flash;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aMIMEType.LowerCaseEqualsASCII("application/x-silverlight") ||
|
2016-03-28 22:37:26 +00:00
|
|
|
aMIMEType.LowerCaseEqualsASCII("application/x-silverlight-2") ||
|
|
|
|
aMIMEType.LowerCaseEqualsASCII("application/x-silverlight-test")) {
|
2015-01-30 15:54:19 +00:00
|
|
|
return eSpecialType_Silverlight;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aMIMEType.LowerCaseEqualsASCII("audio/x-pn-realaudio-plugin")) {
|
|
|
|
NS_WARNING("You are loading RealPlayer");
|
|
|
|
return eSpecialType_RealPlayer;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aMIMEType.LowerCaseEqualsASCII("application/pdf")) {
|
|
|
|
return eSpecialType_PDF;
|
|
|
|
}
|
|
|
|
|
2015-05-20 19:13:16 +00:00
|
|
|
if (aMIMEType.LowerCaseEqualsASCII("application/vnd.unity")) {
|
|
|
|
return eSpecialType_Unity;
|
|
|
|
}
|
|
|
|
|
2015-01-30 15:54:19 +00:00
|
|
|
// Java registers variants of its MIME with parameters, e.g.
|
|
|
|
// application/x-java-vm;version=1.3
|
|
|
|
const nsACString &noParam = Substring(aMIMEType, 0, aMIMEType.FindChar(';'));
|
|
|
|
|
2014-02-10 23:50:53 +00:00
|
|
|
// The java mime pref may well not be one of these,
|
|
|
|
// e.g. application/x-java-test used in the test suite
|
|
|
|
nsAdoptingCString javaMIME = Preferences::GetCString(kPrefJavaMIME);
|
2015-01-30 15:54:19 +00:00
|
|
|
if ((!javaMIME.IsEmpty() && noParam.LowerCaseEqualsASCII(javaMIME)) ||
|
|
|
|
noParam.LowerCaseEqualsASCII("application/x-java-vm") ||
|
|
|
|
noParam.LowerCaseEqualsASCII("application/x-java-applet") ||
|
|
|
|
noParam.LowerCaseEqualsASCII("application/x-java-bean")) {
|
|
|
|
return eSpecialType_Java;
|
|
|
|
}
|
|
|
|
|
|
|
|
return eSpecialType_None;
|
2005-11-06 18:34:03 +00:00
|
|
|
}
|
|
|
|
|
2011-02-19 01:05:23 +00:00
|
|
|
// Check whether or not a tag is a live, valid tag, and that it's loaded.
|
2011-09-29 06:19:26 +00:00
|
|
|
bool
|
2011-02-19 01:05:23 +00:00
|
|
|
nsPluginHost::IsLiveTag(nsIPluginTag* aPluginTag)
|
|
|
|
{
|
2015-05-20 13:30:05 +00:00
|
|
|
nsCOMPtr<nsIInternalPluginTag> internalTag(do_QueryInterface(aPluginTag));
|
|
|
|
uint32_t fakeCount = mFakePlugins.Length();
|
|
|
|
for (uint32_t i = 0; i < fakeCount; i++) {
|
|
|
|
if (mFakePlugins[i] == internalTag) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-19 01:05:23 +00:00
|
|
|
nsPluginTag* tag;
|
|
|
|
for (tag = mPlugins; tag; tag = tag->mNext) {
|
2015-05-20 13:30:05 +00:00
|
|
|
if (tag == internalTag) {
|
2011-09-30 06:02:59 +00:00
|
|
|
return true;
|
2011-02-19 01:05:23 +00:00
|
|
|
}
|
|
|
|
}
|
2011-09-30 06:02:59 +00:00
|
|
|
return false;
|
2011-02-19 01:05:23 +00:00
|
|
|
}
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
// FIXME-jsplugins what should happen with jsplugins here, if anything?
|
2012-07-23 17:52:51 +00:00
|
|
|
nsPluginTag*
|
|
|
|
nsPluginHost::HaveSamePlugin(const nsPluginTag* aPluginTag)
|
|
|
|
{
|
|
|
|
for (nsPluginTag* tag = mPlugins; tag; tag = tag->mNext) {
|
|
|
|
if (tag->HasSameNameAndMimes(aPluginTag)) {
|
|
|
|
return tag;
|
|
|
|
}
|
|
|
|
}
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr;
|
2012-07-23 17:52:51 +00:00
|
|
|
}
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
// Don't have to worry about fake plugins here, since this is only used during
|
|
|
|
// the plugin directory scan, which doesn't pick up fake plugins.
|
2012-07-23 17:52:51 +00:00
|
|
|
nsPluginTag*
|
|
|
|
nsPluginHost::FirstPluginWithPath(const nsCString& path)
|
|
|
|
{
|
|
|
|
for (nsPluginTag* tag = mPlugins; tag; tag = tag->mNext) {
|
|
|
|
if (tag->mFullPath.Equals(path)) {
|
|
|
|
return tag;
|
|
|
|
}
|
|
|
|
}
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr;
|
2012-07-23 17:52:51 +00:00
|
|
|
}
|
|
|
|
|
2014-10-29 15:05:36 +00:00
|
|
|
nsPluginTag*
|
|
|
|
nsPluginHost::PluginWithId(uint32_t aId)
|
|
|
|
{
|
|
|
|
for (nsPluginTag* tag = mPlugins; tag; tag = tag->mNext) {
|
|
|
|
if (tag->mId == aId) {
|
|
|
|
return tag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2012-07-23 17:52:51 +00:00
|
|
|
namespace {
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
int64_t GetPluginLastModifiedTime(const nsCOMPtr<nsIFile>& localfile)
|
2012-07-23 17:52:51 +00:00
|
|
|
{
|
2012-10-25 23:25:59 +00:00
|
|
|
PRTime fileModTime = 0;
|
2012-07-23 17:52:51 +00:00
|
|
|
|
|
|
|
#if defined(XP_MACOSX)
|
|
|
|
// On OS X the date of a bundle's "contents" (i.e. of its Info.plist file)
|
|
|
|
// is a much better guide to when it was last modified than the date of
|
|
|
|
// its package directory. See bug 313700.
|
|
|
|
nsCOMPtr<nsILocalFileMac> localFileMac = do_QueryInterface(localfile);
|
|
|
|
if (localFileMac) {
|
|
|
|
localFileMac->GetBundleContentsLastModifiedTime(&fileModTime);
|
|
|
|
} else {
|
|
|
|
localfile->GetLastModifiedTime(&fileModTime);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
localfile->GetLastModifiedTime(&fileModTime);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return fileModTime;
|
|
|
|
}
|
|
|
|
|
2014-04-19 12:17:19 +00:00
|
|
|
bool
|
|
|
|
GetPluginIsFromExtension(const nsCOMPtr<nsIFile>& pluginFile,
|
2014-04-23 13:51:17 +00:00
|
|
|
const nsCOMArray<nsIFile>& extensionDirs)
|
2014-04-19 12:17:19 +00:00
|
|
|
{
|
2014-04-23 13:51:17 +00:00
|
|
|
for (uint32_t i = 0; i < extensionDirs.Length(); ++i) {
|
2014-04-19 12:17:19 +00:00
|
|
|
bool contains;
|
2014-05-07 20:03:41 +00:00
|
|
|
if (NS_FAILED(extensionDirs[i]->Contains(pluginFile, &contains)) || !contains) {
|
2014-04-19 12:17:19 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-04-23 13:51:17 +00:00
|
|
|
void
|
|
|
|
GetExtensionDirectories(nsCOMArray<nsIFile>& dirs)
|
2014-04-19 12:17:19 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIProperties> dirService = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
|
|
|
|
if (!dirService) {
|
2014-04-23 13:51:17 +00:00
|
|
|
return;
|
2014-04-19 12:17:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> list;
|
|
|
|
nsresult rv = dirService->Get(XRE_EXTENSIONS_DIR_LIST,
|
|
|
|
NS_GET_IID(nsISimpleEnumerator),
|
|
|
|
getter_AddRefs(list));
|
|
|
|
if (NS_FAILED(rv)) {
|
2014-04-23 13:51:17 +00:00
|
|
|
return;
|
2014-04-19 12:17:19 +00:00
|
|
|
}
|
|
|
|
|
2014-04-23 13:51:17 +00:00
|
|
|
bool more;
|
|
|
|
while (NS_SUCCEEDED(list->HasMoreElements(&more)) && more) {
|
|
|
|
nsCOMPtr<nsISupports> next;
|
|
|
|
if (NS_FAILED(list->GetNext(getter_AddRefs(next)))) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIFile> file = do_QueryInterface(next);
|
|
|
|
if (file) {
|
|
|
|
file->Normalize();
|
2016-06-20 22:38:10 +00:00
|
|
|
dirs.AppendElement(file.forget());
|
2014-04-23 13:51:17 +00:00
|
|
|
}
|
|
|
|
}
|
2014-04-19 12:17:19 +00:00
|
|
|
}
|
|
|
|
|
2012-11-29 23:00:04 +00:00
|
|
|
struct CompareFilesByTime
|
2012-07-23 17:52:51 +00:00
|
|
|
{
|
2012-11-29 23:00:04 +00:00
|
|
|
bool
|
|
|
|
LessThan(const nsCOMPtr<nsIFile>& a, const nsCOMPtr<nsIFile>& b) const
|
2012-07-23 17:52:51 +00:00
|
|
|
{
|
2012-10-03 14:13:19 +00:00
|
|
|
return GetPluginLastModifiedTime(a) < GetPluginLastModifiedTime(b);
|
2012-07-23 17:52:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Equals(const nsCOMPtr<nsIFile>& a, const nsCOMPtr<nsIFile>& b) const
|
|
|
|
{
|
2012-10-03 14:13:18 +00:00
|
|
|
return GetPluginLastModifiedTime(a) == GetPluginLastModifiedTime(b);
|
2012-07-23 17:52:51 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-07-13 15:25:42 +00:00
|
|
|
} // namespace
|
2012-07-23 17:52:51 +00:00
|
|
|
|
2015-07-09 22:03:00 +00:00
|
|
|
bool
|
|
|
|
nsPluginHost::ShouldAddPlugin(nsPluginTag* aPluginTag)
|
|
|
|
{
|
|
|
|
#if defined(XP_WIN) && (defined(__x86_64__) || defined(_M_X64))
|
2015-11-18 22:53:27 +00:00
|
|
|
// On 64-bit windows, the only plugins we should load are flash and
|
|
|
|
// silverlight. Use library filename and MIME type to check.
|
2015-05-20 13:30:05 +00:00
|
|
|
if (StringBeginsWith(aPluginTag->FileName(), NS_LITERAL_CSTRING("NPSWF"), nsCaseInsensitiveCStringComparator()) &&
|
2015-07-09 22:03:00 +00:00
|
|
|
(aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-shockwave-flash")) ||
|
|
|
|
aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-shockwave-flash-test")))) {
|
|
|
|
return true;
|
|
|
|
}
|
2015-11-17 00:00:43 +00:00
|
|
|
if (StringBeginsWith(aPluginTag->FileName(), NS_LITERAL_CSTRING("npctrl"), nsCaseInsensitiveCStringComparator()) &&
|
2015-11-18 22:53:27 +00:00
|
|
|
(aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-silverlight-test")) ||
|
2015-11-17 00:00:43 +00:00
|
|
|
aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-silverlight-2")) ||
|
|
|
|
aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-silverlight")))) {
|
|
|
|
return true;
|
|
|
|
}
|
2015-07-09 22:03:00 +00:00
|
|
|
// Accept the test plugin MIME types, so mochitests still work.
|
|
|
|
if (aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-test")) ||
|
|
|
|
aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-Second-Test")) ||
|
|
|
|
aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-java-test"))) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#ifdef PLUGIN_LOGGING
|
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
2015-05-20 13:30:05 +00:00
|
|
|
("ShouldAddPlugin : Ignoring non-flash plugin library %s\n", aPluginTag->FileName().get()));
|
2015-07-09 22:03:00 +00:00
|
|
|
#endif // PLUGIN_LOGGING
|
|
|
|
return false;
|
|
|
|
#else
|
|
|
|
return true;
|
|
|
|
#endif // defined(XP_WIN) && (defined(__x86_64__) || defined(_M_X64))
|
|
|
|
}
|
|
|
|
|
2014-10-29 15:05:36 +00:00
|
|
|
void
|
|
|
|
nsPluginHost::AddPluginTag(nsPluginTag* aPluginTag)
|
|
|
|
{
|
2015-07-09 22:03:00 +00:00
|
|
|
if (!ShouldAddPlugin(aPluginTag)) {
|
|
|
|
return;
|
|
|
|
}
|
2014-10-29 15:05:36 +00:00
|
|
|
aPluginTag->mNext = mPlugins;
|
|
|
|
mPlugins = aPluginTag;
|
|
|
|
|
|
|
|
if (aPluginTag->IsActive()) {
|
|
|
|
nsAdoptingCString disableFullPage =
|
|
|
|
Preferences::GetCString(kPrefDisableFullPage);
|
2015-05-20 13:30:05 +00:00
|
|
|
for (uint32_t i = 0; i < aPluginTag->MimeTypes().Length(); i++) {
|
|
|
|
if (!IsTypeInList(aPluginTag->MimeTypes()[i], disableFullPage)) {
|
|
|
|
RegisterWithCategoryManager(aPluginTag->MimeTypes()[i],
|
2014-10-29 15:05:36 +00:00
|
|
|
ePluginRegister);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-29 13:16:33 +00:00
|
|
|
static bool
|
|
|
|
PluginInfoIsFlash(const nsPluginInfo& info)
|
|
|
|
{
|
2016-10-12 17:49:24 +00:00
|
|
|
if (!info.fName || strcmp(info.fName, "Shockwave Flash") != 0) {
|
2016-09-29 13:16:33 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
for (uint32_t i = 0; i < info.fVariantCount; ++i) {
|
|
|
|
if (info.fMimeTypeArray[i] &&
|
|
|
|
(!strcmp(info.fMimeTypeArray[i], "application/x-shockwave-flash") ||
|
|
|
|
!strcmp(info.fMimeTypeArray[i], "application/x-shockwave-flash-test"))) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2008-09-15 12:45:01 +00:00
|
|
|
typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
|
2002-04-27 01:47:18 +00:00
|
|
|
|
2011-03-31 18:26:57 +00:00
|
|
|
nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
2011-09-29 06:19:26 +00:00
|
|
|
bool aCreatePluginList,
|
|
|
|
bool *aPluginsChanged)
|
2000-02-01 00:42:52 +00:00
|
|
|
{
|
2015-07-04 01:29:00 +00:00
|
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
2014-10-29 15:05:36 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aPluginsChanged);
|
2001-11-17 15:26:02 +00:00
|
|
|
nsresult rv;
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2011-09-30 06:02:59 +00:00
|
|
|
*aPluginsChanged = false;
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2001-11-17 15:26:02 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString dirPath;
|
2002-04-27 05:33:09 +00:00
|
|
|
pluginsDir->GetNativePath(dirPath);
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_BASIC,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::ScanPluginsDirectory dir=%s\n", dirPath.get()));
|
2001-11-17 15:26:02 +00:00
|
|
|
#endif
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2016-09-29 13:16:33 +00:00
|
|
|
bool flashOnly = Preferences::GetBool("plugin.load_flash_only", true);
|
|
|
|
|
2001-11-17 15:26:02 +00:00
|
|
|
nsCOMPtr<nsISimpleEnumerator> iter;
|
|
|
|
rv = pluginsDir->GetDirectoryEntries(getter_AddRefs(iter));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2002-01-26 00:44:47 +00:00
|
|
|
|
2016-02-02 15:36:30 +00:00
|
|
|
AutoTArray<nsCOMPtr<nsIFile>, 6> pluginFiles;
|
2006-01-19 03:40:06 +00:00
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool hasMore;
|
2002-02-11 23:09:38 +00:00
|
|
|
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
|
2001-11-17 15:26:02 +00:00
|
|
|
nsCOMPtr<nsISupports> supports;
|
|
|
|
rv = iter->GetNext(getter_AddRefs(supports));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
continue;
|
2012-06-06 02:08:30 +00:00
|
|
|
nsCOMPtr<nsIFile> dirEntry(do_QueryInterface(supports, &rv));
|
2001-11-17 15:26:02 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
continue;
|
2003-03-22 04:04:55 +00:00
|
|
|
|
|
|
|
// Sun's JRE 1.3.1 plugin must have symbolic links resolved or else it'll crash.
|
2004-10-11 04:01:49 +00:00
|
|
|
// See bug 197855.
|
2003-03-22 04:04:55 +00:00
|
|
|
dirEntry->Normalize();
|
|
|
|
|
2006-11-08 16:43:17 +00:00
|
|
|
if (nsPluginsDir::IsPluginFile(dirEntry)) {
|
2011-05-28 04:08:26 +00:00
|
|
|
pluginFiles.AppendElement(dirEntry);
|
2006-11-08 16:43:17 +00:00
|
|
|
}
|
2011-05-28 04:08:26 +00:00
|
|
|
}
|
2002-01-26 00:44:47 +00:00
|
|
|
|
2012-07-23 17:52:51 +00:00
|
|
|
pluginFiles.Sort(CompareFilesByTime());
|
|
|
|
|
2014-04-23 13:51:17 +00:00
|
|
|
nsCOMArray<nsIFile> extensionDirs;
|
|
|
|
GetExtensionDirectories(extensionDirs);
|
2014-04-19 12:17:19 +00:00
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
for (int32_t i = (pluginFiles.Length() - 1); i >= 0; i--) {
|
2012-06-06 02:08:30 +00:00
|
|
|
nsCOMPtr<nsIFile>& localfile = pluginFiles[i];
|
2011-05-28 04:08:26 +00:00
|
|
|
|
|
|
|
nsString utf16FilePath;
|
|
|
|
rv = localfile->GetPath(utf16FilePath);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
continue;
|
|
|
|
|
2014-04-19 12:17:19 +00:00
|
|
|
const int64_t fileModTime = GetPluginLastModifiedTime(localfile);
|
|
|
|
const bool fromExtension = GetPluginIsFromExtension(localfile, extensionDirs);
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// Look for it in our cache
|
2011-05-28 04:08:26 +00:00
|
|
|
NS_ConvertUTF16toUTF8 filePath(utf16FilePath);
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginTag> pluginTag;
|
2012-06-14 02:51:21 +00:00
|
|
|
RemoveCachedPluginsInfo(filePath.get(), getter_AddRefs(pluginTag));
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool seenBefore = false;
|
2013-02-15 21:00:25 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
if (pluginTag) {
|
2011-09-30 06:02:59 +00:00
|
|
|
seenBefore = true;
|
2005-11-25 08:16:51 +00:00
|
|
|
// If plugin changed, delete cachedPluginTag and don't use cache
|
2012-10-03 14:13:18 +00:00
|
|
|
if (fileModTime != pluginTag->mLastModifiedTime) {
|
2005-11-25 08:16:51 +00:00
|
|
|
// Plugins has changed. Don't use cached plugin info.
|
2012-07-30 14:20:58 +00:00
|
|
|
pluginTag = nullptr;
|
2002-02-11 23:09:38 +00:00
|
|
|
|
|
|
|
// plugin file changed, flag this fact
|
2011-09-30 06:02:59 +00:00
|
|
|
*aPluginsChanged = true;
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
|
|
|
|
2010-10-13 15:50:35 +00:00
|
|
|
// If we're not creating a list and we already know something changed then
|
|
|
|
// we're done.
|
|
|
|
if (!aCreatePluginList) {
|
|
|
|
if (*aPluginsChanged) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2002-02-11 23:09:38 +00:00
|
|
|
continue;
|
2010-10-13 15:50:35 +00:00
|
|
|
}
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2010-12-20 23:38:04 +00:00
|
|
|
bool isKnownInvalidPlugin = false;
|
2015-10-18 05:24:48 +00:00
|
|
|
for (RefPtr<nsInvalidPluginTag> invalidPlugins = mInvalidPlugins;
|
2010-12-09 22:28:15 +00:00
|
|
|
invalidPlugins; invalidPlugins = invalidPlugins->mNext) {
|
|
|
|
// If already marked as invalid, ignore it
|
|
|
|
if (invalidPlugins->mFullPath.Equals(filePath.get()) &&
|
|
|
|
invalidPlugins->mLastModifiedTime == fileModTime) {
|
|
|
|
if (aCreatePluginList) {
|
|
|
|
invalidPlugins->mSeen = true;
|
|
|
|
}
|
|
|
|
isKnownInvalidPlugin = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (isKnownInvalidPlugin) {
|
|
|
|
continue;
|
|
|
|
}
|
2000-02-01 00:42:52 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// if it is not found in cache info list or has been changed, create a new one
|
|
|
|
if (!pluginTag) {
|
2011-05-28 04:08:26 +00:00
|
|
|
nsPluginFile pluginFile(localfile);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// create a tag describing this plugin.
|
2012-07-30 14:20:58 +00:00
|
|
|
PRLibrary *library = nullptr;
|
2008-12-09 17:15:49 +00:00
|
|
|
nsPluginInfo info;
|
|
|
|
memset(&info, 0, sizeof(info));
|
2013-04-01 17:38:48 +00:00
|
|
|
nsresult res;
|
|
|
|
// Opening a block for the telemetry AutoTimer
|
|
|
|
{
|
|
|
|
Telemetry::AutoTimer<Telemetry::PLUGIN_LOAD_METADATA> telemetry;
|
|
|
|
res = pluginFile.GetPluginInfo(info, &library);
|
|
|
|
}
|
2008-12-09 17:15:49 +00:00
|
|
|
// if we don't have mime type don't proceed, this is not a plugin
|
2016-09-29 13:16:33 +00:00
|
|
|
if (NS_FAILED(res) || !info.fMimeTypeArray ||
|
|
|
|
(flashOnly && !PluginInfoIsFlash(info))) {
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(filePath.get(),
|
2010-12-09 22:28:15 +00:00
|
|
|
fileModTime);
|
2001-10-17 00:39:21 +00:00
|
|
|
pluginFile.FreePluginInfo(info);
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
if (aCreatePluginList) {
|
2010-12-20 23:38:04 +00:00
|
|
|
invalidTag->mSeen = true;
|
2010-12-09 22:28:15 +00:00
|
|
|
}
|
|
|
|
invalidTag->mNext = mInvalidPlugins;
|
|
|
|
if (mInvalidPlugins) {
|
|
|
|
mInvalidPlugins->mPrev = invalidTag;
|
|
|
|
}
|
|
|
|
mInvalidPlugins = invalidTag;
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
// Mark aPluginsChanged so pluginreg is rewritten
|
2011-09-30 06:02:59 +00:00
|
|
|
*aPluginsChanged = true;
|
2002-02-11 23:09:38 +00:00
|
|
|
continue;
|
2001-10-17 00:39:21 +00:00
|
|
|
}
|
2002-04-27 01:47:18 +00:00
|
|
|
|
2014-04-19 12:17:19 +00:00
|
|
|
pluginTag = new nsPluginTag(&info, fileModTime, fromExtension);
|
2002-02-11 23:09:38 +00:00
|
|
|
pluginFile.FreePluginInfo(info);
|
2010-08-18 00:05:48 +00:00
|
|
|
pluginTag->mLibrary = library;
|
2015-02-25 16:36:39 +00:00
|
|
|
uint32_t state;
|
|
|
|
rv = pluginTag->GetBlocklistState(&state);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2013-06-19 15:07:28 +00:00
|
|
|
|
|
|
|
// If the blocklist says it is risky and we have never seen this
|
|
|
|
// plugin before, then disable it.
|
|
|
|
if (state == nsIBlocklistService::STATE_SOFTBLOCKED && !seenBefore) {
|
|
|
|
pluginTag->SetEnabledState(nsIPluginTag::STATE_DISABLED);
|
|
|
|
}
|
2008-11-02 12:13:48 +00:00
|
|
|
|
2010-08-18 00:05:48 +00:00
|
|
|
// Plugin unloading is tag-based. If we created a new tag and loaded
|
|
|
|
// the library in the process then we want to attempt to unload it here.
|
|
|
|
// Only do this if the pref is set for aggressive unloading.
|
|
|
|
if (UnloadPluginsASAP()) {
|
2012-02-14 18:03:24 +00:00
|
|
|
pluginTag->TryUnloadPlugin(false);
|
2010-08-18 00:05:48 +00:00
|
|
|
}
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
2000-09-22 00:58:46 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
// do it if we still want it
|
2012-06-14 02:51:21 +00:00
|
|
|
if (!seenBefore) {
|
|
|
|
// We have a valid new plugin so report that plugins have changed.
|
|
|
|
*aPluginsChanged = true;
|
|
|
|
}
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2015-08-31 20:51:19 +00:00
|
|
|
// Avoid adding different versions of the same plugin if they are running
|
|
|
|
// in-process, otherwise we risk undefined behaviour.
|
|
|
|
if (!nsNPAPIPlugin::RunPluginOOP(pluginTag)) {
|
|
|
|
if (HaveSamePlugin(pluginTag)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-23 17:52:51 +00:00
|
|
|
// Don't add the same plugin again if it hasn't changed
|
|
|
|
if (nsPluginTag* duplicate = FirstPluginWithPath(pluginTag->mFullPath)) {
|
2012-10-03 14:13:18 +00:00
|
|
|
if (pluginTag->mLastModifiedTime == duplicate->mLastModifiedTime) {
|
2012-07-23 17:52:51 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2010-10-13 15:50:35 +00:00
|
|
|
|
2012-06-14 02:51:21 +00:00
|
|
|
// If we're not creating a plugin list, simply looking for changes,
|
|
|
|
// then we're done.
|
|
|
|
if (!aCreatePluginList) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2010-10-13 15:50:35 +00:00
|
|
|
|
2014-10-29 15:05:36 +00:00
|
|
|
AddPluginTag(pluginTag);
|
2001-08-16 02:59:03 +00:00
|
|
|
}
|
2011-05-28 04:08:26 +00:00
|
|
|
|
2000-09-22 00:58:46 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-02-01 00:42:52 +00:00
|
|
|
|
2011-03-31 18:26:57 +00:00
|
|
|
nsresult nsPluginHost::ScanPluginsDirectoryList(nsISimpleEnumerator *dirEnum,
|
2011-09-29 06:19:26 +00:00
|
|
|
bool aCreatePluginList,
|
|
|
|
bool *aPluginsChanged)
|
2001-11-17 15:26:02 +00:00
|
|
|
{
|
2015-07-04 01:29:00 +00:00
|
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
2014-10-29 15:05:36 +00:00
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool hasMore;
|
2001-11-17 15:26:02 +00:00
|
|
|
while (NS_SUCCEEDED(dirEnum->HasMoreElements(&hasMore)) && hasMore) {
|
|
|
|
nsCOMPtr<nsISupports> supports;
|
|
|
|
nsresult rv = dirEnum->GetNext(getter_AddRefs(supports));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
continue;
|
|
|
|
nsCOMPtr<nsIFile> nextDir(do_QueryInterface(supports, &rv));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
continue;
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// don't pass aPluginsChanged directly to prevent it from been reset
|
2011-09-29 06:19:26 +00:00
|
|
|
bool pluginschanged = false;
|
2011-03-31 18:26:57 +00:00
|
|
|
ScanPluginsDirectory(nextDir, aCreatePluginList, &pluginschanged);
|
2002-02-11 23:09:38 +00:00
|
|
|
|
|
|
|
if (pluginschanged)
|
2011-09-30 06:02:59 +00:00
|
|
|
*aPluginsChanged = true;
|
2002-02-11 23:09:38 +00:00
|
|
|
|
|
|
|
// if changes are detected and we are not creating the list, do not proceed
|
|
|
|
if (!aCreatePluginList && *aPluginsChanged)
|
|
|
|
break;
|
2001-11-17 15:26:02 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2014-10-29 15:05:36 +00:00
|
|
|
void
|
|
|
|
nsPluginHost::IncrementChromeEpoch()
|
|
|
|
{
|
2015-07-04 01:29:00 +00:00
|
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
2014-10-29 15:05:36 +00:00
|
|
|
mPluginEpoch++;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
nsPluginHost::ChromeEpoch()
|
|
|
|
{
|
2015-07-04 01:29:00 +00:00
|
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
2014-10-29 15:05:36 +00:00
|
|
|
return mPluginEpoch;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
nsPluginHost::ChromeEpochForContent()
|
|
|
|
{
|
2015-07-04 01:29:00 +00:00
|
|
|
MOZ_ASSERT(XRE_IsContentProcess());
|
2014-10-29 15:05:36 +00:00
|
|
|
return mPluginEpoch;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPluginHost::SetChromeEpochForContent(uint32_t aEpoch)
|
|
|
|
{
|
2015-07-04 01:29:00 +00:00
|
|
|
MOZ_ASSERT(XRE_IsContentProcess());
|
2014-10-29 15:05:36 +00:00
|
|
|
mPluginEpoch = aEpoch;
|
|
|
|
}
|
|
|
|
|
2015-02-10 19:58:01 +00:00
|
|
|
#ifdef XP_WIN
|
|
|
|
static void
|
|
|
|
WatchRegKey(uint32_t aRoot, nsCOMPtr<nsIWindowsRegKey>& aKey)
|
|
|
|
{
|
|
|
|
if (aKey) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
aKey = do_CreateInstance("@mozilla.org/windows-registry-key;1");
|
|
|
|
if (!aKey) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
nsresult rv = aKey->Open(aRoot,
|
|
|
|
NS_LITERAL_STRING("Software\\MozillaPlugins"),
|
|
|
|
nsIWindowsRegKey::ACCESS_READ | nsIWindowsRegKey::ACCESS_NOTIFY);
|
2016-10-04 17:18:17 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2015-02-10 19:58:01 +00:00
|
|
|
aKey = nullptr;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
aKey->StartWatching(true);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-05-21 13:28:54 +00:00
|
|
|
nsresult nsPluginHost::LoadPlugins()
|
2000-09-22 00:58:46 +00:00
|
|
|
{
|
2012-01-29 04:16:26 +00:00
|
|
|
#ifdef ANDROID
|
2015-07-04 01:29:00 +00:00
|
|
|
if (XRE_IsContentProcess()) {
|
2012-01-29 04:16:26 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
#endif
|
2000-09-22 00:58:46 +00:00
|
|
|
// do not do anything if it is already done
|
2002-02-11 23:09:38 +00:00
|
|
|
// use ReloadPlugins() to enforce loading
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mPluginsLoaded)
|
2000-09-22 00:58:46 +00:00
|
|
|
return NS_OK;
|
2000-02-01 00:42:52 +00:00
|
|
|
|
2009-10-05 09:00:57 +00:00
|
|
|
if (mPluginsDisabled)
|
|
|
|
return NS_OK;
|
|
|
|
|
2015-02-10 19:58:01 +00:00
|
|
|
#ifdef XP_WIN
|
|
|
|
WatchRegKey(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, mRegKeyHKLM);
|
|
|
|
WatchRegKey(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, mRegKeyHKCU);
|
|
|
|
#endif
|
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool pluginschanged;
|
2011-09-30 06:02:59 +00:00
|
|
|
nsresult rv = FindPlugins(true, &pluginschanged);
|
2002-07-01 20:36:57 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2009-07-01 13:34:31 +00:00
|
|
|
// only if plugins have changed will we notify plugin-change observers
|
2002-07-01 20:36:57 +00:00
|
|
|
if (pluginschanged) {
|
2015-07-04 01:29:00 +00:00
|
|
|
if (XRE_IsParentProcess()) {
|
2014-10-29 15:05:36 +00:00
|
|
|
IncrementChromeEpoch();
|
|
|
|
}
|
|
|
|
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 16:59:13 +00:00
|
|
|
nsCOMPtr<nsIObserverService> obsService =
|
|
|
|
mozilla::services::GetObserverService();
|
2007-07-14 00:28:05 +00:00
|
|
|
if (obsService)
|
2012-07-30 14:20:58 +00:00
|
|
|
obsService->NotifyObservers(nullptr, "plugins-list-updated", nullptr);
|
2002-07-01 20:36:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
|
|
|
|
2014-10-29 15:05:36 +00:00
|
|
|
nsresult
|
|
|
|
nsPluginHost::FindPluginsInContent(bool aCreatePluginList, bool* aPluginsChanged)
|
|
|
|
{
|
2015-07-04 01:29:00 +00:00
|
|
|
MOZ_ASSERT(XRE_IsContentProcess());
|
2014-10-29 15:05:36 +00:00
|
|
|
|
|
|
|
dom::ContentChild* cp = dom::ContentChild::GetSingleton();
|
2015-11-11 04:35:00 +00:00
|
|
|
nsresult rv;
|
2014-10-29 15:05:36 +00:00
|
|
|
nsTArray<PluginTag> plugins;
|
|
|
|
uint32_t parentEpoch;
|
2015-11-11 04:35:00 +00:00
|
|
|
if (!cp->SendFindPlugins(ChromeEpochForContent(), &rv, &plugins, &parentEpoch) ||
|
|
|
|
NS_FAILED(rv)) {
|
2014-10-29 15:05:36 +00:00
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parentEpoch != ChromeEpochForContent()) {
|
|
|
|
*aPluginsChanged = true;
|
|
|
|
if (!aCreatePluginList) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2015-12-24 01:18:57 +00:00
|
|
|
// Don't do this if aCreatePluginList is false. Otherwise, when we actually
|
|
|
|
// want to create the list, we'll come back here and do nothing.
|
|
|
|
SetChromeEpochForContent(parentEpoch);
|
|
|
|
|
2014-10-29 15:05:36 +00:00
|
|
|
for (size_t i = 0; i < plugins.Length(); i++) {
|
|
|
|
PluginTag& tag = plugins[i];
|
|
|
|
|
|
|
|
// Don't add the same plugin again.
|
2015-12-24 01:18:57 +00:00
|
|
|
if (nsPluginTag* existing = PluginWithId(tag.id())) {
|
|
|
|
UpdateInMemoryPluginInfo(existing);
|
2014-10-29 15:05:36 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPluginTag *pluginTag = new nsPluginTag(tag.id(),
|
|
|
|
tag.name().get(),
|
|
|
|
tag.description().get(),
|
|
|
|
tag.filename().get(),
|
|
|
|
"", // aFullPath
|
|
|
|
tag.version().get(),
|
|
|
|
nsTArray<nsCString>(tag.mimeTypes()),
|
|
|
|
nsTArray<nsCString>(tag.mimeDescriptions()),
|
|
|
|
nsTArray<nsCString>(tag.extensions()),
|
|
|
|
tag.isJavaPlugin(),
|
|
|
|
tag.isFlashPlugin(),
|
2015-10-12 19:31:06 +00:00
|
|
|
tag.supportsAsyncInit(),
|
2016-07-25 20:45:29 +00:00
|
|
|
tag.supportsAsyncRender(),
|
2014-10-29 15:05:36 +00:00
|
|
|
tag.lastModifiedTime(),
|
2016-02-08 11:21:20 +00:00
|
|
|
tag.isFromExtension(),
|
|
|
|
tag.sandboxLevel());
|
2014-10-29 15:05:36 +00:00
|
|
|
AddPluginTag(pluginTag);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mPluginsLoaded = true;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// if aCreatePluginList is false we will just scan for plugins
|
|
|
|
// and see if any changes have been made to the plugins.
|
|
|
|
// This is needed in ReloadPlugins to prevent possible recursive reloads
|
2011-09-29 06:19:26 +00:00
|
|
|
nsresult nsPluginHost::FindPlugins(bool aCreatePluginList, bool * aPluginsChanged)
|
2002-02-11 23:09:38 +00:00
|
|
|
{
|
2011-07-01 21:39:17 +00:00
|
|
|
Telemetry::AutoTimer<Telemetry::FIND_PLUGINS> telemetry;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aPluginsChanged);
|
|
|
|
|
2011-09-30 06:02:59 +00:00
|
|
|
*aPluginsChanged = false;
|
2014-10-29 15:05:36 +00:00
|
|
|
|
2015-07-04 01:29:00 +00:00
|
|
|
if (XRE_IsContentProcess()) {
|
2014-10-29 15:05:36 +00:00
|
|
|
return FindPluginsInContent(aCreatePluginList, aPluginsChanged);
|
|
|
|
}
|
|
|
|
|
2001-11-17 15:26:02 +00:00
|
|
|
nsresult rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2009-09-22 07:46:32 +00:00
|
|
|
// Read cached plugins info. If the profile isn't yet available then don't
|
|
|
|
// scan for plugins
|
|
|
|
if (ReadPluginInfo() == NS_ERROR_NOT_AVAILABLE)
|
|
|
|
return NS_OK;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2007-07-20 20:34:51 +00:00
|
|
|
#ifdef XP_WIN
|
2002-07-14 00:39:35 +00:00
|
|
|
// Failure here is not a show-stopper so just warn.
|
2001-11-17 15:26:02 +00:00
|
|
|
rv = EnsurePrivateDirServiceProvider();
|
2006-03-30 18:40:56 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to register dir service provider.");
|
2007-07-20 20:34:51 +00:00
|
|
|
#endif /* XP_WIN */
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-11-17 15:26:02 +00:00
|
|
|
nsCOMPtr<nsIProperties> dirService(do_GetService(kDirectoryServiceContractID, &rv));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-11-17 15:26:02 +00:00
|
|
|
nsCOMPtr<nsISimpleEnumerator> dirList;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// Scan plugins directories;
|
2004-10-11 04:01:49 +00:00
|
|
|
// don't pass aPluginsChanged directly, to prevent its
|
2002-02-11 23:09:38 +00:00
|
|
|
// possible reset in subsequent ScanPluginsDirectory calls
|
2011-09-29 06:19:26 +00:00
|
|
|
bool pluginschanged = false;
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2002-09-20 18:47:49 +00:00
|
|
|
// Scan the app-defined list of plugin dirs.
|
2001-11-17 15:26:02 +00:00
|
|
|
rv = dirService->Get(NS_APP_PLUGINS_DIR_LIST, NS_GET_IID(nsISimpleEnumerator), getter_AddRefs(dirList));
|
2002-02-11 23:09:38 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2011-03-31 18:26:57 +00:00
|
|
|
ScanPluginsDirectoryList(dirList, aCreatePluginList, &pluginschanged);
|
2002-02-11 23:09:38 +00:00
|
|
|
|
|
|
|
if (pluginschanged)
|
2011-09-30 06:02:59 +00:00
|
|
|
*aPluginsChanged = true;
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// if we are just looking for possible changes,
|
2002-02-11 23:09:38 +00:00
|
|
|
// no need to proceed if changes are detected
|
|
|
|
if (!aCreatePluginList && *aPluginsChanged) {
|
2015-10-18 05:24:48 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2002-02-11 23:09:38 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2011-09-16 21:34:31 +00:00
|
|
|
} else {
|
|
|
|
#ifdef ANDROID
|
|
|
|
LOG("getting plugins dir failed");
|
|
|
|
#endif
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2011-09-30 06:02:59 +00:00
|
|
|
mPluginsLoaded = true; // at this point 'some' plugins have been loaded,
|
2001-11-17 15:26:02 +00:00
|
|
|
// the rest is optional
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2007-07-20 20:34:51 +00:00
|
|
|
#ifdef XP_WIN
|
2012-04-04 04:09:20 +00:00
|
|
|
bool bScanPLIDs = Preferences::GetBool("plugin.scan.plid.all", false);
|
2003-05-27 21:14:55 +00:00
|
|
|
|
|
|
|
// Now lets scan any PLID directories
|
|
|
|
if (bScanPLIDs && mPrivateDirServiceProvider) {
|
|
|
|
rv = mPrivateDirServiceProvider->GetPLIDDirectories(getter_AddRefs(dirList));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2011-03-31 18:26:57 +00:00
|
|
|
ScanPluginsDirectoryList(dirList, aCreatePluginList, &pluginschanged);
|
2003-05-27 21:14:55 +00:00
|
|
|
|
|
|
|
if (pluginschanged)
|
2011-09-30 06:02:59 +00:00
|
|
|
*aPluginsChanged = true;
|
2003-05-27 21:14:55 +00:00
|
|
|
|
|
|
|
// if we are just looking for possible changes,
|
|
|
|
// no need to proceed if changes are detected
|
|
|
|
if (!aCreatePluginList && *aPluginsChanged) {
|
2015-10-18 05:24:48 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2003-05-27 21:14:55 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-09-20 18:47:49 +00:00
|
|
|
// Scan the installation paths of our popular plugins if the prefs are enabled
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
// This table controls the order of scanning
|
2013-02-17 12:07:50 +00:00
|
|
|
const char* const prefs[] = {NS_WIN_ACROBAT_SCAN_KEY,
|
2011-03-31 18:26:57 +00:00
|
|
|
NS_WIN_QUICKTIME_SCAN_KEY,
|
|
|
|
NS_WIN_WMP_SCAN_KEY};
|
2002-05-01 02:01:50 +00:00
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t size = sizeof(prefs) / sizeof(prefs[0]);
|
2002-05-01 02:01:50 +00:00
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
for (uint32_t i = 0; i < size; i+=1) {
|
2002-05-01 02:01:50 +00:00
|
|
|
nsCOMPtr<nsIFile> dirToScan;
|
2011-09-29 06:19:26 +00:00
|
|
|
bool bExists;
|
2002-05-01 02:01:50 +00:00
|
|
|
if (NS_SUCCEEDED(dirService->Get(prefs[i], NS_GET_IID(nsIFile), getter_AddRefs(dirToScan))) &&
|
|
|
|
dirToScan &&
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_SUCCEEDED(dirToScan->Exists(&bExists)) &&
|
2002-05-01 02:01:50 +00:00
|
|
|
bExists) {
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2011-03-31 18:26:57 +00:00
|
|
|
ScanPluginsDirectory(dirToScan, aCreatePluginList, &pluginschanged);
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
if (pluginschanged)
|
2011-09-30 06:02:59 +00:00
|
|
|
*aPluginsChanged = true;
|
2002-05-01 02:01:50 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// if we are just looking for possible changes,
|
2002-05-01 02:01:50 +00:00
|
|
|
// no need to proceed if changes are detected
|
|
|
|
if (!aCreatePluginList && *aPluginsChanged) {
|
2015-10-18 05:24:48 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2002-05-01 02:01:50 +00:00
|
|
|
return NS_OK;
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
2001-02-07 01:13:01 +00:00
|
|
|
}
|
2001-11-17 15:26:02 +00:00
|
|
|
#endif
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2012-06-14 02:51:21 +00:00
|
|
|
// We should also consider plugins to have changed if any plugins have been removed.
|
|
|
|
// We'll know if any were removed if they weren't taken out of the cached plugins list
|
|
|
|
// during our scan, thus we can assume something was removed if the cached plugins list
|
|
|
|
// contains anything.
|
|
|
|
if (!*aPluginsChanged && mCachedPlugins) {
|
|
|
|
*aPluginsChanged = true;
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
2012-06-14 02:51:21 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
// Remove unseen invalid plugins
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsInvalidPluginTag> invalidPlugins = mInvalidPlugins;
|
2010-12-09 22:28:15 +00:00
|
|
|
while (invalidPlugins) {
|
|
|
|
if (!invalidPlugins->mSeen) {
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsInvalidPluginTag> invalidPlugin = invalidPlugins;
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
if (invalidPlugin->mPrev) {
|
|
|
|
invalidPlugin->mPrev->mNext = invalidPlugin->mNext;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mInvalidPlugins = invalidPlugin->mNext;
|
|
|
|
}
|
|
|
|
if (invalidPlugin->mNext) {
|
2012-11-29 23:00:04 +00:00
|
|
|
invalidPlugin->mNext->mPrev = invalidPlugin->mPrev;
|
2010-12-09 22:28:15 +00:00
|
|
|
}
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
invalidPlugins = invalidPlugin->mNext;
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2013-10-23 20:34:30 +00:00
|
|
|
invalidPlugin->mPrev = nullptr;
|
|
|
|
invalidPlugin->mNext = nullptr;
|
2010-12-09 22:28:15 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-12-20 23:38:04 +00:00
|
|
|
invalidPlugins->mSeen = false;
|
2010-12-09 22:28:15 +00:00
|
|
|
invalidPlugins = invalidPlugins->mNext;
|
|
|
|
}
|
|
|
|
}
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// if we are not creating the list, there is no need to proceed
|
|
|
|
if (!aCreatePluginList) {
|
2015-10-18 05:24:48 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2002-02-11 23:09:38 +00:00
|
|
|
return NS_OK;
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// if we are creating the list, it is already done;
|
|
|
|
// update the plugins info cache if changes are detected
|
|
|
|
if (*aPluginsChanged)
|
2002-08-14 22:31:59 +00:00
|
|
|
WritePluginInfo();
|
2002-02-11 23:09:38 +00:00
|
|
|
|
|
|
|
// No more need for cached plugins. Clear it up.
|
2015-10-18 05:24:48 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2000-09-22 00:58:46 +00:00
|
|
|
return NS_OK;
|
2000-02-01 00:42:52 +00:00
|
|
|
}
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2015-11-11 04:35:00 +00:00
|
|
|
nsresult
|
2014-10-29 15:05:36 +00:00
|
|
|
mozilla::plugins::FindPluginsForContent(uint32_t aPluginEpoch,
|
|
|
|
nsTArray<PluginTag>* aPlugins,
|
|
|
|
uint32_t* aNewPluginEpoch)
|
|
|
|
{
|
2015-07-04 01:29:00 +00:00
|
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
2014-10-29 15:05:36 +00:00
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
|
2015-11-11 04:35:00 +00:00
|
|
|
return host->FindPluginsForContent(aPluginEpoch, aPlugins, aNewPluginEpoch);
|
2014-10-29 15:05:36 +00:00
|
|
|
}
|
|
|
|
|
2015-11-11 04:35:00 +00:00
|
|
|
nsresult
|
2014-10-29 15:05:36 +00:00
|
|
|
nsPluginHost::FindPluginsForContent(uint32_t aPluginEpoch,
|
|
|
|
nsTArray<PluginTag>* aPlugins,
|
|
|
|
uint32_t* aNewPluginEpoch)
|
|
|
|
{
|
2015-07-04 01:29:00 +00:00
|
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
2014-10-29 15:05:36 +00:00
|
|
|
|
|
|
|
// Load plugins so that the epoch is correct.
|
2015-11-11 04:35:00 +00:00
|
|
|
nsresult rv = LoadPlugins();
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2014-10-29 15:05:36 +00:00
|
|
|
|
|
|
|
*aNewPluginEpoch = ChromeEpoch();
|
|
|
|
if (aPluginEpoch == ChromeEpoch()) {
|
2015-11-11 04:35:00 +00:00
|
|
|
return NS_OK;
|
2014-10-29 15:05:36 +00:00
|
|
|
}
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
nsTArray<nsCOMPtr<nsIInternalPluginTag>> plugins;
|
2015-07-14 13:21:14 +00:00
|
|
|
GetPlugins(plugins, true);
|
2014-10-29 15:05:36 +00:00
|
|
|
|
|
|
|
for (size_t i = 0; i < plugins.Length(); i++) {
|
2015-05-20 13:30:05 +00:00
|
|
|
nsCOMPtr<nsIInternalPluginTag> basetag = plugins[i];
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
nsCOMPtr<nsIFakePluginTag> faketag = do_QueryInterface(basetag);
|
|
|
|
if (faketag) {
|
|
|
|
/// FIXME-jsplugins - We need to make content processes properly
|
|
|
|
/// aware of jsplugins (and add a nsIInternalPluginTag->AsNative() to
|
|
|
|
/// avoid this hacky static cast)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// FIXME-jsplugins - We need to cleanup the various plugintag classes
|
|
|
|
/// to be more sane and avoid this dance
|
2015-05-20 13:30:05 +00:00
|
|
|
nsPluginTag *tag = static_cast<nsPluginTag *>(basetag.get());
|
2014-11-03 23:50:05 +00:00
|
|
|
|
2014-10-29 15:05:36 +00:00
|
|
|
aPlugins->AppendElement(PluginTag(tag->mId,
|
2015-05-20 13:30:05 +00:00
|
|
|
tag->Name(),
|
|
|
|
tag->Description(),
|
|
|
|
tag->MimeTypes(),
|
|
|
|
tag->MimeDescriptions(),
|
|
|
|
tag->Extensions(),
|
2014-10-29 15:05:36 +00:00
|
|
|
tag->mIsJavaPlugin,
|
|
|
|
tag->mIsFlashPlugin,
|
2015-10-12 19:31:06 +00:00
|
|
|
tag->mSupportsAsyncInit,
|
2016-07-25 20:45:29 +00:00
|
|
|
tag->mSupportsAsyncRender,
|
2015-05-20 13:30:05 +00:00
|
|
|
tag->FileName(),
|
|
|
|
tag->Version(),
|
2014-10-29 15:05:36 +00:00
|
|
|
tag->mLastModifiedTime,
|
2016-02-08 11:21:20 +00:00
|
|
|
tag->IsFromExtension(),
|
|
|
|
tag->mSandboxLevel));
|
2014-10-29 15:05:36 +00:00
|
|
|
}
|
2015-11-11 04:35:00 +00:00
|
|
|
return NS_OK;
|
2014-10-29 15:05:36 +00:00
|
|
|
}
|
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
void
|
2015-12-24 01:18:57 +00:00
|
|
|
nsPluginHost::UpdateInMemoryPluginInfo(nsPluginTag* aPluginTag)
|
2007-07-03 21:42:35 +00:00
|
|
|
{
|
2015-10-18 05:24:48 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
|
|
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2007-07-14 00:28:05 +00:00
|
|
|
|
2012-06-29 22:28:45 +00:00
|
|
|
if (!aPluginTag) {
|
2015-02-25 16:36:39 +00:00
|
|
|
return;
|
2012-06-29 22:28:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Update types with category manager
|
|
|
|
nsAdoptingCString disableFullPage =
|
|
|
|
Preferences::GetCString(kPrefDisableFullPage);
|
2015-05-20 13:30:05 +00:00
|
|
|
for (uint32_t i = 0; i < aPluginTag->MimeTypes().Length(); i++) {
|
2012-06-29 22:28:45 +00:00
|
|
|
nsRegisterType shouldRegister;
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
if (IsTypeInList(aPluginTag->MimeTypes()[i], disableFullPage)) {
|
2012-06-29 22:28:45 +00:00
|
|
|
shouldRegister = ePluginUnregister;
|
|
|
|
} else {
|
2015-05-20 13:30:05 +00:00
|
|
|
nsPluginTag *plugin = FindNativePluginForType(aPluginTag->MimeTypes()[i],
|
2015-02-25 16:36:39 +00:00
|
|
|
true);
|
2012-06-29 22:28:45 +00:00
|
|
|
shouldRegister = plugin ? ePluginRegister : ePluginUnregister;
|
|
|
|
}
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
RegisterWithCategoryManager(aPluginTag->MimeTypes()[i], shouldRegister);
|
2012-06-29 22:28:45 +00:00
|
|
|
}
|
|
|
|
|
2012-12-21 00:53:21 +00:00
|
|
|
nsCOMPtr<nsIObserverService> obsService =
|
|
|
|
mozilla::services::GetObserverService();
|
|
|
|
if (obsService)
|
|
|
|
obsService->NotifyObservers(nullptr, "plugin-info-updated", nullptr);
|
2007-07-03 21:42:35 +00:00
|
|
|
}
|
|
|
|
|
2015-12-24 01:18:57 +00:00
|
|
|
// This function is not relevant for fake plugins.
|
|
|
|
void
|
|
|
|
nsPluginHost::UpdatePluginInfo(nsPluginTag* aPluginTag)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
|
|
|
|
|
|
|
ReadPluginInfo();
|
|
|
|
WritePluginInfo();
|
|
|
|
|
|
|
|
IncrementChromeEpoch();
|
|
|
|
|
|
|
|
UpdateInMemoryPluginInfo(aPluginTag);
|
|
|
|
}
|
|
|
|
|
2012-07-02 20:44:39 +00:00
|
|
|
/* static */ bool
|
|
|
|
nsPluginHost::IsTypeWhitelisted(const char *aMimeType)
|
|
|
|
{
|
2012-07-09 21:50:42 +00:00
|
|
|
nsAdoptingCString whitelist = Preferences::GetCString(kPrefWhitelist);
|
|
|
|
if (!whitelist.Length()) {
|
2012-07-02 20:44:39 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
nsDependentCString wrap(aMimeType);
|
2012-07-09 21:50:42 +00:00
|
|
|
return IsTypeInList(wrap, whitelist);
|
2012-07-02 20:44:39 +00:00
|
|
|
}
|
|
|
|
|
2016-01-06 01:57:11 +00:00
|
|
|
/* static */ bool
|
|
|
|
nsPluginHost::ShouldLoadTypeInParent(const nsACString& aMimeType)
|
|
|
|
{
|
|
|
|
nsCString prefName(kPrefLoadInParentPrefix);
|
|
|
|
prefName += aMimeType;
|
|
|
|
return Preferences::GetBool(prefName.get(), false);
|
|
|
|
}
|
|
|
|
|
2012-06-29 22:28:45 +00:00
|
|
|
void
|
2015-05-20 13:30:05 +00:00
|
|
|
nsPluginHost::RegisterWithCategoryManager(const nsCString& aMimeType,
|
2012-06-29 22:28:45 +00:00
|
|
|
nsRegisterType aType)
|
|
|
|
{
|
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
|
|
|
("nsPluginTag::RegisterWithCategoryManager type = %s, removing = %s\n",
|
|
|
|
aMimeType.get(), aType == ePluginUnregister ? "yes" : "no"));
|
|
|
|
|
|
|
|
nsCOMPtr<nsICategoryManager> catMan =
|
|
|
|
do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
|
|
|
|
if (!catMan) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *contractId =
|
|
|
|
"@mozilla.org/content/plugin/document-loader-factory;1";
|
|
|
|
|
|
|
|
if (aType == ePluginRegister) {
|
|
|
|
catMan->AddCategoryEntry("Gecko-Content-Viewers",
|
|
|
|
aMimeType.get(),
|
|
|
|
contractId,
|
|
|
|
false, /* persist: broken by bug 193031 */
|
|
|
|
mOverrideInternalTypes,
|
2012-07-30 14:20:58 +00:00
|
|
|
nullptr);
|
2012-06-29 22:28:45 +00:00
|
|
|
} else {
|
2015-05-20 13:30:05 +00:00
|
|
|
if (aType == ePluginMaybeUnregister) {
|
|
|
|
// Bail out if this type is still used by an enabled plugin
|
|
|
|
if (HavePluginForType(aMimeType)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(aType == ePluginUnregister, "Unknown nsRegisterType");
|
|
|
|
}
|
|
|
|
|
2012-06-29 22:28:45 +00:00
|
|
|
// Only delete the entry if a plugin registered for it
|
|
|
|
nsXPIDLCString value;
|
|
|
|
nsresult rv = catMan->GetCategoryEntry("Gecko-Content-Viewers",
|
|
|
|
aMimeType.get(),
|
|
|
|
getter_Copies(value));
|
|
|
|
if (NS_SUCCEEDED(rv) && strcmp(value, contractId) == 0) {
|
|
|
|
catMan->DeleteCategoryEntry("Gecko-Content-Viewers",
|
|
|
|
aMimeType.get(),
|
|
|
|
true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsresult
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::WritePluginInfo()
|
2002-08-14 22:31:59 +00:00
|
|
|
{
|
2015-07-04 01:29:00 +00:00
|
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID,&rv));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2007-07-26 07:01:22 +00:00
|
|
|
directoryService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
|
2003-05-27 21:14:55 +00:00
|
|
|
getter_AddRefs(mPluginRegFile));
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2003-05-27 21:14:55 +00:00
|
|
|
if (!mPluginRegFile)
|
2002-08-14 22:31:59 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
PRFileDesc* fd = nullptr;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsCOMPtr<nsIFile> pluginReg;
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2003-05-27 21:14:55 +00:00
|
|
|
rv = mPluginRegFile->Clone(getter_AddRefs(pluginReg));
|
2002-08-14 22:31:59 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString filename(kPluginRegistryFilename);
|
2014-05-22 03:48:51 +00:00
|
|
|
filename.AppendLiteral(".tmp");
|
2011-03-27 21:40:59 +00:00
|
|
|
rv = pluginReg->AppendNative(filename);
|
2002-08-14 22:31:59 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2012-06-06 02:08:30 +00:00
|
|
|
rv = pluginReg->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0600, &fd);
|
2002-08-14 22:31:59 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
nsCOMPtr<nsIXULRuntime> runtime = do_GetService("@mozilla.org/xre/runtime;1");
|
|
|
|
if (!runtime) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString arch;
|
2010-12-09 22:28:15 +00:00
|
|
|
rv = runtime->GetXPCOMABI(arch);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
PR_fprintf(fd, "Generated File. Do not edit.\n");
|
2001-02-02 23:48:17 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
PR_fprintf(fd, "\n[HEADER]\nVersion%c%s%c%c\nArch%c%s%c%c\n",
|
2002-08-14 22:31:59 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2002-08-30 00:38:56 +00:00
|
|
|
kPluginRegistryVersion,
|
2002-08-14 22:31:59 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2010-12-09 22:28:15 +00:00
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
arch.get(),
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2002-08-30 00:38:56 +00:00
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
|
2002-07-23 02:18:44 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
// Store all plugins in the mPlugins list - all plugins currently in use.
|
2002-08-30 00:38:56 +00:00
|
|
|
PR_fprintf(fd, "\n[PLUGINS]\n");
|
2002-02-13 02:18:57 +00:00
|
|
|
|
2012-06-14 02:51:21 +00:00
|
|
|
for (nsPluginTag *tag = mPlugins; tag; tag = tag->mNext) {
|
|
|
|
// store each plugin info into the registry
|
|
|
|
// filename & fullpath are on separate line
|
|
|
|
// because they can contain field delimiter char
|
|
|
|
PR_fprintf(fd, "%s%c%c\n%s%c%c\n%s%c%c\n",
|
2015-05-20 13:30:05 +00:00
|
|
|
(tag->FileName().get()),
|
2012-06-14 02:51:21 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
|
|
|
|
(tag->mFullPath.get()),
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
|
2015-05-20 13:30:05 +00:00
|
|
|
(tag->Version().get()),
|
2012-06-14 02:51:21 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
|
2002-08-30 00:38:56 +00:00
|
|
|
|
2014-04-19 12:17:19 +00:00
|
|
|
// lastModifiedTimeStamp|canUnload|tag->mFlags|fromExtension
|
|
|
|
PR_fprintf(fd, "%lld%c%d%c%lu%c%d%c%c\n",
|
2012-06-14 02:51:21 +00:00
|
|
|
tag->mLastModifiedTime,
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
false, // did store whether or not to unload in-process plugins
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2013-02-15 21:00:25 +00:00
|
|
|
0, // legacy field for flags
|
2012-06-14 02:51:21 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2014-04-19 12:17:19 +00:00
|
|
|
tag->IsFromExtension(),
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2012-06-14 02:51:21 +00:00
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
|
|
|
|
|
|
|
|
//description, name & mtypecount are on separate line
|
|
|
|
PR_fprintf(fd, "%s%c%c\n%s%c%c\n%d\n",
|
2015-05-20 13:30:05 +00:00
|
|
|
(tag->Description().get()),
|
2012-06-14 02:51:21 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
|
2015-05-20 13:30:05 +00:00
|
|
|
(tag->Name().get()),
|
2012-06-14 02:51:21 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
|
2015-05-20 13:30:05 +00:00
|
|
|
tag->MimeTypes().Length());
|
2012-06-14 02:51:21 +00:00
|
|
|
|
|
|
|
// Add in each mimetype this plugin supports
|
2015-05-20 13:30:05 +00:00
|
|
|
for (uint32_t i = 0; i < tag->MimeTypes().Length(); i++) {
|
2012-06-14 02:51:21 +00:00
|
|
|
PR_fprintf(fd, "%d%c%s%c%s%c%s%c%c\n",
|
|
|
|
i,PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2015-05-20 13:30:05 +00:00
|
|
|
(tag->MimeTypes()[i].get()),
|
2002-08-30 00:38:56 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2015-05-20 13:30:05 +00:00
|
|
|
(tag->MimeDescriptions()[i].get()),
|
2002-08-30 00:38:56 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2015-05-20 13:30:05 +00:00
|
|
|
(tag->Extensions()[i].get()),
|
2002-08-30 00:38:56 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2002-08-22 22:59:43 +00:00
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
|
2001-02-02 23:48:17 +00:00
|
|
|
}
|
2000-07-22 01:34:13 +00:00
|
|
|
}
|
2012-06-14 02:51:21 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
PR_fprintf(fd, "\n[INVALID]\n");
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsInvalidPluginTag> invalidPlugins = mInvalidPlugins;
|
2010-12-09 22:28:15 +00:00
|
|
|
while (invalidPlugins) {
|
|
|
|
// fullPath
|
|
|
|
PR_fprintf(fd, "%s%c%c\n",
|
|
|
|
(!invalidPlugins->mFullPath.IsEmpty() ? invalidPlugins->mFullPath.get() : ""),
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
|
|
|
|
|
|
|
|
// lastModifiedTimeStamp
|
|
|
|
PR_fprintf(fd, "%lld%c%c\n",
|
|
|
|
invalidPlugins->mLastModifiedTime,
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
invalidPlugins = invalidPlugins->mNext;
|
|
|
|
}
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2013-12-05 17:16:09 +00:00
|
|
|
PRStatus prrc;
|
|
|
|
prrc = PR_Close(fd);
|
|
|
|
if (prrc != PR_SUCCESS) {
|
|
|
|
// we should obtain a refined value based on prrc;
|
|
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
MOZ_ASSERT(false, "PR_Close() failed.");
|
|
|
|
return rv;
|
|
|
|
}
|
2011-03-27 21:40:59 +00:00
|
|
|
nsCOMPtr<nsIFile> parent;
|
2012-06-06 02:08:30 +00:00
|
|
|
rv = pluginReg->GetParent(getter_AddRefs(parent));
|
2011-03-27 21:40:59 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2012-06-06 02:08:30 +00:00
|
|
|
rv = pluginReg->MoveToNative(parent, kPluginRegistryFilename);
|
2011-03-27 21:40:59 +00:00
|
|
|
return rv;
|
2000-07-22 01:34:13 +00:00
|
|
|
}
|
|
|
|
|
2001-10-18 12:26:23 +00:00
|
|
|
nsresult
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::ReadPluginInfo()
|
2001-10-18 12:26:23 +00:00
|
|
|
{
|
2015-07-04 01:29:00 +00:00
|
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
2014-10-29 15:05:36 +00:00
|
|
|
|
2012-12-21 15:12:46 +00:00
|
|
|
const long PLUGIN_REG_MIMETYPES_ARRAY_SIZE = 12;
|
|
|
|
const long PLUGIN_REG_MAX_MIMETYPES = 1000;
|
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsresult rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID,&rv));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2007-07-26 07:01:22 +00:00
|
|
|
directoryService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
|
2003-05-27 21:14:55 +00:00
|
|
|
getter_AddRefs(mPluginRegFile));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2009-09-22 07:46:32 +00:00
|
|
|
if (!mPluginRegFile) {
|
|
|
|
// There is no profile yet, this will tell us if there is going to be one
|
|
|
|
// in the future.
|
|
|
|
directoryService->Get(NS_APP_PROFILE_DIR_STARTUP, NS_GET_IID(nsIFile),
|
|
|
|
getter_AddRefs(mPluginRegFile));
|
|
|
|
if (!mPluginRegFile)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
else
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
PRFileDesc* fd = nullptr;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsCOMPtr<nsIFile> pluginReg;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2003-05-27 21:14:55 +00:00
|
|
|
rv = mPluginRegFile->Clone(getter_AddRefs(pluginReg));
|
2002-08-14 22:31:59 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
rv = pluginReg->AppendNative(kPluginRegistryFilename);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
int64_t fileSize;
|
2012-06-06 02:08:30 +00:00
|
|
|
rv = pluginReg->GetFileSize(&fileSize);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(rv))
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2013-02-27 22:44:52 +00:00
|
|
|
if (fileSize > INT32_MAX) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
int32_t flen = int32_t(fileSize);
|
2002-08-14 22:31:59 +00:00
|
|
|
if (flen == 0) {
|
|
|
|
NS_WARNING("Plugins Registry Empty!");
|
|
|
|
return NS_OK; // ERROR CONDITION
|
|
|
|
}
|
2002-06-26 04:32:49 +00:00
|
|
|
|
2002-08-26 21:20:31 +00:00
|
|
|
nsPluginManifestLineReader reader;
|
2002-08-14 22:31:59 +00:00
|
|
|
char* registry = reader.Init(flen);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!registry)
|
2002-08-14 22:31:59 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2012-06-06 02:08:30 +00:00
|
|
|
rv = pluginReg->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd);
|
2002-08-14 22:31:59 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
|
|
|
// set rv to return an error on goto out
|
2002-08-14 22:31:59 +00:00
|
|
|
rv = NS_ERROR_FAILURE;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2015-07-07 15:29:00 +00:00
|
|
|
// We know how many octes we are supposed to read.
|
|
|
|
// So let use the busy_beaver_PR_Read version.
|
|
|
|
int32_t bread = busy_beaver_PR_Read(fd, registry, flen);
|
2013-12-05 17:16:09 +00:00
|
|
|
|
|
|
|
PRStatus prrc;
|
|
|
|
prrc = PR_Close(fd);
|
|
|
|
if (prrc != PR_SUCCESS) {
|
|
|
|
// Strange error: this is one of those "Should not happen" error.
|
|
|
|
// we may want to report something more refined than NS_ERROR_FAILURE.
|
|
|
|
MOZ_ASSERT(false, "PR_Close() failed.");
|
|
|
|
return rv;
|
|
|
|
}
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2015-07-07 15:29:00 +00:00
|
|
|
// short read error, so to speak.
|
2004-10-11 04:01:49 +00:00
|
|
|
if (flen > bread)
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!ReadSectionHeader(reader, "HEADER"))
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!reader.NextLine())
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
char* values[6];
|
|
|
|
|
2002-08-30 00:38:56 +00:00
|
|
|
// VersionLiteral, kPluginRegistryVersion
|
2008-11-03 19:23:07 +00:00
|
|
|
if (2 != reader.ParseLine(values, 2))
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
// VersionLiteral
|
2008-11-03 19:23:07 +00:00
|
|
|
if (PL_strcmp(values[0], "Version"))
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
// If we're reading an old registry, ignore it
|
|
|
|
if (strcmp(values[1], kPluginRegistryVersion) != 0) {
|
2016-10-04 17:22:07 +00:00
|
|
|
return rv;
|
2016-10-05 13:48:57 +00:00
|
|
|
}
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
char* archValues[6];
|
|
|
|
if (!reader.NextLine()) {
|
|
|
|
return rv;
|
|
|
|
}
|
2016-10-04 21:55:29 +00:00
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
// ArchLiteral, Architecture
|
|
|
|
if (2 != reader.ParseLine(archValues, 2)) {
|
|
|
|
return rv;
|
2016-10-04 17:22:07 +00:00
|
|
|
}
|
2009-06-10 20:47:49 +00:00
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
// ArchLiteral
|
|
|
|
if (PL_strcmp(archValues[0], "Arch")) {
|
|
|
|
return rv;
|
|
|
|
}
|
2016-10-04 21:55:29 +00:00
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
nsCOMPtr<nsIXULRuntime> runtime = do_GetService("@mozilla.org/xre/runtime;1");
|
|
|
|
if (!runtime) {
|
|
|
|
return rv;
|
|
|
|
}
|
2016-10-04 21:55:29 +00:00
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
nsAutoCString arch;
|
|
|
|
if (NS_FAILED(runtime->GetXPCOMABI(arch))) {
|
|
|
|
return rv;
|
|
|
|
}
|
2016-10-04 21:55:29 +00:00
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
// 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;
|
|
|
|
}
|
2016-10-04 21:55:29 +00:00
|
|
|
|
2014-04-19 12:17:19 +00:00
|
|
|
if (!ReadSectionHeader(reader, "PLUGINS"))
|
|
|
|
return rv;
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
while (reader.NextLine()) {
|
2016-10-05 13:48:57 +00:00
|
|
|
if (*reader.LinePtr() == '[') {
|
2010-12-09 22:28:15 +00:00
|
|
|
break;
|
|
|
|
}
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
const char* filename = reader.LinePtr();
|
|
|
|
if (!reader.NextLine())
|
|
|
|
return rv;
|
2016-10-04 21:55:29 +00:00
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
const char* fullpath = reader.LinePtr();
|
|
|
|
if (!reader.NextLine())
|
|
|
|
return rv;
|
2002-08-22 22:59:43 +00:00
|
|
|
|
2009-03-10 23:21:40 +00:00
|
|
|
const char *version;
|
2016-10-05 13:48:57 +00:00
|
|
|
version = reader.LinePtr();
|
|
|
|
if (!reader.NextLine())
|
|
|
|
return rv;
|
2008-07-15 10:50:42 +00:00
|
|
|
|
2014-04-19 12:17:19 +00:00
|
|
|
// lastModifiedTimeStamp|canUnload|tag.mFlag|fromExtension
|
2016-10-05 13:48:57 +00:00
|
|
|
if (4 != reader.ParseLine(values, 4))
|
2002-08-30 00:38:56 +00:00
|
|
|
return rv;
|
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
int64_t lastmod = nsCRT::atoll(values[0]);
|
|
|
|
bool fromExtension = atoi(values[3]);
|
2002-08-30 00:38:56 +00:00
|
|
|
if (!reader.NextLine())
|
|
|
|
return rv;
|
|
|
|
|
2012-12-17 15:05:53 +00:00
|
|
|
char *description = reader.LinePtr();
|
2002-08-14 22:31:59 +00:00
|
|
|
if (!reader.NextLine())
|
|
|
|
return rv;
|
2002-08-22 22:59:43 +00:00
|
|
|
|
2012-12-17 15:05:53 +00:00
|
|
|
#if MOZ_WIDGET_ANDROID
|
|
|
|
// Flash on Android does not populate the version field, but it is tacked on to the description.
|
|
|
|
// For example, "Shockwave Flash 11.1 r115"
|
|
|
|
if (PL_strncmp("Shockwave Flash ", description, 16) == 0 && description[16]) {
|
|
|
|
version = &description[16];
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-03-10 23:21:40 +00:00
|
|
|
const char *name = reader.LinePtr();
|
2002-08-14 22:31:59 +00:00
|
|
|
if (!reader.NextLine())
|
2002-08-30 00:38:56 +00:00
|
|
|
return rv;
|
|
|
|
|
2012-12-21 15:12:46 +00:00
|
|
|
long mimetypecount = std::strtol(reader.LinePtr(), nullptr, 10);
|
|
|
|
if (mimetypecount == LONG_MAX || mimetypecount == LONG_MIN ||
|
|
|
|
mimetypecount >= PLUGIN_REG_MAX_MIMETYPES || mimetypecount < 0) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-30 00:38:56 +00:00
|
|
|
char *stackalloced[PLUGIN_REG_MIMETYPES_ARRAY_SIZE * 3];
|
2002-08-14 22:31:59 +00:00
|
|
|
char **mimetypes;
|
|
|
|
char **mimedescriptions;
|
|
|
|
char **extensions;
|
|
|
|
char **heapalloced = 0;
|
2002-08-30 00:38:56 +00:00
|
|
|
if (mimetypecount > PLUGIN_REG_MIMETYPES_ARRAY_SIZE - 1) {
|
2002-08-14 22:31:59 +00:00
|
|
|
heapalloced = new char *[mimetypecount * 3];
|
|
|
|
mimetypes = heapalloced;
|
|
|
|
} else {
|
|
|
|
mimetypes = stackalloced;
|
|
|
|
}
|
|
|
|
mimedescriptions = mimetypes + mimetypecount;
|
|
|
|
extensions = mimedescriptions + mimetypecount;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
int mtr = 0; //mimetype read
|
|
|
|
for (; mtr < mimetypecount; mtr++) {
|
|
|
|
if (!reader.NextLine())
|
|
|
|
break;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
//line number|mimetype|description|extension
|
|
|
|
if (4 != reader.ParseLine(values, 4))
|
|
|
|
break;
|
|
|
|
int line = atoi(values[0]);
|
|
|
|
if (line != mtr)
|
2004-10-11 04:01:49 +00:00
|
|
|
break;
|
2002-08-14 22:31:59 +00:00
|
|
|
mimetypes[mtr] = values[1];
|
|
|
|
mimedescriptions[mtr] = values[2];
|
|
|
|
extensions[mtr] = values[3];
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
if (mtr != mimetypecount) {
|
|
|
|
if (heapalloced) {
|
|
|
|
delete [] heapalloced;
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginTag> tag = new nsPluginTag(name,
|
2002-08-14 22:31:59 +00:00
|
|
|
description,
|
|
|
|
filename,
|
2009-06-10 20:47:49 +00:00
|
|
|
fullpath,
|
2008-07-15 10:50:42 +00:00
|
|
|
version,
|
2002-08-14 22:31:59 +00:00
|
|
|
(const char* const*)mimetypes,
|
|
|
|
(const char* const*)mimedescriptions,
|
|
|
|
(const char* const*)extensions,
|
2014-04-19 12:17:19 +00:00
|
|
|
mimetypecount, lastmod, fromExtension, true);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (heapalloced)
|
2002-08-14 22:31:59 +00:00
|
|
|
delete [] heapalloced;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2013-02-15 21:00:25 +00:00
|
|
|
// Import flags from registry into prefs for old registry versions
|
2015-05-21 20:22:04 +00:00
|
|
|
MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
2015-05-20 13:30:05 +00:00
|
|
|
("LoadCachedPluginsInfo : Loading Cached plugininfo for %s\n", tag->FileName().get()));
|
2015-07-09 22:03:00 +00:00
|
|
|
|
|
|
|
if (!ShouldAddPlugin(tag)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
tag->mNext = mCachedPlugins;
|
|
|
|
mCachedPlugins = tag;
|
2010-12-09 22:28:15 +00:00
|
|
|
}
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2014-01-15 15:16:40 +00:00
|
|
|
// On Android we always want to try to load a plugin again (Flash). Bug 935676.
|
|
|
|
#ifndef MOZ_WIDGET_ANDROID
|
2016-10-05 13:48:57 +00:00
|
|
|
if (!ReadSectionHeader(reader, "INVALID")) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (reader.NextLine()) {
|
|
|
|
const char *fullpath = reader.LinePtr();
|
|
|
|
if (!reader.NextLine()) {
|
2010-12-09 22:28:15 +00:00
|
|
|
return rv;
|
|
|
|
}
|
2010-12-20 23:38:10 +00:00
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
const char *lastModifiedTimeStamp = reader.LinePtr();
|
|
|
|
int64_t lastmod = nsCRT::atoll(lastModifiedTimeStamp);
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
RefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(fullpath, lastmod);
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2016-10-05 13:48:57 +00:00
|
|
|
invalidTag->mNext = mInvalidPlugins;
|
|
|
|
if (mInvalidPlugins) {
|
|
|
|
mInvalidPlugins->mPrev = invalidTag;
|
2010-12-09 22:28:15 +00:00
|
|
|
}
|
2016-10-05 13:48:57 +00:00
|
|
|
mInvalidPlugins = invalidTag;
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
2014-01-15 15:16:40 +00:00
|
|
|
#endif
|
2013-02-15 21:00:25 +00:00
|
|
|
|
2001-10-18 12:26:23 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-07-03 21:42:35 +00:00
|
|
|
void
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::RemoveCachedPluginsInfo(const char *filePath, nsPluginTag **result)
|
2001-10-18 12:26:23 +00:00
|
|
|
{
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginTag> prev;
|
|
|
|
RefPtr<nsPluginTag> tag = mCachedPlugins;
|
2007-07-03 21:42:35 +00:00
|
|
|
while (tag)
|
2001-10-18 12:26:23 +00:00
|
|
|
{
|
2009-06-10 20:47:49 +00:00
|
|
|
if (tag->mFullPath.Equals(filePath)) {
|
2001-10-18 12:26:23 +00:00
|
|
|
// Found it. Remove it from our list
|
2007-07-03 21:42:35 +00:00
|
|
|
if (prev)
|
|
|
|
prev->mNext = tag->mNext;
|
|
|
|
else
|
|
|
|
mCachedPlugins = tag->mNext;
|
2012-07-30 14:20:58 +00:00
|
|
|
tag->mNext = nullptr;
|
2007-07-03 21:42:35 +00:00
|
|
|
*result = tag;
|
|
|
|
NS_ADDREF(*result);
|
|
|
|
break;
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
2007-07-03 21:42:35 +00:00
|
|
|
prev = tag;
|
|
|
|
tag = tag->mNext;
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-20 20:34:51 +00:00
|
|
|
#ifdef XP_WIN
|
2001-11-17 15:26:02 +00:00
|
|
|
nsresult
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::EnsurePrivateDirServiceProvider()
|
2001-11-17 15:26:02 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!mPrivateDirServiceProvider) {
|
2001-11-17 15:26:02 +00:00
|
|
|
nsresult rv;
|
2003-05-27 21:14:55 +00:00
|
|
|
mPrivateDirServiceProvider = new nsPluginDirServiceProvider();
|
2001-11-17 15:26:02 +00:00
|
|
|
nsCOMPtr<nsIDirectoryService> dirService(do_GetService(kDirectoryServiceContractID, &rv));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2003-05-27 21:14:55 +00:00
|
|
|
rv = dirService->RegisterProvider(mPrivateDirServiceProvider);
|
2001-11-17 15:26:02 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2007-07-20 20:34:51 +00:00
|
|
|
#endif /* XP_WIN */
|
2001-11-17 15:26:02 +00:00
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsresult nsPluginHost::NewPluginURLStream(const nsString& aURL,
|
2010-07-16 19:55:54 +00:00
|
|
|
nsNPAPIPluginInstance *aInstance,
|
2012-05-17 23:54:26 +00:00
|
|
|
nsNPAPIPluginStreamListener* aListener,
|
2009-12-27 20:26:00 +00:00
|
|
|
nsIInputStream *aPostStream,
|
2009-07-02 05:48:08 +00:00
|
|
|
const char *aHeadersData,
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t aHeadersDataLen)
|
1998-09-15 03:48:58 +00:00
|
|
|
{
|
2000-06-16 22:27:16 +00:00
|
|
|
nsCOMPtr<nsIURI> url;
|
2001-04-17 23:30:25 +00:00
|
|
|
nsAutoString absUrl;
|
2000-04-22 20:50:22 +00:00
|
|
|
nsresult rv;
|
2001-01-16 22:53:39 +00:00
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
if (aURL.Length() <= 0)
|
|
|
|
return NS_OK;
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
// get the base URI for the plugin to create an absolute url
|
2012-11-27 14:14:38 +00:00
|
|
|
// in case aURL is relative
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginInstanceOwner> owner = aInstance->GetOwner();
|
2009-06-29 18:53:52 +00:00
|
|
|
if (owner) {
|
2016-05-01 18:29:23 +00:00
|
|
|
nsCOMPtr<nsIURI> baseURI = owner->GetBaseURI();
|
|
|
|
rv = NS_MakeAbsoluteURI(absUrl, aURL, baseURI);
|
2000-06-16 22:27:16 +00:00
|
|
|
}
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2000-06-16 22:27:16 +00:00
|
|
|
if (absUrl.IsEmpty())
|
|
|
|
absUrl.Assign(aURL);
|
|
|
|
|
|
|
|
rv = NS_NewURI(getter_AddRefs(url), absUrl);
|
2015-08-05 03:05:37 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginStreamListenerPeer> listenerPeer = new nsPluginStreamListenerPeer();
|
2015-08-05 03:05:37 +00:00
|
|
|
NS_ENSURE_TRUE(listenerPeer, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
|
|
|
rv = listenerPeer->Initialize(url, aInstance, aListener);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2000-06-16 22:27:16 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
nsCOMPtr<nsIDOMElement> element;
|
2012-11-27 14:14:38 +00:00
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
if (owner) {
|
2012-10-03 02:43:18 +00:00
|
|
|
owner->GetDOMElement(getter_AddRefs(element));
|
2012-11-27 14:14:38 +00:00
|
|
|
owner->GetDocument(getter_AddRefs(doc));
|
|
|
|
}
|
2009-10-29 00:29:44 +00:00
|
|
|
|
2015-08-05 03:05:37 +00:00
|
|
|
nsCOMPtr<nsINode> requestingNode(do_QueryInterface(element));
|
|
|
|
NS_ENSURE_TRUE(requestingNode, NS_ERROR_FAILURE);
|
2000-07-13 02:44:14 +00:00
|
|
|
|
2015-08-05 03:05:37 +00:00
|
|
|
nsCOMPtr<nsIChannel> channel;
|
2014-09-22 11:49:12 +00:00
|
|
|
// @arg loadgroup:
|
|
|
|
// do not add this internal plugin's channel on the
|
|
|
|
// load group otherwise this channel could be canceled
|
|
|
|
// form |nsDocShell::OnLinkClickSync| bug 166613
|
2015-08-05 03:05:37 +00:00
|
|
|
rv = NS_NewChannel(getter_AddRefs(channel),
|
|
|
|
url,
|
|
|
|
requestingNode,
|
|
|
|
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS |
|
|
|
|
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
|
|
|
|
nsIContentPolicy::TYPE_OBJECT_SUBREQUEST,
|
|
|
|
nullptr, // aLoadGroup
|
2015-12-06 09:20:56 +00:00
|
|
|
listenerPeer,
|
2016-02-09 16:14:51 +00:00
|
|
|
nsIRequest::LOAD_NORMAL | nsIChannel::LOAD_CLASSIFY_URI |
|
|
|
|
nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
|
2015-08-05 03:05:37 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
if (doc) {
|
|
|
|
// And if it's a script allow it to execute against the
|
|
|
|
// document's script context.
|
|
|
|
nsCOMPtr<nsIScriptChannel> scriptChannel(do_QueryInterface(channel));
|
|
|
|
if (scriptChannel) {
|
|
|
|
scriptChannel->SetExecutionPolicy(nsIScriptChannel::EXECUTE_NORMAL);
|
|
|
|
// Plug-ins seem to depend on javascript: URIs running synchronously
|
2011-09-30 06:02:59 +00:00
|
|
|
scriptChannel->SetExecuteAsync(false);
|
2009-10-29 00:29:44 +00:00
|
|
|
}
|
|
|
|
}
|
2001-12-12 01:38:02 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
// deal with headers and post data
|
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
|
|
|
if (httpChannel) {
|
2012-02-16 18:14:29 +00:00
|
|
|
if (!aPostStream) {
|
|
|
|
// Only set the Referer header for GET requests because IIS throws
|
|
|
|
// errors about malformed requests if we include it in POSTs. See
|
|
|
|
// bug 724465.
|
2012-03-12 16:48:27 +00:00
|
|
|
nsCOMPtr<nsIURI> referer;
|
2014-11-18 13:47:08 +00:00
|
|
|
net::ReferrerPolicy referrerPolicy = net::RP_Default;
|
2012-03-12 16:48:27 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(element);
|
|
|
|
if (olc)
|
|
|
|
olc->GetSrcURI(getter_AddRefs(referer));
|
|
|
|
|
|
|
|
|
2012-11-27 14:14:38 +00:00
|
|
|
if (!referer) {
|
|
|
|
if (!doc) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2012-03-12 16:48:27 +00:00
|
|
|
referer = doc->GetDocumentURI();
|
2014-11-18 13:47:08 +00:00
|
|
|
referrerPolicy = doc->GetReferrerPolicy();
|
2012-11-27 14:14:38 +00:00
|
|
|
}
|
2012-03-12 16:48:27 +00:00
|
|
|
|
2014-11-18 13:47:08 +00:00
|
|
|
rv = httpChannel->SetReferrerWithPolicy(referer, referrerPolicy);
|
2012-02-16 18:14:29 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv,rv);
|
|
|
|
}
|
2012-11-29 23:00:04 +00:00
|
|
|
|
2009-12-27 20:26:00 +00:00
|
|
|
if (aPostStream) {
|
2009-10-29 00:29:44 +00:00
|
|
|
// XXX it's a bit of a hack to rewind the postdata stream
|
|
|
|
// here but it has to be done in case the post data is
|
|
|
|
// being reused multiple times.
|
|
|
|
nsCOMPtr<nsISeekableStream>
|
2009-12-27 20:26:00 +00:00
|
|
|
postDataSeekable(do_QueryInterface(aPostStream));
|
2009-10-29 00:29:44 +00:00
|
|
|
if (postDataSeekable)
|
|
|
|
postDataSeekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
|
2001-09-05 03:52:26 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(httpChannel));
|
|
|
|
NS_ASSERTION(uploadChannel, "http must support nsIUploadChannel");
|
2001-04-17 23:30:25 +00:00
|
|
|
|
2009-12-27 20:26:00 +00:00
|
|
|
uploadChannel->SetUploadStream(aPostStream, EmptyCString(), -1);
|
2001-04-17 23:30:25 +00:00
|
|
|
}
|
2009-10-29 00:29:44 +00:00
|
|
|
|
2012-01-11 19:38:19 +00:00
|
|
|
if (aHeadersData) {
|
2009-10-29 00:29:44 +00:00
|
|
|
rv = AddHeadersToChannel(aHeadersData, aHeadersDataLen, httpChannel);
|
2012-01-11 19:38:19 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv,rv);
|
|
|
|
}
|
1998-08-05 04:21:36 +00:00
|
|
|
}
|
2015-08-05 03:05:37 +00:00
|
|
|
rv = channel->AsyncOpen2(listenerPeer);
|
2011-02-23 15:47:25 +00:00
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
listenerPeer->TrackRequest(channel);
|
1998-08-05 04:21:36 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2009-06-25 21:06:54 +00:00
|
|
|
nsresult
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::AddHeadersToChannel(const char *aHeadersData,
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t aHeadersDataLen,
|
2009-07-02 05:48:08 +00:00
|
|
|
nsIChannel *aGenericChannel)
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
2001-05-11 21:05:08 +00:00
|
|
|
nsCOMPtr<nsIHttpChannel> aChannel = do_QueryInterface(aGenericChannel);
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
if (!aChannel) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
|
|
|
// used during the manipulation of the String from the aHeadersData
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString headersString;
|
|
|
|
nsAutoCString oneHeader;
|
|
|
|
nsAutoCString headerName;
|
|
|
|
nsAutoCString headerValue;
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t crlf = 0;
|
|
|
|
int32_t colon = 0;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
// Turn the char * buffer into an nsString.
|
|
|
|
headersString = aHeadersData;
|
|
|
|
|
2005-02-05 00:49:25 +00:00
|
|
|
// Iterate over the nsString: for each "\r\n" delimited chunk,
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
// add the value as a header to the nsIHTTPChannel
|
2011-09-30 06:02:59 +00:00
|
|
|
while (true) {
|
|
|
|
crlf = headersString.Find("\r\n", true);
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
if (-1 == crlf) {
|
|
|
|
rv = NS_OK;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
headersString.Mid(oneHeader, 0, crlf);
|
|
|
|
headersString.Cut(0, crlf + 2);
|
|
|
|
oneHeader.StripWhitespace();
|
|
|
|
colon = oneHeader.Find(":");
|
|
|
|
if (-1 == colon) {
|
|
|
|
rv = NS_ERROR_NULL_POINTER;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
oneHeader.Left(headerName, colon);
|
|
|
|
colon++;
|
|
|
|
oneHeader.Mid(headerValue, colon, oneHeader.Length() - colon);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
// FINALLY: we can set the header!
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2011-09-30 06:02:59 +00:00
|
|
|
rv = aChannel->SetRequestHeader(headerName, headerValue, true);
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
rv = NS_ERROR_NULL_POINTER;
|
|
|
|
return rv;
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
}
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
}
|
1999-06-04 22:32:27 +00:00
|
|
|
|
2011-05-18 01:48:34 +00:00
|
|
|
nsresult
|
|
|
|
nsPluginHost::StopPluginInstance(nsNPAPIPluginInstance* aInstance)
|
1999-06-04 22:32:27 +00:00
|
|
|
{
|
2016-01-15 10:38:03 +00:00
|
|
|
PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
|
2008-02-29 02:06:00 +00:00
|
|
|
if (PluginDestructionGuard::DelayDestroy(aInstance)) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::StopPluginInstance called instance=%p\n",aInstance));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2011-07-08 16:39:22 +00:00
|
|
|
if (aInstance->HasStartedDestroying()) {
|
2010-12-20 01:37:43 +00:00
|
|
|
return NS_OK;
|
2011-07-08 16:39:22 +00:00
|
|
|
}
|
|
|
|
|
2012-02-28 20:29:42 +00:00
|
|
|
Telemetry::AutoTimer<Telemetry::PLUGIN_SHUTDOWN_MS> timer;
|
2010-12-20 01:37:43 +00:00
|
|
|
aInstance->Stop();
|
2010-12-24 02:14:04 +00:00
|
|
|
|
2011-11-12 01:10:31 +00:00
|
|
|
// if the instance does not want to be 'cached' just remove it
|
|
|
|
bool doCache = aInstance->ShouldCache();
|
|
|
|
if (doCache) {
|
|
|
|
// try to get the max cached instances from a pref or use default
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t cachedInstanceLimit =
|
2012-04-04 04:09:20 +00:00
|
|
|
Preferences::GetUint(NS_PREF_MAX_NUM_CACHED_INSTANCES,
|
|
|
|
DEFAULT_NUMBER_OF_STOPPED_INSTANCES);
|
2011-11-12 01:10:31 +00:00
|
|
|
if (StoppedInstanceCount() >= cachedInstanceLimit) {
|
|
|
|
nsNPAPIPluginInstance *oldestInstance = FindOldestStoppedInstance();
|
|
|
|
if (oldestInstance) {
|
|
|
|
nsPluginTag* pluginTag = TagForPlugin(oldestInstance->GetPlugin());
|
|
|
|
oldestInstance->Destroy();
|
|
|
|
mInstances.RemoveElement(oldestInstance);
|
2013-02-12 18:03:25 +00:00
|
|
|
// TODO: Remove this check once bug 752422 was investigated
|
2015-02-25 16:36:39 +00:00
|
|
|
if (pluginTag) {
|
2013-02-12 18:03:25 +00:00
|
|
|
OnPluginInstanceDestroyed(pluginTag);
|
|
|
|
}
|
2011-11-12 01:10:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
nsPluginTag* pluginTag = TagForPlugin(aInstance->GetPlugin());
|
|
|
|
aInstance->Destroy();
|
|
|
|
mInstances.RemoveElement(aInstance);
|
2013-02-12 18:03:25 +00:00
|
|
|
// TODO: Remove this check once bug 752422 was investigated
|
2015-02-25 16:36:39 +00:00
|
|
|
if (pluginTag) {
|
2013-02-12 18:03:25 +00:00
|
|
|
OnPluginInstanceDestroyed(pluginTag);
|
|
|
|
}
|
2011-11-12 01:10:31 +00:00
|
|
|
}
|
2010-01-27 01:30:58 +00:00
|
|
|
|
1999-06-04 22:32:27 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-12-13 00:12:41 +00:00
|
|
|
nsresult nsPluginHost::NewPluginStreamListener(nsIURI* aURI,
|
|
|
|
nsNPAPIPluginInstance* aInstance,
|
|
|
|
nsIStreamListener **aStreamListener)
|
1998-08-05 04:21:36 +00:00
|
|
|
{
|
2012-04-24 20:25:21 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aURI);
|
|
|
|
NS_ENSURE_ARG_POINTER(aStreamListener);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginStreamListenerPeer> listener = new nsPluginStreamListenerPeer();
|
2012-12-13 00:12:41 +00:00
|
|
|
nsresult rv = listener->Initialize(aURI, aInstance, nullptr);
|
2012-04-24 20:25:21 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
2012-04-15 21:34:01 +00:00
|
|
|
}
|
2012-01-31 21:55:54 +00:00
|
|
|
|
2012-04-24 20:25:21 +00:00
|
|
|
listener.forget(aStreamListener);
|
2005-09-21 19:14:30 +00:00
|
|
|
|
2012-04-24 20:25:21 +00:00
|
|
|
return NS_OK;
|
2005-09-21 19:14:30 +00:00
|
|
|
}
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2014-12-29 23:12:40 +00:00
|
|
|
void nsPluginHost::CreateWidget(nsPluginInstanceOwner* aOwner)
|
|
|
|
{
|
|
|
|
aOwner->CreateWidget();
|
|
|
|
|
|
|
|
// If we've got a native window, the let the plugin know about it.
|
|
|
|
aOwner->CallSetWindow();
|
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::Observe(nsISupports *aSubject,
|
|
|
|
const char *aTopic,
|
2014-01-04 15:02:17 +00:00
|
|
|
const char16_t *someData)
|
2001-03-12 02:07:15 +00:00
|
|
|
{
|
2013-06-19 15:07:28 +00:00
|
|
|
if (!strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, aTopic)) {
|
2007-07-11 23:25:45 +00:00
|
|
|
OnShutdown();
|
2012-01-06 00:02:51 +00:00
|
|
|
UnloadPlugins();
|
2005-11-06 18:34:03 +00:00
|
|
|
sInst->Release();
|
|
|
|
}
|
2013-06-19 15:07:28 +00:00
|
|
|
if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
|
2012-01-06 00:02:51 +00:00
|
|
|
mPluginsDisabled = Preferences::GetBool("plugin.disable", false);
|
|
|
|
// Unload or load plugins as needed
|
|
|
|
if (mPluginsDisabled) {
|
|
|
|
UnloadPlugins();
|
|
|
|
} else {
|
|
|
|
LoadPlugins();
|
|
|
|
}
|
|
|
|
}
|
2013-06-19 15:07:28 +00:00
|
|
|
if (!strcmp("blocklist-updated", aTopic)) {
|
|
|
|
nsPluginTag* plugin = mPlugins;
|
|
|
|
while (plugin) {
|
|
|
|
plugin->InvalidateBlocklistState();
|
|
|
|
plugin = plugin->mNext;
|
|
|
|
}
|
|
|
|
}
|
2012-02-15 20:34:31 +00:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
2013-06-19 15:07:28 +00:00
|
|
|
if (!strcmp("application-background", aTopic)) {
|
2012-08-22 15:56:38 +00:00
|
|
|
for(uint32_t i = 0; i < mInstances.Length(); i++) {
|
2012-02-15 20:34:31 +00:00
|
|
|
mInstances[i]->NotifyForeground(false);
|
|
|
|
}
|
|
|
|
}
|
2013-06-19 15:07:28 +00:00
|
|
|
if (!strcmp("application-foreground", aTopic)) {
|
2012-08-22 15:56:38 +00:00
|
|
|
for(uint32_t i = 0; i < mInstances.Length(); i++) {
|
2012-02-15 20:34:31 +00:00
|
|
|
if (mInstances[i]->IsOnScreen())
|
|
|
|
mInstances[i]->NotifyForeground(true);
|
|
|
|
}
|
|
|
|
}
|
2013-06-19 15:07:28 +00:00
|
|
|
if (!strcmp("memory-pressure", aTopic)) {
|
2012-08-22 15:56:38 +00:00
|
|
|
for(uint32_t i = 0; i < mInstances.Length(); i++) {
|
2012-02-15 20:34:31 +00:00
|
|
|
mInstances[i]->MemoryPressure();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2001-03-12 02:07:15 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-05-21 13:28:54 +00:00
|
|
|
nsresult
|
2012-08-22 15:56:38 +00:00
|
|
|
nsPluginHost::ParsePostBufferToFixHeaders(const char *inPostData, uint32_t inPostDataLen,
|
|
|
|
char **outPostData, uint32_t *outPostDataLen)
|
2002-01-30 02:40:46 +00:00
|
|
|
{
|
|
|
|
if (!inPostData || !outPostData || !outPostDataLen)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
*outPostData = 0;
|
|
|
|
*outPostDataLen = 0;
|
|
|
|
|
|
|
|
const char CR = '\r';
|
|
|
|
const char LF = '\n';
|
2004-10-11 04:01:49 +00:00
|
|
|
const char CRLFCRLF[] = {CR,LF,CR,LF,'\0'}; // C string"\r\n\r\n"
|
2002-01-30 02:40:46 +00:00
|
|
|
const char ContentLenHeader[] = "Content-length";
|
|
|
|
|
2016-02-02 15:36:30 +00:00
|
|
|
AutoTArray<const char*, 8> singleLF;
|
2002-01-30 02:40:46 +00:00
|
|
|
const char *pSCntlh = 0;// pointer to start of ContentLenHeader in inPostData
|
|
|
|
const char *pSod = 0; // pointer to start of data in inPostData
|
|
|
|
const char *pEoh = 0; // pointer to end of headers in inPostData
|
|
|
|
const char *pEod = inPostData + inPostDataLen; // pointer to end of inPostData
|
|
|
|
if (*inPostData == LF) {
|
|
|
|
// If no custom headers are required, simply add a blank
|
|
|
|
// line ('\n') to the beginning of the file or buffer.
|
|
|
|
// so *inPostData == '\n' is valid
|
|
|
|
pSod = inPostData + 1;
|
2004-10-11 04:01:49 +00:00
|
|
|
} else {
|
2002-01-30 02:40:46 +00:00
|
|
|
const char *s = inPostData; //tmp pointer to sourse inPostData
|
|
|
|
while (s < pEod) {
|
2004-10-11 04:01:49 +00:00
|
|
|
if (!pSCntlh &&
|
|
|
|
(*s == 'C' || *s == 'c') &&
|
2002-01-30 02:40:46 +00:00
|
|
|
(s + sizeof(ContentLenHeader) - 1 < pEod) &&
|
|
|
|
(!PL_strncasecmp(s, ContentLenHeader, sizeof(ContentLenHeader) - 1)))
|
|
|
|
{
|
|
|
|
// lets assume this is ContentLenHeader for now
|
|
|
|
const char *p = pSCntlh = s;
|
|
|
|
p += sizeof(ContentLenHeader) - 1;
|
|
|
|
// search for first CR or LF == end of ContentLenHeader
|
|
|
|
for (; p < pEod; p++) {
|
|
|
|
if (*p == CR || *p == LF) {
|
2004-10-11 04:01:49 +00:00
|
|
|
// got delimiter,
|
|
|
|
// one more check; if previous char is a digit
|
2002-01-30 02:40:46 +00:00
|
|
|
// most likely pSCntlh points to the start of ContentLenHeader
|
|
|
|
if (*(p-1) >= '0' && *(p-1) <= '9') {
|
|
|
|
s = p;
|
|
|
|
}
|
|
|
|
break; //for loop
|
|
|
|
}
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
if (pSCntlh == s) { // curret ptr is the same
|
2002-01-30 02:40:46 +00:00
|
|
|
pSCntlh = 0; // that was not ContentLenHeader
|
|
|
|
break; // there is nothing to parse, break *WHILE LOOP* here
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*s == CR) {
|
|
|
|
if (pSCntlh && // only if ContentLenHeader is found we are looking for end of headers
|
|
|
|
((s + sizeof(CRLFCRLF)-1) <= pEod) &&
|
|
|
|
!memcmp(s, CRLFCRLF, sizeof(CRLFCRLF)-1))
|
|
|
|
{
|
|
|
|
s += sizeof(CRLFCRLF)-1;
|
|
|
|
pEoh = pSod = s; // data stars here
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (*s == LF) {
|
|
|
|
if (*(s-1) != CR) {
|
2009-03-28 13:57:13 +00:00
|
|
|
singleLF.AppendElement(s);
|
2002-01-30 02:40:46 +00:00
|
|
|
}
|
|
|
|
if (pSCntlh && (s+1 < pEod) && (*(s+1) == LF)) {
|
|
|
|
s++;
|
2009-03-28 13:57:13 +00:00
|
|
|
singleLF.AppendElement(s);
|
2002-01-30 02:40:46 +00:00
|
|
|
s++;
|
|
|
|
pEoh = pSod = s; // data stars here
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// deal with output buffer
|
|
|
|
if (!pSod) { // lets assume whole buffer is a data
|
|
|
|
pSod = inPostData;
|
|
|
|
}
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t newBufferLen = 0;
|
|
|
|
uint32_t dataLen = pEod - pSod;
|
|
|
|
uint32_t headersLen = pEoh ? pSod - inPostData : 0;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
char *p; // tmp ptr into new output buf
|
|
|
|
if (headersLen) { // we got a headers
|
2004-10-11 04:01:49 +00:00
|
|
|
// this function does not make any assumption on correctness
|
2002-01-30 02:40:46 +00:00
|
|
|
// of ContentLenHeader value in this case.
|
|
|
|
|
2002-02-07 23:22:39 +00:00
|
|
|
newBufferLen = dataLen + headersLen;
|
2002-01-30 02:40:46 +00:00
|
|
|
// in case there were single LFs in headers
|
|
|
|
// reserve an extra space for CR will be added before each single LF
|
2009-03-28 13:57:13 +00:00
|
|
|
int cntSingleLF = singleLF.Length();
|
2002-01-30 02:40:46 +00:00
|
|
|
newBufferLen += cntSingleLF;
|
|
|
|
|
2015-03-27 00:01:12 +00:00
|
|
|
if (!(*outPostData = p = (char*)moz_xmalloc(newBufferLen)))
|
2002-01-30 02:40:46 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
// deal with single LF
|
|
|
|
const char *s = inPostData;
|
|
|
|
if (cntSingleLF) {
|
|
|
|
for (int i=0; i<cntSingleLF; i++) {
|
2009-03-28 13:57:13 +00:00
|
|
|
const char *plf = singleLF.ElementAt(i); // ptr to single LF in headers
|
2002-01-30 02:40:46 +00:00
|
|
|
int n = plf - s; // bytes to copy
|
|
|
|
if (n) { // for '\n\n' there is nothing to memcpy
|
|
|
|
memcpy(p, s, n);
|
|
|
|
p += n;
|
|
|
|
}
|
|
|
|
*p++ = CR;
|
|
|
|
s = plf;
|
|
|
|
*p++ = *s++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// are we done with headers?
|
|
|
|
headersLen = pEoh - s;
|
|
|
|
if (headersLen) { // not yet
|
|
|
|
memcpy(p, s, headersLen); // copy the rest
|
|
|
|
p += headersLen;
|
|
|
|
}
|
|
|
|
} else if (dataLen) { // no ContentLenHeader is found but there is a data
|
|
|
|
// make new output buffer big enough
|
|
|
|
// to keep ContentLenHeader+value followed by data
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t l = sizeof(ContentLenHeader) + sizeof(CRLFCRLF) + 32;
|
2002-01-30 02:40:46 +00:00
|
|
|
newBufferLen = dataLen + l;
|
2015-03-27 00:01:12 +00:00
|
|
|
if (!(*outPostData = p = (char*)moz_xmalloc(newBufferLen)))
|
2002-01-30 02:40:46 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2016-02-17 19:23:39 +00:00
|
|
|
headersLen = snprintf(p, l,"%s: %u%s", ContentLenHeader, dataLen, CRLFCRLF);
|
|
|
|
if (headersLen == l) { // if snprintf has ate all extra space consider this as an error
|
2015-03-27 00:01:12 +00:00
|
|
|
free(p);
|
2002-01-30 02:40:46 +00:00
|
|
|
*outPostData = 0;
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
p += headersLen;
|
2002-04-25 21:28:06 +00:00
|
|
|
newBufferLen = headersLen + dataLen;
|
2002-01-30 02:40:46 +00:00
|
|
|
}
|
|
|
|
// at this point we've done with headers.
|
|
|
|
// there is a possibility that input buffer has only headers info in it
|
|
|
|
// which already parsed and copied into output buffer.
|
|
|
|
// copy the data
|
|
|
|
if (dataLen) {
|
|
|
|
memcpy(p, pSod, dataLen);
|
|
|
|
}
|
|
|
|
|
|
|
|
*outPostDataLen = newBufferLen;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-05-21 13:28:54 +00:00
|
|
|
nsresult
|
2009-12-27 20:26:00 +00:00
|
|
|
nsPluginHost::CreateTempFileToPost(const char *aPostDataURL, nsIFile **aTmpFile)
|
2002-01-30 02:40:46 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
2012-08-22 15:56:38 +00:00
|
|
|
int64_t fileSize;
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString filename;
|
2002-08-15 18:38:46 +00:00
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
// stat file == get size & convert file:///c:/ to c: if needed
|
2002-08-15 18:38:46 +00:00
|
|
|
nsCOMPtr<nsIFile> inFile;
|
2009-12-27 20:26:00 +00:00
|
|
|
rv = NS_GetFileFromURLSpec(nsDependentCString(aPostDataURL),
|
2002-08-15 18:38:46 +00:00
|
|
|
getter_AddRefs(inFile));
|
|
|
|
if (NS_FAILED(rv)) {
|
2012-06-06 02:08:30 +00:00
|
|
|
nsCOMPtr<nsIFile> localFile;
|
2011-09-30 06:02:59 +00:00
|
|
|
rv = NS_NewNativeLocalFile(nsDependentCString(aPostDataURL), false,
|
2002-08-15 18:38:46 +00:00
|
|
|
getter_AddRefs(localFile));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
inFile = localFile;
|
|
|
|
}
|
|
|
|
rv = inFile->GetFileSize(&fileSize);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
rv = inFile->GetNativePath(filename);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2012-10-03 14:13:18 +00:00
|
|
|
if (fileSize != 0) {
|
2002-01-30 02:40:46 +00:00
|
|
|
nsCOMPtr<nsIInputStream> inStream;
|
2002-04-25 21:28:06 +00:00
|
|
|
rv = NS_NewLocalFileInputStream(getter_AddRefs(inStream), inFile);
|
2002-01-30 02:40:46 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2005-02-11 23:37:51 +00:00
|
|
|
// Create a temporary file to write the http Content-length:
|
|
|
|
// %ld\r\n\" header and "\r\n" == end of headers for post data to
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2005-02-11 23:37:51 +00:00
|
|
|
nsCOMPtr<nsIFile> tempFile;
|
|
|
|
rv = GetPluginTempDir(getter_AddRefs(tempFile));
|
2002-04-25 21:28:06 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString inFileName;
|
2002-05-07 23:07:19 +00:00
|
|
|
inFile->GetNativeLeafName(inFileName);
|
|
|
|
// XXX hack around bug 70083
|
|
|
|
inFileName.Insert(NS_LITERAL_CSTRING("post-"), 0);
|
|
|
|
rv = tempFile->AppendNative(inFileName);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
|
|
|
if (NS_FAILED(rv))
|
2002-04-25 21:28:06 +00:00
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-04-25 21:28:06 +00:00
|
|
|
// make it unique, and mode == 0600, not world-readable
|
2004-10-11 04:01:49 +00:00
|
|
|
rv = tempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
|
2002-04-25 21:28:06 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
nsCOMPtr<nsIOutputStream> outStream;
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStream),
|
|
|
|
tempFile,
|
|
|
|
(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
|
|
|
|
0600); // 600 so others can't read our form data
|
|
|
|
}
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Post data file couldn't be created!");
|
2002-04-25 21:28:06 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
char buf[1024];
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t br, bw;
|
2011-09-29 06:19:26 +00:00
|
|
|
bool firstRead = true;
|
2002-01-30 02:40:46 +00:00
|
|
|
while (1) {
|
|
|
|
// Read() mallocs if buffer is null
|
|
|
|
rv = inStream->Read(buf, 1024, &br);
|
2012-08-22 15:56:38 +00:00
|
|
|
if (NS_FAILED(rv) || (int32_t)br <= 0)
|
2002-04-25 21:28:06 +00:00
|
|
|
break;
|
|
|
|
if (firstRead) {
|
2004-10-11 04:01:49 +00:00
|
|
|
//"For protocols in which the headers must be distinguished from the body,
|
2002-04-25 21:28:06 +00:00
|
|
|
// such as HTTP, the buffer or file should contain the headers, followed by
|
2004-10-11 04:01:49 +00:00
|
|
|
// a blank line, then the body. If no custom headers are required, simply
|
2002-04-25 21:28:06 +00:00
|
|
|
// add a blank line ('\n') to the beginning of the file or buffer.
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-04-25 21:28:06 +00:00
|
|
|
char *parsedBuf;
|
|
|
|
// assuming first 1K (or what we got) has all headers in,
|
2009-07-02 05:48:08 +00:00
|
|
|
// lets parse it through nsPluginHost::ParsePostBufferToFixHeaders()
|
2002-04-25 21:28:06 +00:00
|
|
|
ParsePostBufferToFixHeaders((const char *)buf, br, &parsedBuf, &bw);
|
|
|
|
rv = outStream->Write(parsedBuf, bw, &br);
|
2015-03-27 00:01:12 +00:00
|
|
|
free(parsedBuf);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_FAILED(rv) || (bw != br))
|
2002-04-25 21:28:06 +00:00
|
|
|
break;
|
|
|
|
|
2011-09-30 06:02:59 +00:00
|
|
|
firstRead = false;
|
2002-04-25 21:28:06 +00:00
|
|
|
continue;
|
|
|
|
}
|
2002-01-30 02:40:46 +00:00
|
|
|
bw = br;
|
|
|
|
rv = outStream->Write(buf, bw, &br);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_FAILED(rv) || (bw != br))
|
2002-04-25 21:28:06 +00:00
|
|
|
break;
|
2002-01-30 02:40:46 +00:00
|
|
|
}
|
2002-04-25 21:28:06 +00:00
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
inStream->Close();
|
|
|
|
outStream->Close();
|
2009-12-27 20:26:00 +00:00
|
|
|
if (NS_SUCCEEDED(rv))
|
2014-03-15 19:00:15 +00:00
|
|
|
tempFile.forget(aTmpFile);
|
2002-01-30 02:40:46 +00:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
2002-05-01 02:01:50 +00:00
|
|
|
|
2011-05-21 13:28:54 +00:00
|
|
|
nsresult
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::NewPluginNativeWindow(nsPluginNativeWindow ** aPluginNativeWindow)
|
2002-09-26 02:53:27 +00:00
|
|
|
{
|
|
|
|
return PLUG_NewPluginNativeWindow(aPluginNativeWindow);
|
|
|
|
}
|
|
|
|
|
2011-05-18 01:48:34 +00:00
|
|
|
nsresult
|
|
|
|
nsPluginHost::GetPluginName(nsNPAPIPluginInstance *aPluginInstance,
|
2009-07-02 05:48:08 +00:00
|
|
|
const char** aPluginName)
|
2008-04-16 20:06:48 +00:00
|
|
|
{
|
2010-07-20 02:11:26 +00:00
|
|
|
nsNPAPIPluginInstance *instance = static_cast<nsNPAPIPluginInstance*>(aPluginInstance);
|
|
|
|
if (!instance)
|
2010-01-27 01:30:58 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
nsNPAPIPlugin* plugin = instance->GetPlugin();
|
|
|
|
if (!plugin)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2015-05-20 13:30:05 +00:00
|
|
|
*aPluginName = TagForPlugin(plugin)->Name().get();
|
2010-01-27 01:30:58 +00:00
|
|
|
|
2008-04-16 20:06:48 +00:00
|
|
|
return NS_OK;
|
2009-10-02 11:26:04 +00:00
|
|
|
}
|
|
|
|
|
2011-05-18 01:48:34 +00:00
|
|
|
nsresult
|
|
|
|
nsPluginHost::GetPluginTagForInstance(nsNPAPIPluginInstance *aPluginInstance,
|
2009-10-02 11:26:04 +00:00
|
|
|
nsIPluginTag **aPluginTag)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aPluginInstance);
|
|
|
|
NS_ENSURE_ARG_POINTER(aPluginTag);
|
|
|
|
|
2011-05-18 01:48:34 +00:00
|
|
|
nsNPAPIPlugin *plugin = aPluginInstance->GetPlugin();
|
2010-07-20 02:11:26 +00:00
|
|
|
if (!plugin)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
*aPluginTag = TagForPlugin(plugin);
|
2010-01-29 19:42:54 +00:00
|
|
|
|
2010-02-03 01:18:37 +00:00
|
|
|
NS_ADDREF(*aPluginTag);
|
2009-10-02 11:26:04 +00:00
|
|
|
return NS_OK;
|
2008-04-16 20:06:48 +00:00
|
|
|
}
|
|
|
|
|
2009-12-15 20:44:52 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::Notify(nsITimer* timer)
|
|
|
|
{
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginTag> pluginTag = mPlugins;
|
2012-02-14 18:03:24 +00:00
|
|
|
while (pluginTag) {
|
|
|
|
if (pluginTag->mUnloadTimer == timer) {
|
|
|
|
if (!IsRunningPlugin(pluginTag)) {
|
|
|
|
pluginTag->TryUnloadPlugin(false);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
pluginTag = pluginTag->mNext;
|
|
|
|
}
|
|
|
|
|
2009-12-15 20:44:52 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2010-11-05 15:18:07 +00:00
|
|
|
#ifdef XP_WIN
|
|
|
|
// Re-enable any top level browser windows that were disabled by modal dialogs
|
|
|
|
// displayed by the crashed plugin.
|
|
|
|
static void
|
|
|
|
CheckForDisabledWindows()
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIWindowMediator> wm(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
|
|
|
|
if (!wm)
|
|
|
|
return;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> windowList;
|
2012-07-30 14:20:58 +00:00
|
|
|
wm->GetXULWindowEnumerator(nullptr, getter_AddRefs(windowList));
|
2010-11-05 15:18:07 +00:00
|
|
|
if (!windowList)
|
|
|
|
return;
|
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool haveWindows;
|
2010-11-05 15:18:07 +00:00
|
|
|
do {
|
|
|
|
windowList->HasMoreElements(&haveWindows);
|
|
|
|
if (!haveWindows)
|
|
|
|
return;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> supportsWindow;
|
|
|
|
windowList->GetNext(getter_AddRefs(supportsWindow));
|
|
|
|
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(supportsWindow));
|
|
|
|
if (baseWin) {
|
|
|
|
nsCOMPtr<nsIWidget> widget;
|
|
|
|
baseWin->GetMainWidget(getter_AddRefs(widget));
|
|
|
|
if (widget && !widget->GetParent() &&
|
2012-07-19 08:57:50 +00:00
|
|
|
widget->IsVisible() &&
|
2012-07-23 05:19:08 +00:00
|
|
|
!widget->IsEnabled()) {
|
|
|
|
nsIWidget* child = widget->GetFirstChild();
|
2011-09-29 06:19:26 +00:00
|
|
|
bool enable = true;
|
2010-11-06 20:27:39 +00:00
|
|
|
while (child) {
|
2014-03-19 16:48:08 +00:00
|
|
|
if (child->WindowType() == eWindowType_dialog) {
|
2011-09-30 06:02:59 +00:00
|
|
|
enable = false;
|
2010-11-06 20:27:39 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
child = child->GetNextSibling();
|
2010-11-05 15:18:07 +00:00
|
|
|
}
|
|
|
|
if (enable) {
|
2011-09-30 06:02:59 +00:00
|
|
|
widget->Enable(true);
|
2010-11-05 15:18:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (haveWindows);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-12-16 20:08:45 +00:00
|
|
|
void
|
2010-03-24 21:22:04 +00:00
|
|
|
nsPluginHost::PluginCrashed(nsNPAPIPlugin* aPlugin,
|
|
|
|
const nsAString& pluginDumpID,
|
|
|
|
const nsAString& browserDumpID)
|
2009-12-16 20:08:45 +00:00
|
|
|
{
|
2010-07-20 02:11:26 +00:00
|
|
|
nsPluginTag* crashedPluginTag = TagForPlugin(aPlugin);
|
2015-03-18 21:04:08 +00:00
|
|
|
MOZ_ASSERT(crashedPluginTag);
|
2009-12-16 20:08:45 +00:00
|
|
|
|
2010-03-24 21:22:04 +00:00
|
|
|
// Notify the app's observer that a plugin crashed so it can submit
|
|
|
|
// a crashreport.
|
2011-09-29 06:19:26 +00:00
|
|
|
bool submittedCrashReport = false;
|
2010-03-24 21:22:04 +00:00
|
|
|
nsCOMPtr<nsIObserverService> obsService =
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 16:59:13 +00:00
|
|
|
mozilla::services::GetObserverService();
|
2010-03-24 21:22:04 +00:00
|
|
|
nsCOMPtr<nsIWritablePropertyBag2> propbag =
|
|
|
|
do_CreateInstance("@mozilla.org/hash-property-bag;1");
|
2010-02-10 01:05:31 +00:00
|
|
|
if (obsService && propbag) {
|
2015-03-18 21:04:08 +00:00
|
|
|
uint32_t runID = 0;
|
|
|
|
PluginLibrary* library = aPlugin->GetLibrary();
|
|
|
|
|
|
|
|
if (!NS_WARN_IF(!library)) {
|
|
|
|
library->GetRunID(&runID);
|
|
|
|
}
|
|
|
|
propbag->SetPropertyAsUint32(NS_LITERAL_STRING("runID"), runID);
|
|
|
|
|
|
|
|
nsCString pluginName;
|
|
|
|
crashedPluginTag->GetName(pluginName);
|
|
|
|
propbag->SetPropertyAsAString(NS_LITERAL_STRING("pluginName"),
|
|
|
|
NS_ConvertUTF8toUTF16(pluginName));
|
2010-03-24 21:22:04 +00:00
|
|
|
propbag->SetPropertyAsAString(NS_LITERAL_STRING("pluginDumpID"),
|
|
|
|
pluginDumpID);
|
|
|
|
propbag->SetPropertyAsAString(NS_LITERAL_STRING("browserDumpID"),
|
|
|
|
browserDumpID);
|
|
|
|
propbag->SetPropertyAsBool(NS_LITERAL_STRING("submittedCrashReport"),
|
|
|
|
submittedCrashReport);
|
2012-07-30 14:20:58 +00:00
|
|
|
obsService->NotifyObservers(propbag, "plugin-crashed", nullptr);
|
2010-02-10 01:05:31 +00:00
|
|
|
// see if an observer submitted a crash report.
|
2010-03-24 21:22:04 +00:00
|
|
|
propbag->GetPropertyAsBool(NS_LITERAL_STRING("submittedCrashReport"),
|
|
|
|
&submittedCrashReport);
|
2010-02-10 01:05:31 +00:00
|
|
|
}
|
|
|
|
|
2009-12-16 20:08:45 +00:00
|
|
|
// Invalidate each nsPluginInstanceTag for the crashed plugin
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
for (uint32_t i = mInstances.Length(); i > 0; i--) {
|
2010-07-20 02:11:26 +00:00
|
|
|
nsNPAPIPluginInstance* instance = mInstances[i - 1];
|
|
|
|
if (instance->GetPlugin() == aPlugin) {
|
2010-03-24 21:22:04 +00:00
|
|
|
// notify the content node (nsIObjectLoadingContent) that the
|
|
|
|
// plugin has crashed
|
2010-01-13 16:42:41 +00:00
|
|
|
nsCOMPtr<nsIDOMElement> domElement;
|
2010-07-20 02:11:26 +00:00
|
|
|
instance->GetDOMElement(getter_AddRefs(domElement));
|
2010-01-13 16:42:41 +00:00
|
|
|
nsCOMPtr<nsIObjectLoadingContent> objectContent(do_QueryInterface(domElement));
|
|
|
|
if (objectContent) {
|
2010-07-20 02:11:26 +00:00
|
|
|
objectContent->PluginCrashed(crashedPluginTag, pluginDumpID, browserDumpID,
|
2010-03-24 21:22:04 +00:00
|
|
|
submittedCrashReport);
|
2010-01-13 16:42:41 +00:00
|
|
|
}
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
instance->Destroy();
|
|
|
|
mInstances.RemoveElement(instance);
|
|
|
|
OnPluginInstanceDestroyed(crashedPluginTag);
|
2009-12-16 20:08:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only after all instances have been invalidated is it safe to null
|
2012-04-03 22:08:07 +00:00
|
|
|
// out nsPluginTag.mPlugin. The next time we try to create an
|
2009-12-16 20:08:45 +00:00
|
|
|
// instance of this plugin we reload it (launch a new plugin process).
|
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
crashedPluginTag->mPlugin = nullptr;
|
2014-10-29 15:05:36 +00:00
|
|
|
crashedPluginTag->mContentProcessRunningCount = 0;
|
2010-11-05 15:18:07 +00:00
|
|
|
|
|
|
|
#ifdef XP_WIN
|
|
|
|
CheckForDisabledWindows();
|
|
|
|
#endif
|
2009-12-16 20:08:45 +00:00
|
|
|
}
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
nsNPAPIPluginInstance*
|
|
|
|
nsPluginHost::FindInstance(const char *mimetype)
|
2010-02-03 01:18:37 +00:00
|
|
|
{
|
2012-08-22 15:56:38 +00:00
|
|
|
for (uint32_t i = 0; i < mInstances.Length(); i++) {
|
2010-07-20 02:11:26 +00:00
|
|
|
nsNPAPIPluginInstance* instance = mInstances[i];
|
2010-02-03 01:18:37 +00:00
|
|
|
|
2010-01-27 01:30:58 +00:00
|
|
|
const char* mt;
|
2010-07-20 02:11:26 +00:00
|
|
|
nsresult rv = instance->GetMIMEType(&mt);
|
2010-01-27 01:30:58 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
continue;
|
2010-07-20 02:11:26 +00:00
|
|
|
|
2010-01-27 01:30:58 +00:00
|
|
|
if (PL_strcasecmp(mt, mimetype) == 0)
|
2010-07-20 02:11:26 +00:00
|
|
|
return instance;
|
2010-01-27 01:30:58 +00:00
|
|
|
}
|
2010-07-20 02:11:26 +00:00
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr;
|
2010-01-27 01:30:58 +00:00
|
|
|
}
|
|
|
|
|
2011-11-12 01:10:31 +00:00
|
|
|
nsNPAPIPluginInstance*
|
|
|
|
nsPluginHost::FindOldestStoppedInstance()
|
|
|
|
{
|
2012-07-30 14:20:58 +00:00
|
|
|
nsNPAPIPluginInstance *oldestInstance = nullptr;
|
2011-11-12 01:10:31 +00:00
|
|
|
TimeStamp oldestTime = TimeStamp::Now();
|
2012-08-22 15:56:38 +00:00
|
|
|
for (uint32_t i = 0; i < mInstances.Length(); i++) {
|
2011-11-12 01:10:31 +00:00
|
|
|
nsNPAPIPluginInstance *instance = mInstances[i];
|
|
|
|
if (instance->IsRunning())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
TimeStamp time = instance->StopTime();
|
|
|
|
if (time < oldestTime) {
|
|
|
|
oldestTime = time;
|
|
|
|
oldestInstance = instance;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return oldestInstance;
|
|
|
|
}
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t
|
2011-11-12 01:10:31 +00:00
|
|
|
nsPluginHost::StoppedInstanceCount()
|
|
|
|
{
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t stoppedCount = 0;
|
|
|
|
for (uint32_t i = 0; i < mInstances.Length(); i++) {
|
2011-11-12 01:10:31 +00:00
|
|
|
nsNPAPIPluginInstance *instance = mInstances[i];
|
|
|
|
if (!instance->IsRunning())
|
|
|
|
stoppedCount++;
|
|
|
|
}
|
|
|
|
return stoppedCount;
|
|
|
|
}
|
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
nsTArray< RefPtr<nsNPAPIPluginInstance> >*
|
2010-07-20 02:11:26 +00:00
|
|
|
nsPluginHost::InstanceArray()
|
|
|
|
{
|
|
|
|
return &mInstances;
|
|
|
|
}
|
|
|
|
|
2015-02-25 16:36:39 +00:00
|
|
|
void
|
2013-04-23 20:02:12 +00:00
|
|
|
nsPluginHost::DestroyRunningInstances(nsPluginTag* aPluginTag)
|
2010-01-27 01:30:58 +00:00
|
|
|
{
|
2012-08-22 15:56:38 +00:00
|
|
|
for (int32_t i = mInstances.Length(); i > 0; i--) {
|
2010-07-20 02:11:26 +00:00
|
|
|
nsNPAPIPluginInstance *instance = mInstances[i - 1];
|
|
|
|
if (instance->IsRunning() && (!aPluginTag || aPluginTag == TagForPlugin(instance->GetPlugin()))) {
|
2012-07-30 14:20:58 +00:00
|
|
|
instance->SetWindow(nullptr);
|
2010-01-27 01:30:58 +00:00
|
|
|
instance->Stop();
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
// Get rid of all the instances without the possibility of caching.
|
|
|
|
nsPluginTag* pluginTag = TagForPlugin(instance->GetPlugin());
|
2012-07-30 14:20:58 +00:00
|
|
|
instance->SetWindow(nullptr);
|
2013-03-19 22:38:25 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMElement> domElement;
|
|
|
|
instance->GetDOMElement(getter_AddRefs(domElement));
|
|
|
|
nsCOMPtr<nsIObjectLoadingContent> objectContent =
|
|
|
|
do_QueryInterface(domElement);
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
instance->Destroy();
|
2013-03-19 22:38:25 +00:00
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
mInstances.RemoveElement(instance);
|
2010-01-27 01:30:58 +00:00
|
|
|
OnPluginInstanceDestroyed(pluginTag);
|
2013-03-19 22:38:25 +00:00
|
|
|
|
|
|
|
// Notify owning content that we destroyed its plugin out from under it
|
|
|
|
if (objectContent) {
|
|
|
|
objectContent->PluginDestroyed();
|
|
|
|
}
|
2010-01-27 01:30:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-29 02:06:00 +00:00
|
|
|
// Runnable that does an async destroy of a plugin.
|
|
|
|
|
2016-04-26 00:23:21 +00:00
|
|
|
class nsPluginDestroyRunnable : public Runnable,
|
2008-02-29 02:06:00 +00:00
|
|
|
public PRCList
|
|
|
|
{
|
|
|
|
public:
|
2014-09-01 22:26:43 +00:00
|
|
|
explicit nsPluginDestroyRunnable(nsNPAPIPluginInstance *aInstance)
|
2008-02-29 02:06:00 +00:00
|
|
|
: mInstance(aInstance)
|
|
|
|
{
|
|
|
|
PR_INIT_CLIST(this);
|
|
|
|
PR_APPEND_LINK(this, &sRunnableListHead);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~nsPluginDestroyRunnable()
|
|
|
|
{
|
|
|
|
PR_REMOVE_LINK(this);
|
|
|
|
}
|
|
|
|
|
2016-08-08 02:18:10 +00:00
|
|
|
NS_IMETHOD Run() override
|
2008-02-29 02:06:00 +00:00
|
|
|
{
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsNPAPIPluginInstance> instance;
|
2008-02-29 02:06:00 +00:00
|
|
|
|
|
|
|
// Null out mInstance to make sure this code in another runnable
|
|
|
|
// will do the right thing even if someone was holding on to this
|
|
|
|
// runnable longer than we expect.
|
|
|
|
instance.swap(mInstance);
|
|
|
|
|
|
|
|
if (PluginDestructionGuard::DelayDestroy(instance)) {
|
|
|
|
// It's still not safe to destroy the plugin, it's now up to the
|
|
|
|
// outermost guard on the stack to take care of the destruction.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPluginDestroyRunnable *r =
|
|
|
|
static_cast<nsPluginDestroyRunnable*>(PR_NEXT_LINK(&sRunnableListHead));
|
|
|
|
|
|
|
|
while (r != &sRunnableListHead) {
|
|
|
|
if (r != this && r->mInstance == instance) {
|
|
|
|
// There's another runnable scheduled to tear down
|
|
|
|
// instance. Let it do the job.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2008-03-05 07:14:58 +00:00
|
|
|
r = static_cast<nsPluginDestroyRunnable*>(PR_NEXT_LINK(r));
|
2008-02-29 02:06:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
|
|
|
("Doing delayed destroy of instance %p\n", instance.get()));
|
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
|
2008-11-03 19:23:07 +00:00
|
|
|
if (host)
|
2008-02-29 02:06:00 +00:00
|
|
|
host->StopPluginInstance(instance);
|
|
|
|
|
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
|
|
|
("Done with delayed destroy of instance %p\n", instance.get()));
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsNPAPIPluginInstance> mInstance;
|
2008-02-29 02:06:00 +00:00
|
|
|
|
|
|
|
static PRCList sRunnableListHead;
|
|
|
|
};
|
|
|
|
|
|
|
|
PRCList nsPluginDestroyRunnable::sRunnableListHead =
|
|
|
|
PR_INIT_STATIC_CLIST(&nsPluginDestroyRunnable::sRunnableListHead);
|
|
|
|
|
|
|
|
PRCList PluginDestructionGuard::sListHead =
|
|
|
|
PR_INIT_STATIC_CLIST(&PluginDestructionGuard::sListHead);
|
|
|
|
|
2013-08-27 05:05:29 +00:00
|
|
|
PluginDestructionGuard::PluginDestructionGuard(nsNPAPIPluginInstance *aInstance)
|
|
|
|
: mInstance(aInstance)
|
|
|
|
{
|
|
|
|
Init();
|
|
|
|
}
|
|
|
|
|
2014-12-29 23:12:40 +00:00
|
|
|
PluginDestructionGuard::PluginDestructionGuard(PluginAsyncSurrogate *aSurrogate)
|
|
|
|
: mInstance(static_cast<nsNPAPIPluginInstance*>(aSurrogate->GetNPP()->ndata))
|
|
|
|
{
|
|
|
|
InitAsync();
|
|
|
|
}
|
|
|
|
|
2013-08-27 05:05:29 +00:00
|
|
|
PluginDestructionGuard::PluginDestructionGuard(NPP npp)
|
|
|
|
: mInstance(npp ? static_cast<nsNPAPIPluginInstance*>(npp->ndata) : nullptr)
|
|
|
|
{
|
|
|
|
Init();
|
|
|
|
}
|
|
|
|
|
2008-02-29 02:06:00 +00:00
|
|
|
PluginDestructionGuard::~PluginDestructionGuard()
|
|
|
|
{
|
|
|
|
NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread");
|
|
|
|
|
|
|
|
PR_REMOVE_LINK(this);
|
|
|
|
|
|
|
|
if (mDelayedDestroy) {
|
|
|
|
// We've attempted to destroy the plugin instance we're holding on
|
|
|
|
// to while we were guarding it. Do the actual destroy now, off of
|
|
|
|
// a runnable.
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsPluginDestroyRunnable> evt =
|
2008-02-29 02:06:00 +00:00
|
|
|
new nsPluginDestroyRunnable(mInstance);
|
|
|
|
|
|
|
|
NS_DispatchToMainThread(evt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
2011-09-29 06:19:26 +00:00
|
|
|
bool
|
2011-05-18 01:48:34 +00:00
|
|
|
PluginDestructionGuard::DelayDestroy(nsNPAPIPluginInstance *aInstance)
|
2008-02-29 02:06:00 +00:00
|
|
|
{
|
|
|
|
NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread");
|
|
|
|
NS_ASSERTION(aInstance, "Uh, I need an instance!");
|
|
|
|
|
|
|
|
// Find the first guard on the stack and make it do a delayed
|
|
|
|
// destroy upon destruction.
|
|
|
|
|
|
|
|
PluginDestructionGuard *g =
|
|
|
|
static_cast<PluginDestructionGuard*>(PR_LIST_HEAD(&sListHead));
|
|
|
|
|
|
|
|
while (g != &sListHead) {
|
|
|
|
if (g->mInstance == aInstance) {
|
2011-09-30 06:02:59 +00:00
|
|
|
g->mDelayedDestroy = true;
|
2008-02-29 02:06:00 +00:00
|
|
|
|
2011-09-30 06:02:59 +00:00
|
|
|
return true;
|
2008-02-29 02:06:00 +00:00
|
|
|
}
|
2012-11-29 23:00:04 +00:00
|
|
|
g = static_cast<PluginDestructionGuard*>(PR_NEXT_LINK(g));
|
2008-02-29 02:06:00 +00:00
|
|
|
}
|
|
|
|
|
2011-09-30 06:02:59 +00:00
|
|
|
return false;
|
2008-02-29 02:06:00 +00:00
|
|
|
}
|