0

[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:
Asanka Herath
2020-09-29 05:30:43 +00:00
committed by Commit Bot
parent 35137ce628
commit 74ec31fc6a
7 changed files with 22 additions and 207 deletions

@ -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