#include "content/browser/plugin_service_impl.h"
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/content_browser_test.h"
#include "ppapi/buildflags/buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(ENABLE_PPAPI)
#include "content/browser/ppapi_plugin_process_host.h"
#endif
namespace content {
namespace {
#if BUILDFLAG(ENABLE_PPAPI)
class TestPluginClient : public PpapiPluginProcessHost::PluginClient {
public:
void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle,
int* renderer_id) override {}
void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle,
base::ProcessId plugin_pid,
int plugin_child_id) override {
plugin_pid_ = plugin_pid;
run_loop_->Quit();
}
bool Incognito() override { return false; }
base::ProcessId plugin_pid() const { return plugin_pid_; }
void SetRunLoop(base::RunLoop* run_loop) { run_loop_ = run_loop; }
void WaitForQuit() { run_loop_->Run(); }
private:
base::ProcessId plugin_pid_ = 0;
raw_ptr<base::RunLoop> run_loop_ = nullptr;
};
#endif
}
class PluginServiceImplBrowserTest : public ContentBrowserTest { … };
IN_PROC_BROWSER_TEST_F(PluginServiceImplBrowserTest, GetPluginInfoByPath) { … }
#if BUILDFLAG(ENABLE_PPAPI)
IN_PROC_BROWSER_TEST_F(PluginServiceImplBrowserTest, OriginLock) {
RegisterFakePlugin();
url::Origin origin1 = url::Origin::Create(GURL("http://google.com/"));
url::Origin origin2 = url::Origin::Create(GURL("http://youtube.com/"));
TestPluginClient client1;
OpenChannelToFakePlugin(origin1, &client1);
EXPECT_NE(base::kNullProcessId, client1.plugin_pid());
TestPluginClient client2a;
OpenChannelToFakePlugin(origin2, &client2a);
EXPECT_NE(base::kNullProcessId, client2a.plugin_pid());
TestPluginClient client2b;
OpenChannelToFakePlugin(origin2, &client2b);
EXPECT_NE(base::kNullProcessId, client2b.plugin_pid());
EXPECT_NE(client1.plugin_pid(), client2a.plugin_pid());
EXPECT_NE(client1.plugin_pid(), client2b.plugin_pid());
EXPECT_EQ(client2a.plugin_pid(), client2b.plugin_pid());
TestPluginClient client3a;
OpenChannelToFakePlugin(std::nullopt, &client3a);
EXPECT_NE(base::kNullProcessId, client3a.plugin_pid());
TestPluginClient client3b;
OpenChannelToFakePlugin(std::nullopt, &client3b);
EXPECT_NE(base::kNullProcessId, client3b.plugin_pid());
EXPECT_NE(client1.plugin_pid(), client3a.plugin_pid());
EXPECT_NE(client1.plugin_pid(), client3b.plugin_pid());
EXPECT_NE(client2a.plugin_pid(), client3a.plugin_pid());
EXPECT_NE(client2a.plugin_pid(), client3b.plugin_pid());
EXPECT_EQ(client3a.plugin_pid(), client3b.plugin_pid());
}
IN_PROC_BROWSER_TEST_F(PluginServiceImplBrowserTest, NoForkBombs) {
RegisterFakePlugin();
PluginServiceImpl* service = PluginServiceImpl::GetInstance();
service->SetMaxPpapiProcessesPerProfileForTesting(4);
static constexpr char kFakeURLTemplate[] = "https://foo.fake%d.com/";
TestPluginClient client;
for (int i = 0; i < 4; ++i) {
std::string url = base::StringPrintf(kFakeURLTemplate, i);
url::Origin origin = url::Origin::Create(GURL(url));
OpenChannelToFakePlugin(origin, &client);
EXPECT_NE(base::kNullProcessId, client.plugin_pid());
}
for (int i = 4; i < 8; ++i) {
std::string url = base::StringPrintf(kFakeURLTemplate, i);
url::Origin origin = url::Origin::Create(GURL(url));
OpenChannelToFakePlugin(origin, &client);
EXPECT_EQ(base::kNullProcessId, client.plugin_pid());
}
OpenChannelToFakePlugin(std::nullopt, &client);
EXPECT_NE(base::kNullProcessId, client.plugin_pid());
for (int i = 0; i < 4; ++i) {
std::string url = base::StringPrintf(kFakeURLTemplate, i);
url::Origin origin = url::Origin::Create(GURL(url));
OpenChannelToFakePlugin(origin, &client);
EXPECT_NE(base::kNullProcessId, client.plugin_pid());
}
}
#endif
}