Skip to content

Commit

Permalink
Implement a test plugin for testing deprecated/private PPAPI interfaces.
Browse files Browse the repository at this point in the history
Unfortunately, there's still a few legacy consumers of these APIs. It's
important to continue testing these to make sure there are no security
or stability regressions.

For now, only http/tests/plugins/cross-frame-object-access.html has been
ported over to use the new plugin.

BUG=474535

Review URL: https://codereview.chromium.org/1750783002

Cr-Commit-Position: refs/heads/master@{#378664}
  • Loading branch information
zetafunction authored and Commit bot committed Mar 2, 2016
1 parent a5e91c5 commit c70b36e
Show file tree
Hide file tree
Showing 10 changed files with 278 additions and 43 deletions.
2 changes: 2 additions & 0 deletions content/content_shell.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
'../media/media.gyp:media',
'../net/net.gyp:net',
'../net/net.gyp:net_resources',
'../ppapi/ppapi_internal.gyp:blink_deprecated_test_plugin',
'../ppapi/ppapi_internal.gyp:blink_test_plugin',
'../skia/skia.gyp:skia',
'../storage/storage_browser.gyp:storage',
Expand Down Expand Up @@ -704,6 +705,7 @@
# that corresponds to Content Shell Framework.framework.
'destination': '<(PRODUCT_DIR)/$(CONTENTS_FOLDER_PATH)',
'files': [
'<(PRODUCT_DIR)/blink_deprecated_test_plugin.plugin',
'<(PRODUCT_DIR)/blink_test_plugin.plugin',
],
},
Expand Down
89 changes: 60 additions & 29 deletions content/public/test/ppapi_test_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "content/public/test/ppapi_test_utils.h"

#include <vector>

#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/macros.h"
Expand All @@ -12,40 +14,57 @@
#include "content/public/common/content_switches.h"
#include "ppapi/shared_impl/ppapi_constants.h"

using CharType = base::FilePath::CharType;
using StringType = base::FilePath::StringType;

namespace ppapi {

namespace {

bool RegisterPlugin(
base::CommandLine* command_line,
const base::FilePath::StringType& library_name,
const base::FilePath::StringType& extra_registration_parameters,
const base::FilePath::StringType& mime_type) {
struct PluginInfo {
PluginInfo(const StringType& library_name,
const StringType& extra_params,
const StringType& mime_type)
: library_name(library_name),
extra_params(extra_params),
mime_type(mime_type) {}

StringType library_name;
// Typically a string of the form #name#description#version
StringType extra_params;
StringType mime_type;
};

bool RegisterPlugins(base::CommandLine* command_line,
const std::vector<PluginInfo>& plugins) {
base::FilePath plugin_dir;
if (!PathService::Get(base::DIR_MODULE, &plugin_dir))
return false;

base::FilePath plugin_path = plugin_dir.Append(library_name);

// Append the switch to register the pepper plugin.
if (!base::PathExists(plugin_path))
return false;
base::FilePath::StringType pepper_plugin = plugin_path.value();
pepper_plugin.append(extra_registration_parameters);
pepper_plugin.append(FILE_PATH_LITERAL(";"));
pepper_plugin.append(mime_type);
command_line->AppendSwitchNative(switches::kRegisterPepperPlugins,
pepper_plugin);
StringType args;
for (const auto& plugin : plugins) {
if (!args.empty())
args += FILE_PATH_LITERAL(",");
base::FilePath plugin_path = plugin_dir.Append(plugin.library_name);
if (!base::PathExists(plugin_path))
return false;
args += plugin_path.value();
args += plugin.extra_params;
args += FILE_PATH_LITERAL(";");
args += plugin.mime_type;
}
command_line->AppendSwitchNative(switches::kRegisterPepperPlugins, args);
return true;
}

bool RegisterPluginWithDefaultMimeType(
base::CommandLine* command_line,
const base::FilePath::StringType& library_name,
const base::FilePath::StringType& extra_registration_parameters) {
return RegisterPlugin(command_line, library_name,
extra_registration_parameters,
FILE_PATH_LITERAL("application/x-ppapi-tests"));
std::vector<PluginInfo> plugins;
plugins.push_back(PluginInfo(library_name, extra_registration_parameters,
FILE_PATH_LITERAL("application/x-ppapi-tests")));
return RegisterPlugins(command_line, plugins);
}

} // namespace
Expand Down Expand Up @@ -78,19 +97,31 @@ bool RegisterPowerSaverTestPlugin(base::CommandLine* command_line) {

bool RegisterBlinkTestPlugin(base::CommandLine* command_line) {
#if defined(OS_WIN)
static const base::FilePath::CharType kPluginLibrary[] =
L"blink_test_plugin.dll";
static const CharType kPluginLibrary[] = L"blink_test_plugin.dll";
static const CharType kDeprecatedPluginLibrary[] =
L"blink_deprecated_test_plugin.dll";
#elif defined(OS_MACOSX)
static const base::FilePath::CharType kPluginLibrary[] =
"blink_test_plugin.plugin";
static const CharType kPluginLibrary[] = "blink_test_plugin.plugin";
static const CharType kDeprecatedPluginLibrary[] =
"blink_deprecated_test_plugin.plugin";
#elif defined(OS_POSIX)
static const base::FilePath::CharType kPluginLibrary[] =
"libblink_test_plugin.so";
static const CharType kPluginLibrary[] = "libblink_test_plugin.so";
static const CharType kDeprecatedPluginLibrary[] =
"libblink_deprecated_test_plugin.so";
#endif
// #name#description#version
static const base::FilePath::CharType kExtraParameters[] =
static const CharType kExtraParameters[] =
FILE_PATH_LITERAL("#Blink Test Plugin#Interesting description.#0.8");
return RegisterPlugin(command_line, kPluginLibrary, kExtraParameters,
FILE_PATH_LITERAL("application/x-blink-test-plugin"));
static const CharType kDeprecatedExtraParameters[] =
FILE_PATH_LITERAL("#Blink Deprecated Test Plugin#Description#0.1");

std::vector<PluginInfo> plugins;
plugins.push_back(
PluginInfo(kPluginLibrary, kExtraParameters,
FILE_PATH_LITERAL("application/x-blink-test-plugin")));
plugins.push_back(PluginInfo(
kDeprecatedPluginLibrary, kDeprecatedExtraParameters,
FILE_PATH_LITERAL("application/x-blink-deprecated-test-plugin")));
return RegisterPlugins(command_line, plugins);
}

} // namespace ppapi
1 change: 1 addition & 0 deletions content/shell/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ static_library("content_shell_lib") {
if (enable_plugins) {
deps += [
"//content/ppapi_plugin",
"//ppapi:blink_deprecated_test_plugin",
"//ppapi:blink_test_plugin",
]
}
Expand Down
1 change: 1 addition & 0 deletions content/shell/browser/shell_plugin_service_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ bool ShellPluginServiceFilter::IsPluginAvailable(
const GURL& policy_url,
WebPluginInfo* plugin) {
return plugin->name == base::ASCIIToUTF16("Blink Test Plugin") ||
plugin->name == base::ASCIIToUTF16("Blink Deprecated Test Plugin") ||
plugin->name == base::ASCIIToUTF16("WebKit Test PlugIn");
}

Expand Down
13 changes: 13 additions & 0 deletions ppapi/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,19 @@ shared_library("power_saver_test_plugin") {
]
}

loadable_module("blink_deprecated_test_plugin") {
sources = [
"tests/blink_deprecated_test_plugin.cc",
]

deps = [
"//base",
"//build/config/sanitizers:deps",
"//ppapi/cpp",
"//ppapi/shared_impl",
]
}

loadable_module("blink_test_plugin") {
sources = [
"tests/blink_test_plugin.cc",
Expand Down
20 changes: 20 additions & 0 deletions ppapi/ppapi_tests.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,26 @@
}],
],
},
{
# GN version: //ppapi:blink_deprecated_test_plugin
'target_name': 'blink_deprecated_test_plugin',
'type': 'loadable_module',
'sources': [
'tests/blink_deprecated_test_plugin.cc',
],
'dependencies': [
'../base/base.gyp:base',
'ppapi.gyp:ppapi_cpp',
'ppapi_internal.gyp:ppapi_shared',
],
'conditions': [
['OS=="mac"', {
'mac_bundle': 1,
'product_name': 'blink_deprecated_test_plugin',
'product_extension': 'plugin',
}],
],
},
{
# GN version: //ppapi:blink_test_plugin
'target_name': 'blink_test_plugin',
Expand Down
5 changes: 5 additions & 0 deletions ppapi/tests/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ skip_child_includes = [
"clang",
]
specific_include_rules = {
# The Blink test plugins use //base.
"blink_deprecated_test_plugin\.cc": [
"+base",
],

# extensions/packaged_app/test_packaged_app.cc uses kMaxDescriptorsPerMessage
# defined in ipc/ipc_message_attachment_set.h.
"test_packaged_app\.cc": [
Expand Down
144 changes: 144 additions & 0 deletions ppapi/tests/blink_deprecated_test_plugin.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// A simple C++ Pepper plugin for exercising deprecated PPAPI interfaces in
// Blink layout tests.
//
// Most layout tests should prefer to use the normal Blink test plugin, with the
// MIME type application/x-blink-test-plugin. For layout tests that absolutely
// need to test deprecated synchronous scripting interfaces, this plugin can be
// instantiated using the application/x-blink-deprecated-test-plugin MIME type.

#include <stdint.h>

#include <map>
#include <sstream>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "ppapi/cpp/dev/scriptable_object_deprecated.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/private/instance_private.h"
#include "ppapi/cpp/private/var_private.h"
#include "ppapi/cpp/var.h"

namespace {

class InstanceSO : public pp::deprecated::ScriptableObject {
public:
explicit InstanceSO(pp::InstancePrivate* instance) : instance_(instance) {
methods_.insert(std::make_pair(
"testExecuteScript",
base::Bind(&InstanceSO::TestExecuteScript, base::Unretained(this))));
methods_.insert(std::make_pair(
"testGetProperty",
base::Bind(&InstanceSO::TestGetProperty, base::Unretained(this))));
}

// pp::deprecated::ScriptableObject overrides:
bool HasMethod(const pp::Var& name, pp::Var* exception) {
return FindMethod(name) != methods_.end();
}

pp::Var Call(const pp::Var& method_name,
const std::vector<pp::Var>& args,
pp::Var* exception) override {
auto method = FindMethod(method_name);
if (method != methods_.end()) {
return method->second.Run(args, exception);
}

return ScriptableObject::Call(method_name, args, exception);
}

private:
using MethodMap =
std::map<std::string,
base::Callback<pp::Var(const std::vector<pp::Var>&, pp::Var*)>>;

MethodMap::iterator FindMethod(const pp::Var& name) {
if (!name.is_string())
return methods_.end();
return methods_.find(name.AsString());
}

// Requires one argument. The argument is passed through as-is to
// pp::InstancePrivate::ExecuteScript().
pp::Var TestExecuteScript(const std::vector<pp::Var>& args,
pp::Var* exception) {
if (args.size() != 1) {
*exception = pp::Var("testExecuteScript requires one argument");
return pp::Var();
}
return instance_->ExecuteScript(args[0], exception);
}

// Requires one or more arguments. Roughly analogous to NPN_GetProperty.
// The arguments are the chain of properties to traverse, starting with the
// global context.
pp::Var TestGetProperty(const std::vector<pp::Var>& args,
pp::Var* exception) {
if (args.size() < 1) {
*exception = pp::Var("testGetProperty requires at least one argument");
return pp::Var();
}
pp::VarPrivate object = instance_->GetWindowObject();
for (const auto& arg : args) {
if (!object.HasProperty(arg, exception))
return pp::Var();
object = object.GetProperty(arg, exception);
}
return object;
}

pp::InstancePrivate* const instance_;
MethodMap methods_;
};

class BlinkDeprecatedTestInstance : public pp::InstancePrivate {
public:
explicit BlinkDeprecatedTestInstance(PP_Instance instance)
: pp::InstancePrivate(instance) {}
~BlinkDeprecatedTestInstance() override {}

bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
return true;
}

// pp::InstancePrivate overrides:
pp::Var GetInstanceObject() override {
if (instance_var_.is_undefined()) {
instance_so_ = new InstanceSO(this);
instance_var_ = pp::VarPrivate(this, instance_so_);
}
return instance_var_;
}

private:
pp::VarPrivate instance_var_;
// Owned by |instance_var_|.
InstanceSO* instance_so_;
};

class BlinkDeprecatedTestModule : public pp::Module {
public:
BlinkDeprecatedTestModule() {}
~BlinkDeprecatedTestModule() override {}

virtual pp::Instance* CreateInstance(PP_Instance instance) {
return new BlinkDeprecatedTestInstance(instance);
}
};

} // namespace

namespace pp {

Module* CreateModule() {
return new BlinkDeprecatedTestModule();
}

} // namespace pp
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ Frame: 'childFrame'
--------

This tests that plugins can access objects in other frames as allowed by the security model enforced in WebCore.
Error: Error: Failed conversion between PP_Var and V8 value
Error: Uncaught [object DOMException]
Error: Error: Failed conversion between PP_Var and V8 value
Error: Uncaught [object DOMException]
SUCCESS
Loading

0 comments on commit c70b36e

Please sign in to comment.