[privacy-budget] Cleanup IdentifiabilityDigestHelper
There are two methods of converting a value to a IdentifiableToken: either directly via the IdentifiableToken constructor or through IdentifiabilityDigestHelper. Differences between the two can result in different digests. This change removes the latter. Bug: 973801 Change-Id: Ic4fa466afe76abb6288fc024d34f32f05be32018 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2433029 Commit-Queue: Asanka Herath <asanka@chromium.org> Reviewed-by: Kentaro Hara <haraken@chromium.org> Reviewed-by: Caleb Raitto <caraitto@chromium.org> Reviewed-by: Reilly Grant <reillyg@chromium.org> Cr-Commit-Position: refs/heads/master@{#811586}
This commit is contained in:

committed by
Commit Bot

parent
35137ce628
commit
74ec31fc6a
chrome/browser/extensions
extensions/common
third_party/blink
common
privacy_budget
public
common
privacy_budget
renderer
core
@ -157,16 +157,12 @@ class ExtensionNavigationThrottleUnitTest
|
||||
ASSERT_EQ(1u, entries.size());
|
||||
EXPECT_EQ(source_id, entries[0].source);
|
||||
ASSERT_EQ(1u, entries[0].metrics.size());
|
||||
EXPECT_EQ(
|
||||
blink::IdentifiableSurface::FromTypeAndInput(
|
||||
blink::IdentifiableSurface::Type::kExtensionFileAccess,
|
||||
blink::IdentifiabilityDigestOfBytes(base::as_bytes(base::make_span(
|
||||
ExtensionSet::GetExtensionIdByURL(extension_url)))))
|
||||
.ToUkmMetricHash(),
|
||||
entries[0].metrics[0].surface.ToUkmMetricHash());
|
||||
EXPECT_EQ(
|
||||
blink::IdentifiabilityDigestHelper(expected),
|
||||
static_cast<uint64_t>(entries[0].metrics[0].value.ToUkmMetricValue()));
|
||||
EXPECT_EQ(blink::IdentifiableSurface::FromTypeAndToken(
|
||||
blink::IdentifiableSurface::Type::kExtensionFileAccess,
|
||||
base::as_bytes(base::make_span(
|
||||
ExtensionSet::GetExtensionIdByURL(extension_url)))),
|
||||
entries[0].metrics[0].surface);
|
||||
EXPECT_EQ(blink::IdentifiableToken(expected), entries[0].metrics[0].value);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -321,15 +321,11 @@ class ExtensionProtocolsTestBase : public testing::Test {
|
||||
ASSERT_EQ(1u, entries.size());
|
||||
EXPECT_EQ(test_ukm_id_, entries[0].source);
|
||||
ASSERT_EQ(1u, entries[0].metrics.size());
|
||||
EXPECT_EQ(blink::IdentifiableSurface::FromTypeAndInput(
|
||||
EXPECT_EQ(blink::IdentifiableSurface::FromTypeAndToken(
|
||||
blink::IdentifiableSurface::Type::kExtensionFileAccess,
|
||||
blink::IdentifiabilityDigestOfBytes(
|
||||
base::as_bytes(base::make_span(extension->id()))))
|
||||
.ToUkmMetricHash(),
|
||||
entries[0].metrics[0].surface.ToUkmMetricHash());
|
||||
EXPECT_EQ(
|
||||
blink::IdentifiabilityDigestHelper(expected),
|
||||
static_cast<uint64_t>(entries[0].metrics[0].value.ToUkmMetricValue()));
|
||||
base::as_bytes(base::make_span(extension->id()))),
|
||||
entries[0].metrics[0].surface);
|
||||
EXPECT_EQ(blink::IdentifiableToken(expected), entries[0].metrics[0].value);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -7,16 +7,14 @@
|
||||
#include "extensions/common/extension_set.h"
|
||||
#include "services/metrics/public/cpp/ukm_recorder.h"
|
||||
#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
|
||||
#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
blink::IdentifiableSurface SurfaceForExtension(
|
||||
blink::IdentifiableSurface::Type type,
|
||||
const ExtensionId& extension_id) {
|
||||
return blink::IdentifiableSurface::FromTypeAndInput(
|
||||
type, blink::IdentifiabilityDigestOfBytes(
|
||||
base::as_bytes(base::make_span(extension_id))));
|
||||
return blink::IdentifiableSurface::FromTypeAndToken(
|
||||
type, base::as_bytes(base::make_span(extension_id)));
|
||||
}
|
||||
|
||||
void RecordExtensionResourceAccessResult(base::UkmSourceId ukm_source_id,
|
||||
@ -30,7 +28,7 @@ void RecordExtensionResourceAccessResult(base::UkmSourceId ukm_source_id,
|
||||
.Set(SurfaceForExtension(
|
||||
blink::IdentifiableSurface::Type::kExtensionFileAccess,
|
||||
extension_id),
|
||||
blink::IdentifiabilityDigestHelper(result))
|
||||
result)
|
||||
.Record(ukm::UkmRecorder::Get());
|
||||
}
|
||||
|
||||
@ -42,7 +40,7 @@ void RecordContentScriptInjection(base::UkmSourceId ukm_source_id,
|
||||
.Set(SurfaceForExtension(
|
||||
blink::IdentifiableSurface::Type::kExtensionContentScript,
|
||||
extension_id),
|
||||
blink::IdentifiabilityDigestHelper(true))
|
||||
/* Succeeded= */ true)
|
||||
.Record(ukm::UkmRecorder::Get());
|
||||
}
|
||||
|
||||
@ -54,7 +52,7 @@ void RecordNetworkRequestBlocked(base::UkmSourceId ukm_source_id,
|
||||
.Set(SurfaceForExtension(
|
||||
blink::IdentifiableSurface::Type::kExtensionCancelRequest,
|
||||
extension_id),
|
||||
blink::IdentifiabilityDigestHelper(true))
|
||||
/* Succeeded= */ true)
|
||||
.Record(ukm::UkmRecorder::Get());
|
||||
}
|
||||
|
||||
|
@ -41,104 +41,4 @@ TEST(IdentifiabilityMetricsTest, IdentifiabilityDigestOfBytes_EdgeCases) {
|
||||
IdentifiabilityDigestOfBytes(kOneByte));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassInt) {
|
||||
EXPECT_EQ(UINT64_C(5), IdentifiabilityDigestHelper(5));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassChar) {
|
||||
EXPECT_EQ(UINT64_C(97), IdentifiabilityDigestHelper('a'));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassBool) {
|
||||
EXPECT_EQ(UINT64_C(1), IdentifiabilityDigestHelper(true));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassLong) {
|
||||
EXPECT_EQ(UINT64_C(5), IdentifiabilityDigestHelper(5L));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassUint16) {
|
||||
EXPECT_EQ(UINT64_C(5), IdentifiabilityDigestHelper(static_cast<uint16_t>(5)));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassSizeT) {
|
||||
EXPECT_EQ(UINT64_C(1), IdentifiabilityDigestHelper(sizeof(char)));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassFloat) {
|
||||
EXPECT_NE(UINT64_C(0), IdentifiabilityDigestHelper(5.0f));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassDouble) {
|
||||
EXPECT_NE(UINT64_C(0), IdentifiabilityDigestHelper(5.0));
|
||||
}
|
||||
|
||||
// Use an arbitrary, large number to make accidental matches unlikely.
|
||||
enum SimpleEnum { kSimpleValue = 2730421 };
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassEnum) {
|
||||
EXPECT_EQ(UINT64_C(2730421), IdentifiabilityDigestHelper(kSimpleValue));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Use an arbitrary, large number to make accidental matches unlikely.
|
||||
enum Simple64Enum : uint64_t { kSimple64Value = 4983422 };
|
||||
|
||||
// Use an arbitrary, large number to make accidental matches unlikely.
|
||||
enum class SimpleEnumClass { kSimpleValue = 3498249 };
|
||||
|
||||
// Use an arbitrary, large number to make accidental matches unlikely.
|
||||
enum class SimpleEnumClass64 : uint64_t { kSimple64Value = 4398372 };
|
||||
|
||||
constexpr uint64_t kExpectedCombinationResult = UINT64_C(0xa5e30a57547cd49b);
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassEnum64) {
|
||||
EXPECT_EQ(UINT64_C(4983422), IdentifiabilityDigestHelper(kSimple64Value));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassEnumClass) {
|
||||
EXPECT_EQ(UINT64_C(3498249),
|
||||
IdentifiabilityDigestHelper(SimpleEnumClass::kSimpleValue));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassEnumClass64) {
|
||||
EXPECT_EQ(UINT64_C(4398372),
|
||||
IdentifiabilityDigestHelper(SimpleEnumClass64::kSimple64Value));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassSpan) {
|
||||
const int data[] = {1, 2, 3};
|
||||
EXPECT_EQ(UINT64_C(0xb0dd8c7041b0a8bb),
|
||||
IdentifiabilityDigestHelper(base::make_span(data)));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, PassSpanDouble) {
|
||||
const double data[] = {1.0, 2.0, 3.0};
|
||||
EXPECT_EQ(UINT64_C(0x95f52e9784f9582a),
|
||||
IdentifiabilityDigestHelper(base::make_span(data)));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, Combination) {
|
||||
const int data[] = {1, 2, 3};
|
||||
EXPECT_EQ(kExpectedCombinationResult,
|
||||
IdentifiabilityDigestHelper(
|
||||
5, 'a', true, static_cast<uint16_t>(5), sizeof(char),
|
||||
kSimpleValue, kSimple64Value, SimpleEnumClass::kSimpleValue,
|
||||
SimpleEnumClass64::kSimple64Value, base::make_span(data)));
|
||||
}
|
||||
|
||||
TEST(IdentifiabilityMetricsTest, CombinationWithFloats) {
|
||||
const int data[] = {1, 2, 3};
|
||||
const int data_doubles[] = {1.0, 2.0, 3.0};
|
||||
EXPECT_NE(kExpectedCombinationResult,
|
||||
IdentifiabilityDigestHelper(
|
||||
5, 'a', true, static_cast<uint16_t>(5), sizeof(char),
|
||||
kSimpleValue, kSimple64Value, SimpleEnumClass::kSimpleValue,
|
||||
SimpleEnumClass64::kSimple64Value, 5.0f, 5.0,
|
||||
base::make_span(data), base::make_span(data_doubles)));
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
|
@ -37,80 +37,6 @@ namespace blink {
|
||||
BLINK_COMMON_EXPORT uint64_t
|
||||
IdentifiabilityDigestOfBytes(base::span<const uint8_t> in);
|
||||
|
||||
// A family of helper function overloads that produce digests for basic types.
|
||||
// If sizeof(in) <= 64, the underlying bits are used directly; no hash is
|
||||
// invoked.
|
||||
//
|
||||
// The set of supported types can be extended by declaring overloads of
|
||||
// IdentifiabilityDigestHelper(); such declarations should be made in a header
|
||||
// included before this header so that they can be used by the span and
|
||||
// parameter pack overloads of IdentifiabilityDigestHelper.
|
||||
//
|
||||
// TODO(asanka): Remove once callers have been migrated to
|
||||
// IdentifiabilityToken().
|
||||
|
||||
// Integer version.
|
||||
template <typename T,
|
||||
typename std::enable_if_t<std::is_integral<T>::value>* = nullptr>
|
||||
uint64_t IdentifiabilityDigestHelper(T in) {
|
||||
static_assert(sizeof(in) <= sizeof(uint64_t),
|
||||
"The input type must be smaller than 64 bits.");
|
||||
return in;
|
||||
}
|
||||
|
||||
// Floating-point version. Note that this doesn't account for endianness, and
|
||||
// that integer and floating point endianness need not match for a given
|
||||
// architecture.
|
||||
template <
|
||||
typename T,
|
||||
typename std::enable_if_t<std::is_floating_point<T>::value>* = nullptr>
|
||||
uint64_t IdentifiabilityDigestHelper(T in) {
|
||||
static_assert(sizeof(in) <= sizeof(uint64_t),
|
||||
"The input type must be smaller than 64 bits.");
|
||||
uint64_t result = 0;
|
||||
std::memcpy(&result, &in, sizeof(in));
|
||||
return result;
|
||||
}
|
||||
|
||||
// Enum version. This just casts to the underlying type of the enum, which is
|
||||
// then converted to uint64_t.
|
||||
template <typename T,
|
||||
typename std::enable_if_t<std::is_enum<T>::value>* = nullptr>
|
||||
uint64_t IdentifiabilityDigestHelper(T in) {
|
||||
static_assert(sizeof(in) <= sizeof(uint64_t),
|
||||
"The input type must be smaller than 64 bits.");
|
||||
return static_cast<typename std::underlying_type<T>::type>(in);
|
||||
}
|
||||
|
||||
// Computes a combined digest for a span of elements. T can be any type
|
||||
// supported by a IdentifiabilityDigestHelper overload declared before this
|
||||
// function.
|
||||
template <typename T, size_t Extent>
|
||||
uint64_t IdentifiabilityDigestHelper(base::span<T, Extent> span) {
|
||||
uint64_t cur_digest = 0;
|
||||
for (const auto& element : span) {
|
||||
uint64_t digests[2];
|
||||
digests[0] = cur_digest;
|
||||
digests[1] = IdentifiabilityDigestHelper(element);
|
||||
cur_digest = IdentifiabilityDigestOfBytes(
|
||||
base::make_span(reinterpret_cast<uint8_t*>(digests), sizeof(digests)));
|
||||
}
|
||||
return cur_digest;
|
||||
}
|
||||
|
||||
// Computes a combined digest value for a series of elements passed in as
|
||||
// arguments. This declaration must appear after any other
|
||||
// IdentifiabilityDigestHelper()
|
||||
// overloads.
|
||||
template <typename T, typename... Targs>
|
||||
uint64_t IdentifiabilityDigestHelper(T in, Targs... extra_in) {
|
||||
uint64_t digests[2];
|
||||
digests[0] = IdentifiabilityDigestHelper(in);
|
||||
digests[1] = IdentifiabilityDigestHelper(extra_in...);
|
||||
return IdentifiabilityDigestOfBytes(
|
||||
base::make_span(reinterpret_cast<uint8_t*>(digests), sizeof(digests)));
|
||||
}
|
||||
|
||||
// The zero-length digest, i.e. the digest computed for no bytes.
|
||||
static constexpr uint64_t kIdentifiabilityDigestOfNoBytes =
|
||||
0x9ae16a3b2f90404fULL;
|
||||
|
@ -260,8 +260,8 @@ void HTMLCanvasElement::RegisterRenderingContextFactory(
|
||||
}
|
||||
|
||||
void HTMLCanvasElement::RecordIdentifiabilityMetric(
|
||||
const blink::IdentifiableSurface& surface,
|
||||
int64_t value) const {
|
||||
IdentifiableSurface surface,
|
||||
IdentifiableToken value) const {
|
||||
blink::IdentifiabilityMetricBuilder(GetDocument().UkmSourceID())
|
||||
.Set(surface, value)
|
||||
.Record(GetDocument().UkmRecorder());
|
||||
@ -335,11 +335,10 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContextInternal(
|
||||
if (!context_) {
|
||||
if (IsUserInIdentifiabilityStudy()) {
|
||||
RecordIdentifiabilityMetric(
|
||||
blink::IdentifiableSurface::FromTypeAndInput(
|
||||
IdentifiableSurface::FromTypeAndToken(
|
||||
blink::IdentifiableSurface::Type::kWebFeature,
|
||||
static_cast<uint64_t>(
|
||||
blink::WebFeature::kCanvasRenderingContext)),
|
||||
blink::IdentifiabilityDigestHelper(context_type));
|
||||
blink::WebFeature::kCanvasRenderingContext),
|
||||
context_type);
|
||||
}
|
||||
UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.ContextType", context_type);
|
||||
}
|
||||
|
@ -320,8 +320,8 @@ class CORE_EXPORT HTMLCanvasElement final
|
||||
private:
|
||||
void Dispose();
|
||||
|
||||
void RecordIdentifiabilityMetric(const blink::IdentifiableSurface& surface,
|
||||
int64_t value) const;
|
||||
void RecordIdentifiabilityMetric(IdentifiableSurface surface,
|
||||
IdentifiableToken value) const;
|
||||
|
||||
// If the user is enrolled in the identifiability study, report the canvas
|
||||
// type, and if applicable, canvas digest, taint bits, and
|
||||
|
Reference in New Issue
Block a user