blob: 72ba1af9176c3e727416054e69084787c88aab63 [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/chrome_content_client.h"
#include <string>
#include "base/containers/contains.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/test/scoped_command_line.h"
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/origin_util.h"
#include "content/public/test/test_utils.h"
#include "extensions/buildflags/buildflags.h"
#include "ppapi/buildflags/buildflags.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
#include "url/url_util.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/constants.h"
#endif
namespace chrome_common {
TEST(ChromeContentClientTest, AdditionalSchemes) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
EXPECT_TRUE(url::IsStandard(
extensions::kExtensionScheme,
url::Component(0, strlen(extensions::kExtensionScheme))));
GURL extension_url(
"chrome-extension://abcdefghijklmnopqrstuvwxyzabcdef/foo.html");
url::Origin origin = url::Origin::Create(extension_url);
EXPECT_EQ("chrome-extension://abcdefghijklmnopqrstuvwxyzabcdef",
origin.Serialize());
#endif
// IsUrlPotentiallyTrustworthy assertions test for https://crbug.com/734581.
constexpr const char* kChromeLayerUrlsRegisteredAsSecure[] = {
// The schemes below are registered both as secure and no-access. Product
// code needs to treat such URLs as trustworthy, even though no-access
// schemes translate into an opaque origin (which is untrustworthy).
"chrome-native://newtab/",
"chrome-error://foo/",
// The schemes below are registered as secure (but not as no-access).
"chrome://foo/",
"chrome-untrusted://foo/",
"chrome-search://foo/",
"isolated-app://foo/",
#if BUILDFLAG(ENABLE_EXTENSIONS)
"chrome-extension://foo/",
#endif
"devtools://foo/",
};
for (const std::string& str : kChromeLayerUrlsRegisteredAsSecure) {
SCOPED_TRACE(str);
GURL url(str);
EXPECT_TRUE(base::Contains(url::GetSecureSchemes(), url.scheme()));
EXPECT_TRUE(network::IsUrlPotentiallyTrustworthy(url));
}
GURL chrome_url(content::GetWebUIURL("dummyurl"));
EXPECT_TRUE(network::IsUrlPotentiallyTrustworthy(chrome_url));
EXPECT_TRUE(content::OriginCanAccessServiceWorkers(chrome_url));
EXPECT_TRUE(
network::IsOriginPotentiallyTrustworthy(url::Origin::Create(chrome_url)));
}
class OriginTrialInitializationTestThread
: public base::PlatformThread::Delegate {
public:
explicit OriginTrialInitializationTestThread(
ChromeContentClient* chrome_client)
: chrome_client_(chrome_client) {}
OriginTrialInitializationTestThread(
const OriginTrialInitializationTestThread&) = delete;
OriginTrialInitializationTestThread& operator=(
const OriginTrialInitializationTestThread&) = delete;
void ThreadMain() override { AccessPolicy(chrome_client_, &policy_objects_); }
// Static helper which can also be called from the main thread.
static void AccessPolicy(
ChromeContentClient* content_client,
std::vector<raw_ptr<blink::OriginTrialPolicy, VectorExperimental>>*
policy_objects) {
// Repeatedly access the lazily-created origin trial policy
for (int i = 0; i < 20; i++) {
blink::OriginTrialPolicy* policy = content_client->GetOriginTrialPolicy();
policy_objects->push_back(policy);
base::PlatformThread::YieldCurrentThread();
}
}
const std::vector<raw_ptr<blink::OriginTrialPolicy, VectorExperimental>>*
policy_objects() const {
return &policy_objects_;
}
private:
raw_ptr<ChromeContentClient> chrome_client_;
std::vector<raw_ptr<blink::OriginTrialPolicy, VectorExperimental>>
policy_objects_;
};
// Test that the lazy initialization of Origin Trial policy is resistant to
// races with concurrent access. Failures (especially flaky) indicate that the
// race prevention is no longer sufficient.
TEST(ChromeContentClientTest, OriginTrialPolicyConcurrentInitialization) {
ChromeContentClient content_client;
std::vector<raw_ptr<blink::OriginTrialPolicy, VectorExperimental>>
policy_objects;
OriginTrialInitializationTestThread thread(&content_client);
base::PlatformThreadHandle handle;
ASSERT_TRUE(base::PlatformThread::Create(0, &thread, &handle));
// Repeatedly access the lazily-created origin trial policy
OriginTrialInitializationTestThread::AccessPolicy(&content_client,
&policy_objects);
base::PlatformThread::Join(handle);
ASSERT_EQ(20UL, policy_objects.size());
blink::OriginTrialPolicy* first_policy = policy_objects[0];
const std::vector<raw_ptr<blink::OriginTrialPolicy, VectorExperimental>>*
all_policy_objects[] = {
&policy_objects,
thread.policy_objects(),
};
for (const std::vector<raw_ptr<blink::OriginTrialPolicy, VectorExperimental>>*
thread_policy_objects : all_policy_objects) {
EXPECT_GE(20UL, thread_policy_objects->size());
for (blink::OriginTrialPolicy* policy : *(thread_policy_objects)) {
EXPECT_EQ(first_policy, policy);
}
}
}
} // namespace chrome_common