diff options
| author | wfh <wfh@chromium.org> | 2015-01-21 06:36:46 -0800 | 
|---|---|---|
| committer | Commit bot <commit-bot@chromium.org> | 2015-01-21 14:38:17 +0000 | 
| commit | 0539f2f5214fc17fdd5d1964be0ceedf98fdb9ce (patch) | |
| tree | 1f30ce9cd48cba479715c1cc6d6cbe8bb02d404b | |
| parent | d7ce058384dd92263b59836d11e6fde7950e3eb7 (diff) | |
| download | chromium_src-0539f2f5214fc17fdd5d1964be0ceedf98fdb9ce.zip chromium_src-0539f2f5214fc17fdd5d1964be0ceedf98fdb9ce.tar.gz chromium_src-0539f2f5214fc17fdd5d1964be0ceedf98fdb9ce.tar.bz2 | |
Block NPAPI plugins by default
Add --enable-npapi flag in chrome://flags to support re-enable.
BUG=295137
TEST=browser_tests, unit_tests, content_browsertests, blink layout tests
Review URL: https://codereview.chromium.org/645203002
Cr-Commit-Position: refs/heads/master@{#312374}
| -rw-r--r-- | chrome/app/generated_resources.grd | 8 | ||||
| -rw-r--r-- | chrome/browser/about_flags.cc | 9 | ||||
| -rw-r--r-- | chrome/browser/content_settings/content_settings_browsertest.cc | 68 | ||||
| -rw-r--r-- | chrome/browser/plugins/plugin_prefs_unittest.cc | 1 | ||||
| -rw-r--r-- | chrome/browser/prerender/prerender_browsertest.cc | 1 | ||||
| -rw-r--r-- | chrome/test/data/load_npapi_plugin.html | 31 | ||||
| -rw-r--r-- | content/browser/plugin_browsertest.cc | 1 | ||||
| -rw-r--r-- | content/browser/plugin_service_impl.cc | 31 | ||||
| -rw-r--r-- | content/browser/plugin_service_impl.h | 3 | ||||
| -rw-r--r-- | content/public/browser/plugin_service.h | 3 | ||||
| -rw-r--r-- | content/public/common/content_switches.cc | 3 | ||||
| -rw-r--r-- | content/public/common/content_switches.h | 2 | ||||
| -rw-r--r-- | content/shell/app/shell_main_delegate.cc | 3 | ||||
| -rw-r--r-- | content/test/fake_plugin_service.cc | 3 | ||||
| -rw-r--r-- | content/test/fake_plugin_service.h | 1 | ||||
| -rw-r--r-- | content/test/plugin/plugin_client.cc | 53 | ||||
| -rw-r--r-- | tools/metrics/histograms/histograms.xml | 17 | 
17 files changed, 230 insertions, 8 deletions
| diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 3f0bfe3..5b776a1 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -5794,6 +5794,14 @@ Keep your key file in a safe place. You will need it to create new versions of y            Enables the win32k renderer lockdown, which is only available on Windows 8 and above.          </message>        </if> +      <if expr="is_win or is_macosx"> +        <message name="IDS_FLAGS_ENABLE_NPAPI_NAME" desc="Name of the 'Enable NPAPI' lab."> +          Enable NPAPI +        </message> +        <message name="IDS_FLAGS_ENABLE_NPAPI_DESCRIPTION" desc="Description of the 'Enable NPAPI' lab."> +          Enables the use of NPAPI plugins. +        </message> +      </if>        <message name="IDS_FLAGS_ENABLE_EXPERIMENTAL_CANVAS_FEATURES_NAME" desc="Name of the 'Enable experimental canvas features' lab.">          Enable experimental canvas features        </message> diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 09b672c..15baf08 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc @@ -500,6 +500,15 @@ const Experiment kExperiments[] = {      kOsAll,      SINGLE_VALUE_TYPE(switches::kDisableExperimentalWebGL)    }, +#if defined(OS_WIN) || defined(OS_MACOSX) +  { +    "enable-npapi", +    IDS_FLAGS_ENABLE_NPAPI_NAME, +    IDS_FLAGS_ENABLE_NPAPI_DESCRIPTION, +    kOsWin | kOsMac, +    SINGLE_VALUE_TYPE(switches::kEnableNpapi) +  }, +#endif    {      "disable-webrtc",      IDS_FLAGS_DISABLE_WEBRTC_NAME, diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc index f6f0606..1ed96bb 100644 --- a/chrome/browser/content_settings/content_settings_browsertest.cc +++ b/chrome/browser/content_settings/content_settings_browsertest.cc @@ -294,20 +294,84 @@ IN_PROC_BROWSER_TEST_F(ContentSettingsTest, RedirectCrossOrigin) {  // On Aura NPAPI only works on Windows.  #if !defined(USE_AURA) || defined(OS_WIN) +class LoadPluginTest : public ContentSettingsTest { + protected: +  void PerformTest(bool expect_loaded) { +    GURL url = ui_test_utils::GetTestUrl( +        base::FilePath(), +        base::FilePath().AppendASCII("load_npapi_plugin.html")); +    ui_test_utils::NavigateToURL(browser(), url); + +    const char* expected_result = expect_loaded ? "Loaded" : "Not Loaded"; +    const char* unexpected_result = expect_loaded ? "Not Loaded" : "Loaded"; + +    base::string16 expected_title(base::ASCIIToUTF16(expected_result)); +    base::string16 unexpected_title(base::ASCIIToUTF16(unexpected_result)); + +    content::TitleWatcher title_watcher( +        browser()->tab_strip_model()->GetActiveWebContents(), expected_title); +    title_watcher.AlsoWaitForTitle(unexpected_title); + +    EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); +  } + +  void SetUpCommandLineInternal(base::CommandLine* command_line, +                                bool expect_loaded) { +#if defined(OS_MACOSX) +    base::FilePath plugin_dir; +    PathService::Get(base::DIR_MODULE, &plugin_dir); +    plugin_dir = plugin_dir.AppendASCII("plugins"); +    // The plugins directory isn't read by default on the Mac, so it needs to be +    // explicitly registered. +    command_line->AppendSwitchPath(switches::kExtraPluginDir, plugin_dir); +#endif +    command_line->AppendSwitch(switches::kAlwaysAuthorizePlugins); +    if (expect_loaded) +      command_line->AppendSwitch(switches::kEnableNpapi); +  } +}; + +class DisabledPluginTest : public LoadPluginTest { + public: +  DisabledPluginTest() {} + +  void SetUpCommandLine(base::CommandLine* command_line) override { +    SetUpCommandLineInternal(command_line, false); +  } +}; + +IN_PROC_BROWSER_TEST_F(DisabledPluginTest, Load) { +  PerformTest(false); +} + +class EnabledPluginTest : public LoadPluginTest { + public: +  EnabledPluginTest() {} + +  void SetUpCommandLine(base::CommandLine* command_line) override { +    SetUpCommandLineInternal(command_line, true); +  } +}; + +IN_PROC_BROWSER_TEST_F(EnabledPluginTest, Load) { +  PerformTest(true); +} +  class ClickToPlayPluginTest : public ContentSettingsTest {   public:    ClickToPlayPluginTest() {} -#if defined(OS_MACOSX)    void SetUpCommandLine(base::CommandLine* command_line) override { +#if defined(OS_MACOSX)      base::FilePath plugin_dir;      PathService::Get(base::DIR_MODULE, &plugin_dir);      plugin_dir = plugin_dir.AppendASCII("plugins");      // The plugins directory isn't read by default on the Mac, so it needs to be      // explicitly registered.      command_line->AppendSwitchPath(switches::kExtraPluginDir, plugin_dir); -  }  #endif +    command_line->AppendSwitch(switches::kEnableNpapi); +  }  };  IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, Basic) { diff --git a/chrome/browser/plugins/plugin_prefs_unittest.cc b/chrome/browser/plugins/plugin_prefs_unittest.cc index 12c4277..70deb5d 100644 --- a/chrome/browser/plugins/plugin_prefs_unittest.cc +++ b/chrome/browser/plugins/plugin_prefs_unittest.cc @@ -208,6 +208,7 @@ TEST_F(PluginPrefsTest, UnifiedPepperFlashState) {    PluginService::GetInstance()->Init();    PluginService::GetInstance()->DisablePluginsDiscoveryForTesting(); +  PluginService::GetInstance()->EnableNpapiPluginsForTesting();    base::string16 component_updated_plugin_name(        ASCIIToUTF16("Component-updated Pepper Flash")); diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 002d32f..aa7447e 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc @@ -1082,6 +1082,7 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest {          app_dir.Append(FILE_PATH_LITERAL("plugins")));  #endif      command_line->AppendSwitch(switches::kAlwaysAuthorizePlugins); +    command_line->AppendSwitch(switches::kEnableNpapi);    }    void SetPreference(NetworkPredictionOptions value) { diff --git a/chrome/test/data/load_npapi_plugin.html b/chrome/test/data/load_npapi_plugin.html new file mode 100644 index 0000000..2b91f5f --- /dev/null +++ b/chrome/test/data/load_npapi_plugin.html @@ -0,0 +1,31 @@ +<html> +<head> +<title>Initial Title</title> +<script> +function PluginCreated() { +  document.title = "Loaded"; +} + +function injectPlugin() { +  var child = document.createElement('div'); +  child.innerHTML = '<embed type="application/vnd.npapi-test" src="foo"' + +                     ' name="invoke_js_function_on_create" id="plugin"' + +                     ' mode="np_embed"></embed>'; +  document.getElementById('content').appendChild(child); +  // Plugins are loaded synchronously during layout, so the plugin has either +  // been loaded or blocked at this point. +  var plugin = document.getElementById('plugin'); +  // Check for the "loadedProperty" to determine if plugin is loaded. +  if (plugin.loadedProperty == true) { +    document.title = "Loaded"; +  } else { +    document.title = "Not Loaded"; +  } +} +</script> +</head> +<body onload='injectPlugin();'> +<div id='content'></div> +</embed> +</body> +</html> diff --git a/content/browser/plugin_browsertest.cc b/content/browser/plugin_browsertest.cc index e1e5c30..9f55c96 100644 --- a/content/browser/plugin_browsertest.cc +++ b/content/browser/plugin_browsertest.cc @@ -74,6 +74,7 @@ class PluginTest : public ContentBrowserTest {      // explicitly registered.      command_line->AppendSwitchPath(switches::kExtraPluginDir, plugin_dir);  #endif +    command_line->AppendSwitch(switches::kEnableNpapi);    }    void SetUpOnMainThread() override { diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc index 49b6638..42ac63b 100644 --- a/content/browser/plugin_service_impl.cc +++ b/content/browser/plugin_service_impl.cc @@ -59,6 +59,16 @@ enum FlashUsage {    FLASH_USAGE_ENUM_COUNT  }; +enum NPAPIPluginStatus { +  // Platform does not support NPAPI. +  NPAPI_STATUS_UNSUPPORTED, +  // Platform supports NPAPI and NPAPI is disabled. +  NPAPI_STATUS_DISABLED, +  // Platform supports NPAPI and NPAPI is enabled. +  NPAPI_STATUS_ENABLED, +  NPAPI_STATUS_ENUM_COUNT +}; +  bool LoadPluginListInProcess() {  #if defined(OS_WIN)    return true; @@ -143,7 +153,7 @@ PluginServiceImpl* PluginServiceImpl::GetInstance() {  }  PluginServiceImpl::PluginServiceImpl() -    : filter_(NULL) { +    : npapi_plugins_enabled_(false), filter_(NULL) {    // Collect the total number of browser processes (which create    // PluginServiceImpl objects, to be precise). The number is used to normalize    // the number of processes which start at least one NPAPI/PPAPI Flash process. @@ -180,6 +190,15 @@ void PluginServiceImpl::Init() {    if (command_line->HasSwitch(switches::kDisablePluginsDiscovery))      PluginList::Singleton()->DisablePluginsDiscovery(); +#if defined(OS_WIN) || defined(OS_MACOSX) +  npapi_plugins_enabled_ = command_line->HasSwitch(switches::kEnableNpapi); +  NPAPIPluginStatus status = +      npapi_plugins_enabled_ ? NPAPI_STATUS_ENABLED : NPAPI_STATUS_DISABLED; +#else +  NPAPIPluginStatus status = NPAPI_STATUS_UNSUPPORTED; +#endif +  UMA_HISTOGRAM_ENUMERATION("Plugin.NPAPIStatus", status, +                            NPAPI_STATUS_ENUM_COUNT);  }  void PluginServiceImpl::StartWatchingPlugins() { @@ -778,17 +797,17 @@ void PluginServiceImpl::GetInternalPlugins(  }  bool PluginServiceImpl::NPAPIPluginsSupported() { -#if defined(OS_WIN) || defined(OS_MACOSX) -  return true; -#else -  return false; -#endif +  return npapi_plugins_enabled_;  }  void PluginServiceImpl::DisablePluginsDiscoveryForTesting() {    PluginList::Singleton()->DisablePluginsDiscovery();  } +void PluginServiceImpl::EnableNpapiPluginsForTesting() { +  npapi_plugins_enabled_ = true; +} +  #if defined(OS_MACOSX)  void PluginServiceImpl::AppActivated() {    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, diff --git a/content/browser/plugin_service_impl.h b/content/browser/plugin_service_impl.h index 8770974..6b25ed4 100644 --- a/content/browser/plugin_service_impl.h +++ b/content/browser/plugin_service_impl.h @@ -106,6 +106,7 @@ class CONTENT_EXPORT PluginServiceImpl    void UnregisterInternalPlugin(const base::FilePath& path) override;    void GetInternalPlugins(std::vector<WebPluginInfo>* plugins) override;    bool NPAPIPluginsSupported() override; +  void EnableNpapiPluginsForTesting() override;    void DisablePluginsDiscoveryForTesting() override;  #if defined(OS_MACOSX)    void AppActivated() override; @@ -226,6 +227,8 @@ class CONTENT_EXPORT PluginServiceImpl    base::win::RegKey hklm_key_;  #endif +  bool npapi_plugins_enabled_; +  #if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID)    ScopedVector<base::FilePathWatcher> file_watchers_;  #endif diff --git a/content/public/browser/plugin_service.h b/content/public/browser/plugin_service.h index cebc890..9121e68 100644 --- a/content/public/browser/plugin_service.h +++ b/content/public/browser/plugin_service.h @@ -143,6 +143,9 @@ class PluginService {    // This can be called from any thread.    virtual bool NPAPIPluginsSupported() = 0; +  // This is equivalent to specifying kEnableNpapi, but is useful for unittests. +  virtual void EnableNpapiPluginsForTesting() = 0; +    // This is equivalent to specifying kDisablePluginsDiscovery, but is useful    // for unittests.    virtual void DisablePluginsDiscoveryForTesting() = 0; diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index b9d93ed..830a7da 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc @@ -955,6 +955,9 @@ const char kEnableWin32kRendererLockDown[] =  const char kFontCacheSharedMemSuffix[] = "font-cache-shared-mem-suffix";  #endif +// Enables the use of NPAPI plugins. +const char kEnableNpapi[]                   = "enable-npapi"; +  #if defined(ENABLE_PLUGINS)  // Enables the plugin power saver feature.  const char kEnablePluginPowerSaver[] = "enable-plugin-power-saver"; diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 2db8c17..6b72dbc 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h @@ -291,6 +291,8 @@ CONTENT_EXPORT extern const char kFontCacheSharedMemSuffix[];  CONTENT_EXPORT bool IsWin32kRendererLockdownEnabled();  #endif +CONTENT_EXPORT extern const char kEnableNpapi[]; +  #if defined(ENABLE_PLUGINS)  CONTENT_EXPORT extern const char kEnablePluginPowerSaver[];  #endif diff --git a/content/shell/app/shell_main_delegate.cc b/content/shell/app/shell_main_delegate.cc index a4ec664..12e33cf 100644 --- a/content/shell/app/shell_main_delegate.cc +++ b/content/shell/app/shell_main_delegate.cc @@ -191,6 +191,9 @@ bool ShellMainDelegate::BasicStartupComplete(int* exit_code) {      command_line.AppendSwitchASCII(switches::kHostResolverRules,                                     "MAP *.test 127.0.0.1"); +    // TODO(wfh): crbug.com/295137 Remove this when NPAPI is gone. +    command_line.AppendSwitch(switches::kEnableNpapi); +      // Unless/until WebM files are added to the media layout tests, we need to      // avoid removing MP4/H264/AAC so that layout tests can run on Android.  #if !defined(OS_ANDROID) diff --git a/content/test/fake_plugin_service.cc b/content/test/fake_plugin_service.cc index 1d7767cb..75e35d4 100644 --- a/content/test/fake_plugin_service.cc +++ b/content/test/fake_plugin_service.cc @@ -101,6 +101,9 @@ bool FakePluginService::NPAPIPluginsSupported() {    return false;  } +void FakePluginService::EnableNpapiPluginsForTesting() { +} +  void FakePluginService::DisablePluginsDiscoveryForTesting() {  } diff --git a/content/test/fake_plugin_service.h b/content/test/fake_plugin_service.h index b8d15d4..ed8450c 100644 --- a/content/test/fake_plugin_service.h +++ b/content/test/fake_plugin_service.h @@ -52,6 +52,7 @@ class FakePluginService : public PluginService {    void UnregisterInternalPlugin(const base::FilePath& path) override;    void GetInternalPlugins(std::vector<WebPluginInfo>* plugins) override;    bool NPAPIPluginsSupported() override; +  void EnableNpapiPluginsForTesting() override;    void DisablePluginsDiscoveryForTesting() override;  #if defined(OS_MACOSX)    void AppActivated() override; diff --git a/content/test/plugin/plugin_client.cc b/content/test/plugin/plugin_client.cc index e5d0f8c..f2f4e68 100644 --- a/content/test/plugin/plugin_client.cc +++ b/content/test/plugin/plugin_client.cc @@ -11,6 +11,52 @@  namespace NPAPIClient { +class NPWithProperty : public NPObject { + public: +  NPWithProperty() : NPObject() {} + +  static NPObject* Allocate(NPP npp, NPClass* npclass) { +    return new NPWithProperty(); +  } + +  static void Deallocate(NPObject* npobject) { +    delete static_cast<NPWithProperty*>(npobject); +  } + +  static bool HasProperty(NPObject* npobject, NPIdentifier name) { +    return (name == PluginClient::HostFunctions()-> +                getstringidentifier("loadedProperty")); +  } + +  static bool GetProperty(NPObject* npobject, +                          NPIdentifier name, +                          NPVariant* result) { +    if (name == PluginClient::HostFunctions()-> +            getstringidentifier("loadedProperty")) { +      BOOLEAN_TO_NPVARIANT(true, *result); +      return true; +    } +    return false; +  } +}; + +static NPClass* GetNPClass() { +  static NPClass plugin_class = { +      NP_CLASS_STRUCT_VERSION, +      NPWithProperty::Allocate, +      NPWithProperty::Deallocate, +      NULL,  // Invalidate +      NULL,  // HasMethod +      NULL,  // Invoke +      NULL,  // InvokeDefault +      NPWithProperty::HasProperty, +      NPWithProperty::GetProperty, +      NULL,  // SetProperty +      NULL,  // RemoveProperty +  }; +  return &plugin_class; +} +  NPNetscapeFuncs* PluginClient::host_functions_;  NPError PluginClient::GetEntryPoints(NPPluginFuncs* pFuncs) { @@ -230,6 +276,13 @@ NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) {      return NPERR_NO_ERROR;    } +  if (variable == NPPVpluginScriptableNPObject) { +    *(NPObject**)value = +        NPAPIClient::PluginClient::HostFunctions()->createobject( +            instance, NPAPIClient::GetNPClass()); +    return NPERR_NO_ERROR; +  } +    // XXXMB - do work here.    return NPERR_GENERIC_ERROR;  } diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index a33a454..125d719 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -25874,6 +25874,14 @@ Therefore, the affected-histogram name has to have at least one dot in it.    <summary>Collects Flash usage data.</summary>  </histogram> +<histogram name="Plugin.NPAPIStatus" enum="NPAPIPluginStatus"> +  <owner>wfh@chromium.org</owner> +  <summary> +    Records whether NPAPI plugins are supported by the platform, and if so, +    whether they are enabled or disabled.  Recorded once at browser startup. +  </summary> +</histogram> +  <histogram name="Plugin.PowerSaver.PeripheralHeuristic"      enum="PluginPowerSaverPeripheralHeuristicDecision">    <owner>tommycli@chromium.org</owner> @@ -50293,6 +50301,7 @@ To add a new entry, add it with any value and run test to compute valid value.    <int value="-1218608640" label="disable-offline-load-stale-cache"/>    <int value="-1212273428" label="enable-experimental-app-list"/>    <int value="-1201183153" label="enable-centered-app-list"/> +  <int value="-1184904651" label="enable-npapi"/>    <int value="-1177802205" label="enable-hosted-app-quit-notification"/>    <int value="-1172204005" label="enable-offline-auto-reload-visible-only"/>    <int value="-1159563774" label="enable-accessibility-script-injection"/> @@ -52415,6 +52424,14 @@ To add a new entry, add it with any value and run test to compute valid value.    <int value="7" label="Notification closed by system"/>  </enum> +<enum name="NPAPIPluginStatus" type="int"> +  <int value="0" label="Unsupported"> +    NPAPI is not supported on this platform +  </int> +  <int value="1" label="Disabled">NPAPI is disabled</int> +  <int value="2" label="Enabled">NPAPI is enabled</int> +</enum> +  <enum name="NtpFollowAction" type="int">    <int value="0" label="PAGE_TRANSITION_LINK"/>    <int value="1" label="PAGE_TRANSITION_TYPED"/> | 
