Optimize inherited permissions policy storage
`PermissionsPolicyFeatureState` used to store a map of _each_ enum value of `network::mojom::PermissionsPolicyFeature` to a boolean, telling whether the feature is enabled or not. There are more than a hundred enum values which makes this object large, expensive to copy, and expensive to mojo-serialze/deserialize. The new approach introduced in this CL stores this state on a bitset. Bug: 382291442 Change-Id: I798c58a04ece4b1c95c0940f4b92726ff0eeeddb Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6333964 Reviewed-by: Maks Orlovich <morlovich@chromium.org> Commit-Queue: Sandor «Alex» Major <sandormajor@chromium.org> Reviewed-by: David Bokan <bokan@chromium.org> Cr-Commit-Position: refs/heads/main@{#1429700}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
ad438f99b5
commit
5e79508c68
@ -355,6 +355,8 @@ component("web_platform") {
|
||||
"permissions_policy/permissions_policy_declaration.h",
|
||||
"permissions_policy/permissions_policy_features.cc",
|
||||
"permissions_policy/permissions_policy_features.h",
|
||||
"permissions_policy/permissions_policy_features_bitset.cc",
|
||||
"permissions_policy/permissions_policy_features_bitset.h",
|
||||
"permissions_policy/permissions_policy_features_generated.h",
|
||||
"permissions_policy/permissions_policy_features_internal.cc",
|
||||
"permissions_policy/permissions_policy_features_internal.h",
|
||||
@ -706,6 +708,7 @@ source_set("tests") {
|
||||
"parsed_request_cookie_mojom_traits_unittest.cc",
|
||||
"permissions_policy/origin_with_possible_wildcards_unittest.cc",
|
||||
"permissions_policy/permissions_policy_declaration_unittest.cc",
|
||||
"permissions_policy/permissions_policy_features_bitset_unittest.cc",
|
||||
"permissions_policy/permissions_policy_unittest.cc",
|
||||
"proxy_config_mojom_traits_unittest.cc",
|
||||
"request_destination_unittest.cc",
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "services/network/public/cpp/permissions_policy/origin_with_possible_wildcards.h"
|
||||
#include "services/network/public/cpp/permissions_policy/permissions_policy_declaration.h"
|
||||
#include "services/network/public/cpp/permissions_policy/permissions_policy_features.h"
|
||||
#include "services/network/public/cpp/permissions_policy/permissions_policy_features_bitset.h"
|
||||
#include "services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
|
||||
#include "services/network/public/mojom/web_sandbox_flags.mojom-shared.h"
|
||||
#include "url/gurl.h"
|
||||
@ -158,23 +159,24 @@ std::unique_ptr<PermissionsPolicy> PermissionsPolicy::CreateFromParsedPolicy(
|
||||
parsed_policy_for_isolated_app,
|
||||
const url::Origin& origin,
|
||||
const network::PermissionsPolicyFeatureList& features) {
|
||||
network::PermissionsPolicyFeatureState inherited_policies;
|
||||
network::PermissionsPolicyFeaturesBitset inherited_policies;
|
||||
AllowlistsAndReportingEndpoints allow_lists_and_reporting_endpoints =
|
||||
parsed_policy_for_isolated_app
|
||||
? CombinePolicies(parsed_policy_for_isolated_app.value(),
|
||||
parsed_policy)
|
||||
: CreateAllowlistsAndReportingEndpoints(parsed_policy);
|
||||
for (const auto& feature : features) {
|
||||
inherited_policies[feature.first] =
|
||||
base::Contains(allow_lists_and_reporting_endpoints.allowlists_,
|
||||
feature.first) &&
|
||||
allow_lists_and_reporting_endpoints.allowlists_[feature.first].Contains(
|
||||
origin);
|
||||
for (const auto& [feature, unused] : features) {
|
||||
if (base::Contains(allow_lists_and_reporting_endpoints.allowlists_,
|
||||
feature) &&
|
||||
allow_lists_and_reporting_endpoints.allowlists_[feature].Contains(
|
||||
origin)) {
|
||||
inherited_policies.Add(feature);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<PermissionsPolicy> new_policy = base::WrapUnique(
|
||||
new PermissionsPolicy(origin, allow_lists_and_reporting_endpoints,
|
||||
inherited_policies, features));
|
||||
std::move(inherited_policies), features));
|
||||
|
||||
return new_policy;
|
||||
}
|
||||
@ -187,8 +189,7 @@ bool PermissionsPolicy::IsHeaderlessUrl(const GURL& url) {
|
||||
|
||||
bool PermissionsPolicy::IsFeatureEnabledByInheritedPolicy(
|
||||
network::mojom::PermissionsPolicyFeature feature) const {
|
||||
DCHECK(base::Contains(inherited_policies_, feature));
|
||||
return inherited_policies_.at(feature);
|
||||
return inherited_policies_.Contains(feature);
|
||||
}
|
||||
|
||||
bool PermissionsPolicy::IsFeatureEnabled(
|
||||
@ -482,7 +483,7 @@ const network::mojom::PermissionsPolicyFeature
|
||||
PermissionsPolicy::PermissionsPolicy(
|
||||
url::Origin origin,
|
||||
AllowlistsAndReportingEndpoints allow_lists_and_reporting_endpoints,
|
||||
network::PermissionsPolicyFeatureState inherited_policies,
|
||||
network::PermissionsPolicyFeaturesBitset inherited_policies,
|
||||
const network::PermissionsPolicyFeatureList& feature_list,
|
||||
bool headerless)
|
||||
: origin_(std::move(origin)),
|
||||
@ -515,18 +516,17 @@ PermissionsPolicy::CreateFlexibleForFencedFrame(
|
||||
const network::ParsedPermissionsPolicy& container_policy,
|
||||
const url::Origin& subframe_origin,
|
||||
const network::PermissionsPolicyFeatureList& features) {
|
||||
network::PermissionsPolicyFeatureState inherited_policies;
|
||||
for (const auto& feature : features) {
|
||||
if (base::Contains(network::kFencedFrameAllowedFeatures, feature.first)) {
|
||||
inherited_policies[feature.first] = InheritedValueForFeature(
|
||||
subframe_origin, parent_policy, feature, container_policy);
|
||||
} else {
|
||||
inherited_policies[feature.first] = false;
|
||||
network::PermissionsPolicyFeaturesBitset inherited_policies;
|
||||
for (const auto& [feature, default_value] : features) {
|
||||
if (base::Contains(network::kFencedFrameAllowedFeatures, feature) &&
|
||||
InheritedValueForFeature(subframe_origin, parent_policy,
|
||||
{feature, default_value}, container_policy)) {
|
||||
inherited_policies.Add(feature);
|
||||
}
|
||||
}
|
||||
return base::WrapUnique(new PermissionsPolicy(
|
||||
subframe_origin, CreateAllowlistsAndReportingEndpoints(header_policy),
|
||||
inherited_policies, features));
|
||||
std::move(inherited_policies), features));
|
||||
}
|
||||
|
||||
// static
|
||||
@ -547,18 +547,15 @@ std::unique_ptr<PermissionsPolicy> PermissionsPolicy::CreateFixedForFencedFrame(
|
||||
const network::PermissionsPolicyFeatureList& features,
|
||||
base::span<const network::mojom::PermissionsPolicyFeature>
|
||||
effective_enabled_permissions) {
|
||||
network::PermissionsPolicyFeatureState inherited_policies;
|
||||
for (const auto& feature : features) {
|
||||
inherited_policies[feature.first] = false;
|
||||
}
|
||||
network::PermissionsPolicyFeaturesBitset inherited_policies;
|
||||
for (const network::mojom::PermissionsPolicyFeature feature :
|
||||
effective_enabled_permissions) {
|
||||
inherited_policies[feature] = true;
|
||||
inherited_policies.Add(feature);
|
||||
}
|
||||
|
||||
return base::WrapUnique(new PermissionsPolicy(
|
||||
origin, CreateAllowlistsAndReportingEndpoints(header_policy),
|
||||
inherited_policies, features));
|
||||
std::move(inherited_policies), features));
|
||||
}
|
||||
|
||||
// static
|
||||
@ -569,14 +566,16 @@ std::unique_ptr<PermissionsPolicy> PermissionsPolicy::CreateFromParentPolicy(
|
||||
const url::Origin& origin,
|
||||
const network::PermissionsPolicyFeatureList& features,
|
||||
bool headerless) {
|
||||
network::PermissionsPolicyFeatureState inherited_policies;
|
||||
for (const auto& feature : features) {
|
||||
inherited_policies[feature.first] = InheritedValueForFeature(
|
||||
origin, parent_policy, feature, container_policy);
|
||||
network::PermissionsPolicyFeaturesBitset inherited_policies;
|
||||
for (const auto& [feature, default_value] : features) {
|
||||
if (InheritedValueForFeature(origin, parent_policy,
|
||||
{feature, default_value}, container_policy)) {
|
||||
inherited_policies.Add(feature);
|
||||
}
|
||||
}
|
||||
return base::WrapUnique(new PermissionsPolicy(
|
||||
origin, CreateAllowlistsAndReportingEndpoints(header_policy),
|
||||
inherited_policies, features, headerless));
|
||||
std::move(inherited_policies), features, headerless));
|
||||
}
|
||||
|
||||
// Implements Permissions Policy 9.9: Is feature enabled in document for origin?
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "services/network/public/cpp/permissions_policy/origin_with_possible_wildcards.h"
|
||||
#include "services/network/public/cpp/permissions_policy/permissions_policy_declaration.h"
|
||||
#include "services/network/public/cpp/permissions_policy/permissions_policy_features.h"
|
||||
#include "services/network/public/cpp/permissions_policy/permissions_policy_features_bitset.h"
|
||||
#include "services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
|
||||
#include "services/network/public/mojom/web_sandbox_flags.mojom-shared.h"
|
||||
#include "url/origin.h"
|
||||
@ -321,7 +322,7 @@ class COMPONENT_EXPORT(NETWORK_CPP_WEB_PLATFORM) PermissionsPolicy {
|
||||
PermissionsPolicy(
|
||||
url::Origin origin,
|
||||
AllowlistsAndReportingEndpoints allow_lists_and_reporting_endpoints,
|
||||
network::PermissionsPolicyFeatureState inherited_policies,
|
||||
network::PermissionsPolicyFeaturesBitset inherited_policies,
|
||||
const network::PermissionsPolicyFeatureList& feature_list,
|
||||
bool headerless = false);
|
||||
static std::unique_ptr<PermissionsPolicy> CreateFromParentPolicy(
|
||||
@ -396,7 +397,7 @@ class COMPONENT_EXPORT(NETWORK_CPP_WEB_PLATFORM) PermissionsPolicy {
|
||||
|
||||
// Records whether or not each feature was enabled for this frame by its
|
||||
// parent frame.
|
||||
const network::PermissionsPolicyFeatureState inherited_policies_;
|
||||
const network::PermissionsPolicyFeaturesBitset inherited_policies_;
|
||||
|
||||
// The map of features to their default enable state.
|
||||
const raw_ref<const network::PermissionsPolicyFeatureList> feature_list_;
|
||||
|
@ -65,11 +65,6 @@ const PermissionsPolicyFeatureList& GetPermissionsPolicyFeatureList(
|
||||
COMPONENT_EXPORT(NETWORK_CPP_WEB_PLATFORM)
|
||||
void UpdatePermissionsPolicyFeatureListForTesting();
|
||||
|
||||
// TODO(iclelland): Generate, instead of this map, a set of bool flags, one
|
||||
// for each feature, as all features are supposed to be represented here.
|
||||
using PermissionsPolicyFeatureState =
|
||||
std::map<network::mojom::PermissionsPolicyFeature, bool>;
|
||||
|
||||
} // namespace network
|
||||
|
||||
#endif // SERVICES_NETWORK_PUBLIC_CPP_PERMISSIONS_POLICY_PERMISSIONS_POLICY_FEATURES_H_
|
||||
|
@ -0,0 +1,98 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "services/network/public/cpp/permissions_policy/permissions_policy_features_bitset.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "base/check_op.h"
|
||||
#include "base/containers/span.h"
|
||||
#include "services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
|
||||
|
||||
namespace network {
|
||||
|
||||
PermissionsPolicyFeaturesBitset::PermissionsPolicyFeaturesBitset(
|
||||
const PermissionsPolicyFeaturesBitset&) = default;
|
||||
PermissionsPolicyFeaturesBitset& PermissionsPolicyFeaturesBitset::operator=(
|
||||
const PermissionsPolicyFeaturesBitset&) = default;
|
||||
|
||||
PermissionsPolicyFeaturesBitset::PermissionsPolicyFeaturesBitset(
|
||||
PermissionsPolicyFeaturesBitset&&) = default;
|
||||
PermissionsPolicyFeaturesBitset& PermissionsPolicyFeaturesBitset::operator=(
|
||||
PermissionsPolicyFeaturesBitset&&) = default;
|
||||
|
||||
PermissionsPolicyFeaturesBitset::PermissionsPolicyFeaturesBitset() = default;
|
||||
|
||||
PermissionsPolicyFeaturesBitset::~PermissionsPolicyFeaturesBitset() = default;
|
||||
|
||||
void PermissionsPolicyFeaturesBitset::Add(
|
||||
network::mojom::PermissionsPolicyFeature feature) {
|
||||
size_t index = static_cast<size_t>(feature);
|
||||
CHECK_LT(index, kPermissionsPolicyFeaturesBitsetSize);
|
||||
size_t internal_index = ToInternalIndex(index);
|
||||
uint8_t bitmask = ToBitmask(index);
|
||||
bitset_[internal_index] |= bitmask;
|
||||
}
|
||||
|
||||
bool PermissionsPolicyFeaturesBitset::Contains(
|
||||
network::mojom::PermissionsPolicyFeature feature) const {
|
||||
return Contains(static_cast<size_t>(feature));
|
||||
}
|
||||
|
||||
bool PermissionsPolicyFeaturesBitset::Contains(size_t index) const {
|
||||
CHECK_LT(index, kPermissionsPolicyFeaturesBitsetSize);
|
||||
size_t internal_index = ToInternalIndex(index);
|
||||
uint8_t bitmask = ToBitmask(index);
|
||||
return (bitset_[internal_index] & bitmask) != 0;
|
||||
}
|
||||
|
||||
std::string PermissionsPolicyFeaturesBitset::Serialize() const {
|
||||
// Since the bitset is stored from right to left, as an optimization, omit all
|
||||
// the leftmost 0's.
|
||||
size_t offset;
|
||||
for (offset = 0; offset < bitset_.size(); ++offset) {
|
||||
if (bitset_[offset] != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
base::span<const char> s =
|
||||
base::as_chars(base::span(bitset_).subspan(offset));
|
||||
return std::string(s.begin(), s.end());
|
||||
}
|
||||
|
||||
bool PermissionsPolicyFeaturesBitset::Deserialize(std::string_view data) {
|
||||
if (data.size() > bitset_.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy the passed `data` to the end of the internal `bitset_`. For example,
|
||||
// if `data` is {0xAA, 0xBB}, and set size is 32 (so `bitset_` is a vector of
|
||||
// 4 uint8_t's), then the final `bitset_` should be {0x00, 0x00, 0xAA, 0xBB}.
|
||||
base::span(bitset_).last(data.size()).copy_from(base::as_byte_span((data)));
|
||||
|
||||
// Zero out the rest of `bitset_` to clear any residual data.
|
||||
size_t zero_count = kPermissionsPolicyFeaturesBitsetArraySize - data.size();
|
||||
if (zero_count > 0) {
|
||||
std::fill(bitset_.begin(), bitset_.begin() + zero_count, 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t PermissionsPolicyFeaturesBitset::bitset_size() const {
|
||||
return kPermissionsPolicyFeaturesBitsetSize;
|
||||
}
|
||||
|
||||
size_t PermissionsPolicyFeaturesBitset::ToInternalIndex(size_t index) const {
|
||||
// Note: internally, the bitset is stored from right to left. For example,
|
||||
// index 0 maps to the least significant bit of the last element of `bitset_`.
|
||||
return bitset_.size() - 1 - index / 8;
|
||||
}
|
||||
|
||||
uint8_t PermissionsPolicyFeaturesBitset::ToBitmask(size_t index) const {
|
||||
return 1 << (index % 8);
|
||||
}
|
||||
|
||||
} // namespace network
|
@ -0,0 +1,85 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SERVICES_NETWORK_PUBLIC_CPP_PERMISSIONS_POLICY_PERMISSIONS_POLICY_FEATURES_BITSET_H_
|
||||
#define SERVICES_NETWORK_PUBLIC_CPP_PERMISSIONS_POLICY_PERMISSIONS_POLICY_FEATURES_BITSET_H_
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "base/component_export.h"
|
||||
#include "base/gtest_prod_util.h"
|
||||
#include "services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
|
||||
|
||||
namespace network {
|
||||
|
||||
inline constexpr size_t kPermissionsPolicyFeaturesBitsetSize =
|
||||
static_cast<size_t>(network::mojom::PermissionsPolicyFeature::kMaxValue) +
|
||||
1;
|
||||
inline constexpr size_t kPermissionsPolicyFeaturesBitsetArraySize =
|
||||
1 + (kPermissionsPolicyFeaturesBitsetSize - 1) / 8;
|
||||
|
||||
// A custom bitset class used to keep track of permissions policy feature state
|
||||
// across processes. `std::bitset<>` and `base::EnumSet<>` are intentionally not
|
||||
// used because they do not provide the flexibility needed to efficiently
|
||||
// serialize/deserialize the set.
|
||||
class COMPONENT_EXPORT(NETWORK_CPP_WEB_PLATFORM)
|
||||
PermissionsPolicyFeaturesBitset {
|
||||
public:
|
||||
// Creates an empty PermissionsPolicyFeaturesBitset with the size of
|
||||
// `network::mojom::PermissionsPolicyFeature`.
|
||||
explicit PermissionsPolicyFeaturesBitset();
|
||||
|
||||
PermissionsPolicyFeaturesBitset(const PermissionsPolicyFeaturesBitset&);
|
||||
PermissionsPolicyFeaturesBitset& operator=(
|
||||
const PermissionsPolicyFeaturesBitset&);
|
||||
|
||||
PermissionsPolicyFeaturesBitset(PermissionsPolicyFeaturesBitset&&);
|
||||
PermissionsPolicyFeaturesBitset& operator=(PermissionsPolicyFeaturesBitset&&);
|
||||
|
||||
friend bool operator==(const PermissionsPolicyFeaturesBitset&,
|
||||
const PermissionsPolicyFeaturesBitset&) = default;
|
||||
|
||||
~PermissionsPolicyFeaturesBitset();
|
||||
|
||||
// Adds the given `feature` to the bitset.
|
||||
void Add(network::mojom::PermissionsPolicyFeature feature);
|
||||
// Returns whether the given `feature` is present in the bitset.
|
||||
bool Contains(network::mojom::PermissionsPolicyFeature feature) const;
|
||||
|
||||
// Serializes `this` and returns the compressed value. The bitset can be
|
||||
// deserialized with `Deserialize()`.
|
||||
std::string Serialize() const;
|
||||
|
||||
// Deserializes the bitset from `data`. If `data` is longer than the bitset,
|
||||
// returns false.
|
||||
bool Deserialize(std::string_view data);
|
||||
|
||||
// Size of the bitset as number of bits.
|
||||
size_t bitset_size() const;
|
||||
|
||||
private:
|
||||
FRIEND_TEST_ALL_PREFIXES(PermissionsPolicyFeaturesBitsetTest,
|
||||
PermissionsPolicyFeaturesBitset);
|
||||
FRIEND_TEST_ALL_PREFIXES(PermissionsPolicyFeaturesBitsetTest,
|
||||
DeserializePartialData);
|
||||
FRIEND_TEST_ALL_PREFIXES(PermissionsPolicyFeaturesBitsetTest,
|
||||
DeserializeRepeatedly);
|
||||
|
||||
// Returns whether the given `index` is present in the bitset. Carved out of
|
||||
// the public `Contains()` method to make it available for tests because the
|
||||
// enums are not sequential.
|
||||
bool Contains(size_t index) const;
|
||||
// Returns which element `index` maps to in `bitset_`.
|
||||
size_t ToInternalIndex(size_t index) const;
|
||||
// Returns which bit `index` maps to given a certain `bitset_` element.
|
||||
uint8_t ToBitmask(size_t index) const;
|
||||
|
||||
std::array<uint8_t, kPermissionsPolicyFeaturesBitsetArraySize> bitset_ = {};
|
||||
};
|
||||
|
||||
} // namespace network
|
||||
|
||||
#endif // SERVICES_NETWORK_PUBLIC_CPP_PERMISSIONS_POLICY_PERMISSIONS_POLICY_FEATURES_BITSET_H_
|
103
services/network/public/cpp/permissions_policy/permissions_policy_features_bitset_unittest.cc
Normal file
103
services/network/public/cpp/permissions_policy/permissions_policy_features_bitset_unittest.cc
Normal file
@ -0,0 +1,103 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "services/network/public/cpp/permissions_policy/permissions_policy_features_bitset.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace network {
|
||||
|
||||
TEST(PermissionsPolicyFeaturesBitsetTest, PermissionsPolicyFeaturesBitset) {
|
||||
// Create a bitset and verify that it is initially empty.
|
||||
PermissionsPolicyFeaturesBitset bitset1;
|
||||
EXPECT_EQ(kPermissionsPolicyFeaturesBitsetSize, bitset1.bitset_size());
|
||||
for (size_t i = 0; i < bitset1.bitset_size(); ++i) {
|
||||
EXPECT_FALSE(bitset1.Contains(i));
|
||||
}
|
||||
EXPECT_TRUE(bitset1.Serialize().empty());
|
||||
|
||||
// Add some elements to the bitset, and verify they can be looked up.
|
||||
bitset1.Add(network::mojom::PermissionsPolicyFeature::kNotFound);
|
||||
bitset1.Add(network::mojom::PermissionsPolicyFeature::kUsb);
|
||||
for (size_t i = 0; i < bitset1.bitset_size(); ++i) {
|
||||
EXPECT_EQ(bitset1.Contains(i), i == 0 || i == 14);
|
||||
}
|
||||
|
||||
// Serialize the bitset. The trailing zeros should be optimized away, and
|
||||
// the resulting output should fit in 2 bytes (0b01000000 and 0b00000001).
|
||||
std::string serialized = bitset1.Serialize();
|
||||
EXPECT_EQ(serialized.size(), 2U);
|
||||
EXPECT_EQ(static_cast<uint8_t>(serialized[0]), 0b01000000);
|
||||
EXPECT_EQ(static_cast<uint8_t>(serialized[1]), 0b00000001);
|
||||
|
||||
// Create a new bitset using the serialized data and verify that it contains
|
||||
// the same data.
|
||||
PermissionsPolicyFeaturesBitset bitset2;
|
||||
EXPECT_TRUE(bitset2.Deserialize(serialized));
|
||||
EXPECT_EQ(kPermissionsPolicyFeaturesBitsetSize, bitset2.bitset_size());
|
||||
for (size_t i = 0; i < bitset2.bitset_size(); ++i) {
|
||||
EXPECT_EQ(bitset1.Contains(i), bitset2.Contains(i));
|
||||
}
|
||||
|
||||
// Do some last few checks for good measure.
|
||||
bitset2.Add(network::mojom::PermissionsPolicyFeature::kScreenWakeLock);
|
||||
// Adding the same element a second time should have no impact.
|
||||
bitset2.Add(network::mojom::PermissionsPolicyFeature::kScreenWakeLock);
|
||||
for (size_t i = 0; i < bitset2.bitset_size(); ++i) {
|
||||
EXPECT_EQ(bitset2.Contains(i), i == 0 || i == 14 || i == 31);
|
||||
}
|
||||
serialized = bitset2.Serialize();
|
||||
EXPECT_EQ(serialized.size(), 4U);
|
||||
EXPECT_EQ(static_cast<uint8_t>(serialized[0]), 0b10000000);
|
||||
EXPECT_EQ(static_cast<uint8_t>(serialized[1]), 0b00000000);
|
||||
EXPECT_EQ(static_cast<uint8_t>(serialized[2]), 0b01000000);
|
||||
EXPECT_EQ(static_cast<uint8_t>(serialized[3]), 0b00000001);
|
||||
}
|
||||
|
||||
TEST(PermissionsPolicyFeaturesBitsetTest, DeserializeTooLargeData) {
|
||||
std::string data(kPermissionsPolicyFeaturesBitsetArraySize + 1, 0xFF);
|
||||
PermissionsPolicyFeaturesBitset bitset;
|
||||
EXPECT_FALSE(bitset.Deserialize(data));
|
||||
}
|
||||
|
||||
TEST(PermissionsPolicyFeaturesBitsetTest, DeserializePartialData) {
|
||||
PermissionsPolicyFeaturesBitset bitset;
|
||||
std::string data = "\x01\x02\x03";
|
||||
ASSERT_TRUE(bitset.Deserialize(data));
|
||||
|
||||
std::array<uint8_t, kPermissionsPolicyFeaturesBitsetArraySize>
|
||||
expected_bitset = {};
|
||||
expected_bitset[kPermissionsPolicyFeaturesBitsetArraySize - 3] = 0x01;
|
||||
expected_bitset[kPermissionsPolicyFeaturesBitsetArraySize - 2] = 0x02;
|
||||
expected_bitset[kPermissionsPolicyFeaturesBitsetArraySize - 1] = 0x03;
|
||||
|
||||
EXPECT_EQ(bitset.bitset_, expected_bitset);
|
||||
}
|
||||
|
||||
TEST(PermissionsPolicyFeaturesBitsetTest, DeserializeRepeatedly) {
|
||||
PermissionsPolicyFeaturesBitset bitset;
|
||||
std::string data1 = "\xAA\xBB";
|
||||
ASSERT_TRUE(bitset.Deserialize(data1));
|
||||
|
||||
std::array<uint8_t, kPermissionsPolicyFeaturesBitsetArraySize>
|
||||
expected_bitset1 = {};
|
||||
expected_bitset1[kPermissionsPolicyFeaturesBitsetArraySize - 2] = 0xAA;
|
||||
expected_bitset1[kPermissionsPolicyFeaturesBitsetArraySize - 1] = 0xBB;
|
||||
|
||||
ASSERT_EQ(bitset.bitset_, expected_bitset1);
|
||||
|
||||
std::string data2 = "\xCC";
|
||||
ASSERT_TRUE(bitset.Deserialize(data2));
|
||||
|
||||
std::array<uint8_t, kPermissionsPolicyFeaturesBitsetArraySize>
|
||||
expected_bitset2 = {};
|
||||
expected_bitset2[kPermissionsPolicyFeaturesBitsetArraySize - 1] = 0xCC;
|
||||
|
||||
ASSERT_EQ(bitset.bitset_, expected_bitset2);
|
||||
}
|
||||
|
||||
} // namespace network
|
@ -29,25 +29,17 @@ namespace network {
|
||||
namespace {
|
||||
|
||||
const network::mojom::PermissionsPolicyFeature kDefaultOnFeature =
|
||||
static_cast<network::mojom::PermissionsPolicyFeature>(
|
||||
static_cast<int>(network::mojom::PermissionsPolicyFeature::kMaxValue) +
|
||||
1);
|
||||
network::mojom::PermissionsPolicyFeature::kDeferredFetchMinimal;
|
||||
|
||||
const network::mojom::PermissionsPolicyFeature kDefaultSelfFeature =
|
||||
static_cast<network::mojom::PermissionsPolicyFeature>(
|
||||
static_cast<int>(network::mojom::PermissionsPolicyFeature::kMaxValue) +
|
||||
2);
|
||||
network::mojom::PermissionsPolicyFeature::kAmbientLightSensor;
|
||||
|
||||
const network::mojom::PermissionsPolicyFeature kDefaultOffFeature =
|
||||
static_cast<network::mojom::PermissionsPolicyFeature>(
|
||||
static_cast<int>(network::mojom::PermissionsPolicyFeature::kMaxValue) +
|
||||
3);
|
||||
network::mojom::PermissionsPolicyFeature::kUnload;
|
||||
|
||||
// This feature is defined in code, but not present in the feature list.
|
||||
// This feature is defined in mojo, but not present in the feature list.
|
||||
const network::mojom::PermissionsPolicyFeature kUnavailableFeature =
|
||||
static_cast<network::mojom::PermissionsPolicyFeature>(
|
||||
static_cast<int>(network::mojom::PermissionsPolicyFeature::kMaxValue) +
|
||||
4);
|
||||
network::mojom::PermissionsPolicyFeature::kNotFound;
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -135,7 +127,7 @@ class PermissionsPolicyTest : public testing::Test {
|
||||
bool PolicyContainsInheritedValue(
|
||||
const PermissionsPolicy* policy,
|
||||
network::mojom::PermissionsPolicyFeature feature) {
|
||||
return base::Contains(policy->inherited_policies_, feature);
|
||||
return policy->inherited_policies_.Contains(feature);
|
||||
}
|
||||
|
||||
url::Origin origin_a_ = url::Origin::Create(GURL("https://example.com/"));
|
||||
|
@ -2149,7 +2149,6 @@ WebLocalFrameImpl* WebLocalFrameImpl::CreateProvisional(
|
||||
frame_token);
|
||||
network::mojom::blink::WebSandboxFlags sandbox_flags =
|
||||
network::mojom::blink::WebSandboxFlags::kNone;
|
||||
network::PermissionsPolicyFeatureState feature_state;
|
||||
if (!previous_frame->Owner() || previous_frame->IsFencedFrameRoot()) {
|
||||
// Provisional main frames need to force sandbox flags. This is necessary
|
||||
// to inherit sandbox flags when a sandboxed frame does a window.open()
|
||||
|
Reference in New Issue
Block a user