861 lines
37 KiB
Diff
861 lines
37 KiB
Diff
|
From: csagan5 <32685696+csagan5@users.noreply.github.com>
|
||
|
Date: Fri, 30 Mar 2018 10:09:03 +0200
|
||
|
Subject: Multiple fingerprinting mitigations
|
||
|
|
||
|
1. getClientRects, getBoundingClientRect, measureText: add fingerprinting mitigation
|
||
|
|
||
|
Scale the result of Range::getClientRects, Element::getBoundingClientRect and
|
||
|
Canvas::measureText by a random +/-3/1000000th of the original value for each
|
||
|
float in the returned Rect/Quad.
|
||
|
|
||
|
It contains improvements from ungoogled-chromium which add two flags:
|
||
|
1. --fingerprinting-client-rects-noise to enable fingerprinting deception for Range::getClientRects and Element::getBoundingClientRect
|
||
|
2. --fingerprinting-canvas-measuretext-noise to enable fingerprinting deception for Canvas::measureText
|
||
|
|
||
|
2. Canvas: fingerprinting mitigations for image data
|
||
|
|
||
|
Modify the color data returned by ToBlob, ToDataURL and getImageData so that
|
||
|
it will contain randomly manipulated pixels (maximum 20) that slightly change
|
||
|
the color of the R,G,B components without a visible effect.
|
||
|
|
||
|
Credits to Slaviro (https://github.com/Slaviro) for coming up with a better
|
||
|
approach to change color components.
|
||
|
|
||
|
Added flag --fingerprinting-canvas-image-data-noise to disable Canvas image data fingerprinting deception
|
||
|
Add noise also to SVGs (credits to uazo)
|
||
|
|
||
|
License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html
|
||
|
---
|
||
|
chrome/browser/BUILD.gn | 1 +
|
||
|
chrome/browser/about_flags.cc | 16 ++
|
||
|
content/browser/BUILD.gn | 1 +
|
||
|
.../renderer_host/render_process_host_impl.cc | 4 +
|
||
|
content/child/BUILD.gn | 1 +
|
||
|
content/child/runtime_features.cc | 8 +
|
||
|
.../public/platform/web_runtime_features.h | 3 +
|
||
|
.../blink/renderer/core/dom/document.cc | 20 +++
|
||
|
.../blink/renderer/core/dom/document.h | 7 +
|
||
|
.../blink/renderer/core/dom/element.cc | 8 +
|
||
|
third_party/blink/renderer/core/dom/range.cc | 12 +-
|
||
|
.../html/canvas/canvas_async_blob_creator.cc | 5 +
|
||
|
.../renderer/core/html/canvas/text_metrics.cc | 18 ++
|
||
|
.../renderer/core/html/canvas/text_metrics.h | 2 +
|
||
|
.../renderer/core/svg/svg_graphics_element.cc | 2 +
|
||
|
.../core/svg/svg_text_content_element.cc | 28 +++-
|
||
|
.../canvas2d/base_rendering_context_2d.cc | 24 ++-
|
||
|
third_party/blink/renderer/platform/BUILD.gn | 5 +-
|
||
|
.../platform/exported/web_runtime_features.cc | 12 ++
|
||
|
.../platform/graphics/image_data_buffer.cc | 7 +
|
||
|
.../platform/graphics/static_bitmap_image.cc | 155 ++++++++++++++++++
|
||
|
.../platform/graphics/static_bitmap_image.h | 2 +
|
||
|
.../platform/runtime_enabled_features.json5 | 9 +
|
||
|
third_party/ungoogled/BUILD.gn | 10 ++
|
||
|
third_party/ungoogled/ungoogled_switches.cc | 18 ++
|
||
|
third_party/ungoogled/ungoogled_switches.h | 18 ++
|
||
|
26 files changed, 388 insertions(+), 8 deletions(-)
|
||
|
create mode 100644 third_party/ungoogled/BUILD.gn
|
||
|
create mode 100644 third_party/ungoogled/ungoogled_switches.cc
|
||
|
create mode 100644 third_party/ungoogled/ungoogled_switches.h
|
||
|
|
||
|
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
|
||
|
--- a/chrome/browser/BUILD.gn
|
||
|
+++ b/chrome/browser/BUILD.gn
|
||
|
@@ -2530,6 +2530,7 @@ static_library("browser") {
|
||
|
"//services/device/public/cpp:device_features",
|
||
|
"//services/device/public/cpp/geolocation",
|
||
|
"//services/device/public/cpp/usb",
|
||
|
+ "//third_party/ungoogled:switches",
|
||
|
"//services/device/public/mojom",
|
||
|
"//services/device/public/mojom:usb",
|
||
|
"//services/image_annotation:service",
|
||
|
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
|
||
|
--- a/chrome/browser/about_flags.cc
|
||
|
+++ b/chrome/browser/about_flags.cc
|
||
|
@@ -227,6 +227,8 @@
|
||
|
#include "ui/ui_features.h"
|
||
|
#include "url/url_features.h"
|
||
|
|
||
|
+#include "third_party/ungoogled/ungoogled_switches.h"
|
||
|
+
|
||
|
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||
|
#include "base/allocator/buildflags.h"
|
||
|
#endif
|
||
|
@@ -4160,6 +4162,20 @@ const FeatureEntry kFeatureEntries[] = {
|
||
|
flag_descriptions::kWebrtcUseMinMaxVEADimensionsName,
|
||
|
flag_descriptions::kWebrtcUseMinMaxVEADimensionsDescription, kOsAll,
|
||
|
FEATURE_VALUE_TYPE(blink::features::kWebRtcUseMinMaxVEADimensions)},
|
||
|
+
|
||
|
+ {"fingerprinting-canvas-image-data-noise",
|
||
|
+ "Disable Canvas image data fingerprint deception",
|
||
|
+ "Slightly modifies at most 20 pixels in Canvas image data extracted via JS APIs",
|
||
|
+ kOsAll, SINGLE_DISABLE_VALUE_TYPE(switches::kFingerprintingCanvasImageDataNoise)},
|
||
|
+ {"fingerprinting-client-rects-noise",
|
||
|
+ "Disable get*ClientRects() fingerprint deception",
|
||
|
+ "Scale the output values of Range::getClientRects() and Element::getBoundingClientRect() with a randomly selected factor in the range -0.0003% to 0.0003%, which are recomputed on every document initialization.",
|
||
|
+ kOsAll, SINGLE_DISABLE_VALUE_TYPE(switches::kFingerprintingClientRectsNoise)},
|
||
|
+ {"fingerprinting-canvas-measuretext-noise",
|
||
|
+ "Disable Canvas::measureText() fingerprint deception",
|
||
|
+ "Scale the output values of Canvas::measureText() with a randomly selected factor in the range -0.0003% to 0.0003%, which are recomputed on every document initialization.",
|
||
|
+ kOsAll, SINGLE_DISABLE_VALUE_TYPE(switches::kFingerprintingCanvasMeasureTextNoise)},
|
||
|
+
|
||
|
#if BUILDFLAG(ENABLE_NACL)
|
||
|
{"enable-nacl", flag_descriptions::kNaclName,
|
||
|
flag_descriptions::kNaclDescription, kOsAll,
|
||
|
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
|
||
|
--- a/content/browser/BUILD.gn
|
||
|
+++ b/content/browser/BUILD.gn
|
||
|
@@ -245,6 +245,7 @@ source_set("browser") {
|
||
|
"//third_party/libyuv",
|
||
|
"//third_party/re2",
|
||
|
"//third_party/sqlite",
|
||
|
+ "//third_party/ungoogled:switches",
|
||
|
"//third_party/webrtc_overrides:webrtc_component",
|
||
|
"//third_party/zlib",
|
||
|
"//third_party/zlib/google:zip",
|
||
|
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
|
||
|
--- a/content/browser/renderer_host/render_process_host_impl.cc
|
||
|
+++ b/content/browser/renderer_host/render_process_host_impl.cc
|
||
|
@@ -211,6 +211,7 @@
|
||
|
#include "url/gurl.h"
|
||
|
#include "url/origin.h"
|
||
|
|
||
|
+#include "third_party/ungoogled/ungoogled_switches.h"
|
||
|
#if BUILDFLAG(IS_ANDROID)
|
||
|
#include "base/android/child_process_binding_types.h"
|
||
|
#include "content/browser/android/java_interfaces_impl.h"
|
||
|
@@ -3299,6 +3300,9 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
|
||
|
switches::kDisableBreakpad,
|
||
|
switches::kDisableDatabases,
|
||
|
switches::kDisableFileSystem,
|
||
|
+ switches::kFingerprintingClientRectsNoise,
|
||
|
+ switches::kFingerprintingCanvasMeasureTextNoise,
|
||
|
+ switches::kFingerprintingCanvasImageDataNoise,
|
||
|
switches::kDisableFrameRateLimit,
|
||
|
switches::kDisableGpuMemoryBufferVideoFrames,
|
||
|
switches::kDisableHistogramCustomizer,
|
||
|
diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn
|
||
|
--- a/content/child/BUILD.gn
|
||
|
+++ b/content/child/BUILD.gn
|
||
|
@@ -102,6 +102,7 @@ target(link_target_type, "child") {
|
||
|
"//third_party/blink/public/common:buildflags",
|
||
|
"//third_party/blink/public/strings",
|
||
|
"//third_party/ced",
|
||
|
+ "//third_party/ungoogled:switches",
|
||
|
"//third_party/zlib/google:compression_utils",
|
||
|
"//ui/base",
|
||
|
"//ui/events/blink",
|
||
|
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
|
||
|
--- a/content/child/runtime_features.cc
|
||
|
+++ b/content/child/runtime_features.cc
|
||
|
@@ -46,6 +46,8 @@
|
||
|
#include "ui/gl/gl_switches.h"
|
||
|
#include "ui/native_theme/native_theme_features.h"
|
||
|
|
||
|
+#include "third_party/ungoogled/ungoogled_switches.h"
|
||
|
+
|
||
|
#if BUILDFLAG(IS_ANDROID)
|
||
|
#include "base/android/build_info.h"
|
||
|
#endif
|
||
|
@@ -548,6 +550,12 @@ void SetRuntimeFeaturesFromCommandLine(const base::CommandLine& command_line) {
|
||
|
// as a last resort.
|
||
|
void SetCustomizedRuntimeFeaturesFromCombinedArgs(
|
||
|
const base::CommandLine& command_line) {
|
||
|
+ WebRuntimeFeatures::EnableFingerprintingClientRectsNoise(
|
||
|
+ !command_line.HasSwitch(switches::kFingerprintingClientRectsNoise));
|
||
|
+ WebRuntimeFeatures::EnableFingerprintingCanvasMeasureTextNoise(
|
||
|
+ !command_line.HasSwitch(switches::kFingerprintingCanvasMeasureTextNoise));
|
||
|
+ WebRuntimeFeatures::EnableFingerprintingCanvasImageDataNoise(
|
||
|
+ !command_line.HasSwitch(switches::kFingerprintingCanvasImageDataNoise));
|
||
|
// CAUTION: Only add custom enabling logic here if it cannot
|
||
|
// be covered by the other functions.
|
||
|
|
||
|
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h
|
||
|
--- a/third_party/blink/public/platform/web_runtime_features.h
|
||
|
+++ b/third_party/blink/public/platform/web_runtime_features.h
|
||
|
@@ -66,6 +66,9 @@ class BLINK_PLATFORM_EXPORT WebRuntimeFeatures : public WebRuntimeFeaturesBase {
|
||
|
static void UpdateStatusFromBaseFeatures();
|
||
|
|
||
|
static void EnableOverlayScrollbars(bool);
|
||
|
+ static void EnableFingerprintingClientRectsNoise(bool);
|
||
|
+ static void EnableFingerprintingCanvasMeasureTextNoise(bool);
|
||
|
+ static void EnableFingerprintingCanvasImageDataNoise(bool);
|
||
|
static void EnableFluentScrollbars(bool);
|
||
|
|
||
|
WebRuntimeFeatures() = delete;
|
||
|
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
|
||
|
--- a/third_party/blink/renderer/core/dom/document.cc
|
||
|
+++ b/third_party/blink/renderer/core/dom/document.cc
|
||
|
@@ -38,6 +38,7 @@
|
||
|
#include "base/debug/dump_without_crashing.h"
|
||
|
#include "base/i18n/time_formatting.h"
|
||
|
#include "base/metrics/histogram_functions.h"
|
||
|
+#include "base/rand_util.h"
|
||
|
#include "base/notreached.h"
|
||
|
#include "base/ranges/algorithm.h"
|
||
|
#include "base/task/single_thread_task_runner.h"
|
||
|
@@ -847,6 +848,17 @@ Document::Document(const DocumentInit& initializer,
|
||
|
: nullptr),
|
||
|
data_(MakeGarbageCollected<DocumentData>(GetExecutionContext())) {
|
||
|
DCHECK(agent_);
|
||
|
+ if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled() ||
|
||
|
+ RuntimeEnabledFeatures::FingerprintingCanvasMeasureTextNoiseEnabled() ||
|
||
|
+ RuntimeEnabledFeatures::FingerprintingCanvasImageDataNoiseEnabled()) {
|
||
|
+ // Precompute -0.0003% to 0.0003% noise factor for get*ClientRect*() fingerprinting
|
||
|
+ noise_factor_x_ = 1.0 + (base::RandDouble() - 0.5) * 0.0003;
|
||
|
+ noise_factor_y_ = 1.0 + (base::RandDouble() - 0.5) * 0.0003;
|
||
|
+ } else {
|
||
|
+ noise_factor_x_ = 1;
|
||
|
+ noise_factor_y_ = 1;
|
||
|
+ }
|
||
|
+
|
||
|
if (base::FeatureList::IsEnabled(features::kDelayAsyncScriptExecution))
|
||
|
script_runner_delayer_->Activate();
|
||
|
|
||
|
@@ -2300,6 +2312,14 @@ void Document::UpdateStyleAndLayoutTreeForThisDocument() {
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
+double Document::GetNoiseFactorX() {
|
||
|
+ return noise_factor_x_;
|
||
|
+}
|
||
|
+
|
||
|
+double Document::GetNoiseFactorY() {
|
||
|
+ return noise_factor_y_;
|
||
|
+}
|
||
|
+
|
||
|
void Document::InvalidateStyleAndLayoutForFontUpdates() {
|
||
|
DCHECK(IsActive());
|
||
|
DCHECK(IsMainThread());
|
||
|
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
|
||
|
--- a/third_party/blink/renderer/core/dom/document.h
|
||
|
+++ b/third_party/blink/renderer/core/dom/document.h
|
||
|
@@ -532,6 +532,10 @@ class CORE_EXPORT Document : public ContainerNode,
|
||
|
has_xml_declaration_ = has_xml_declaration ? 1 : 0;
|
||
|
}
|
||
|
|
||
|
+ // Values for get*ClientRect fingerprint deception
|
||
|
+ double GetNoiseFactorX();
|
||
|
+ double GetNoiseFactorY();
|
||
|
+
|
||
|
AtomicString visibilityState() const;
|
||
|
bool IsPageVisible() const;
|
||
|
bool hidden() const;
|
||
|
@@ -2430,6 +2434,9 @@ class CORE_EXPORT Document : public ContainerNode,
|
||
|
|
||
|
base::ElapsedTimer start_time_;
|
||
|
|
||
|
+ double noise_factor_x_;
|
||
|
+ double noise_factor_y_;
|
||
|
+
|
||
|
Member<ScriptRunner> script_runner_;
|
||
|
Member<ScriptRunnerDelayer> script_runner_delayer_;
|
||
|
|
||
|
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
|
||
|
--- a/third_party/blink/renderer/core/dom/element.cc
|
||
|
+++ b/third_party/blink/renderer/core/dom/element.cc
|
||
|
@@ -2121,6 +2121,7 @@ void Element::ClientQuads(Vector<gfx::QuadF>& quads) const {
|
||
|
quads.push_back(element_layout_object->LocalToAbsoluteQuad(
|
||
|
gfx::QuadF(element_layout_object->ObjectBoundingBox())));
|
||
|
}
|
||
|
+ //TODO: cover this as well
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
@@ -2129,6 +2130,10 @@ void Element::ClientQuads(Vector<gfx::QuadF>& quads) const {
|
||
|
element_layout_object->IsBR()) {
|
||
|
element_layout_object->AbsoluteQuads(quads);
|
||
|
}
|
||
|
+ if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
|
||
|
+ for (auto& quad : quads)
|
||
|
+ quad.Scale(GetDocument().GetNoiseFactorX(), GetDocument().GetNoiseFactorY());
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
DOMRectList* Element::getClientRects() {
|
||
|
@@ -2171,6 +2176,9 @@ gfx::RectF Element::GetBoundingClientRectNoLifecycleUpdate() const {
|
||
|
DCHECK(element_layout_object);
|
||
|
GetDocument().AdjustRectForScrollAndAbsoluteZoom(result,
|
||
|
*element_layout_object);
|
||
|
+ if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
|
||
|
+ result.Scale(GetDocument().GetNoiseFactorX(), GetDocument().GetNoiseFactorY());
|
||
|
+ }
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/renderer/core/dom/range.cc
|
||
|
--- a/third_party/blink/renderer/core/dom/range.cc
|
||
|
+++ b/third_party/blink/renderer/core/dom/range.cc
|
||
|
@@ -1618,6 +1618,12 @@ DOMRectList* Range::getClientRects() const {
|
||
|
Vector<gfx::QuadF> quads;
|
||
|
GetBorderAndTextQuads(quads);
|
||
|
|
||
|
+ if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
|
||
|
+ for (auto& quad : quads) {
|
||
|
+ quad.Scale(owner_document_->GetNoiseFactorX(), owner_document_->GetNoiseFactorY());
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
return MakeGarbageCollected<DOMRectList>(quads);
|
||
|
}
|
||
|
|
||
|
@@ -1753,7 +1759,11 @@ gfx::RectF Range::BoundingRect() const {
|
||
|
|
||
|
// If all rects are empty, return the first rect.
|
||
|
if (result.IsEmpty() && !quads.empty())
|
||
|
- return quads.front().BoundingBox();
|
||
|
+ result = quads.front().BoundingBox();
|
||
|
+
|
||
|
+ if (!result.IsEmpty() && RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
|
||
|
+ result.Scale(owner_document_->GetNoiseFactorX(), owner_document_->GetNoiseFactorY());
|
||
|
+ }
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc b/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc
|
||
|
--- a/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc
|
||
|
+++ b/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc
|
||
|
@@ -20,6 +20,7 @@
|
||
|
#include "third_party/blink/renderer/core/fileapi/blob.h"
|
||
|
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
|
||
|
#include "third_party/blink/renderer/platform/graphics/image_data_buffer.h"
|
||
|
+#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
|
||
|
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
|
||
|
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
|
||
|
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
|
||
|
@@ -208,6 +209,10 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(
|
||
|
std::min(info.height(), max_dimension));
|
||
|
src_data_.reset(info, src_data_.addr(), src_data_.rowBytes());
|
||
|
}
|
||
|
+ if (RuntimeEnabledFeatures::FingerprintingCanvasImageDataNoiseEnabled()) {
|
||
|
+ StaticBitmapImage::ShuffleSubchannelColorData(src_data_.writable_addr(),
|
||
|
+ src_data_.info(), 0, 0);
|
||
|
+ }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
diff --git a/third_party/blink/renderer/core/html/canvas/text_metrics.cc b/third_party/blink/renderer/core/html/canvas/text_metrics.cc
|
||
|
--- a/third_party/blink/renderer/core/html/canvas/text_metrics.cc
|
||
|
+++ b/third_party/blink/renderer/core/html/canvas/text_metrics.cc
|
||
|
@@ -68,6 +68,24 @@ TextMetrics::TextMetrics(const Font& font,
|
||
|
Update(font, direction, baseline, align, text);
|
||
|
}
|
||
|
|
||
|
+void TextMetrics::Shuffle(const double factor) {
|
||
|
+ // x-direction
|
||
|
+ width_ *= factor;
|
||
|
+ actual_bounding_box_left_ *= factor;
|
||
|
+ actual_bounding_box_right_ *= factor;
|
||
|
+
|
||
|
+ // y-direction
|
||
|
+ font_bounding_box_ascent_ *= factor;
|
||
|
+ font_bounding_box_descent_ *= factor;
|
||
|
+ actual_bounding_box_ascent_ *= factor;
|
||
|
+ actual_bounding_box_descent_ *= factor;
|
||
|
+ em_height_ascent_ *= factor;
|
||
|
+ em_height_descent_ *= factor;
|
||
|
+ baselines_->setAlphabetic(baselines_->alphabetic() * factor);
|
||
|
+ baselines_->setHanging(baselines_->hanging() * factor);
|
||
|
+ baselines_->setIdeographic(baselines_->ideographic() * factor);
|
||
|
+}
|
||
|
+
|
||
|
void TextMetrics::Update(const Font& font,
|
||
|
const TextDirection& direction,
|
||
|
const TextBaseline& baseline,
|
||
|
diff --git a/third_party/blink/renderer/core/html/canvas/text_metrics.h b/third_party/blink/renderer/core/html/canvas/text_metrics.h
|
||
|
--- a/third_party/blink/renderer/core/html/canvas/text_metrics.h
|
||
|
+++ b/third_party/blink/renderer/core/html/canvas/text_metrics.h
|
||
|
@@ -66,6 +66,8 @@ class CORE_EXPORT TextMetrics final : public ScriptWrappable {
|
||
|
|
||
|
void Trace(Visitor*) const override;
|
||
|
|
||
|
+ void Shuffle(const double factor);
|
||
|
+
|
||
|
private:
|
||
|
void Update(const Font&,
|
||
|
const TextDirection&,
|
||
|
diff --git a/third_party/blink/renderer/core/svg/svg_graphics_element.cc b/third_party/blink/renderer/core/svg/svg_graphics_element.cc
|
||
|
--- a/third_party/blink/renderer/core/svg/svg_graphics_element.cc
|
||
|
+++ b/third_party/blink/renderer/core/svg/svg_graphics_element.cc
|
||
|
@@ -143,6 +143,8 @@ SVGRectTearOff* SVGGraphicsElement::getBBoxFromJavascript() {
|
||
|
if (const auto* layout_object = GetLayoutObject()) {
|
||
|
bounding_box = GetBBox();
|
||
|
|
||
|
+ if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled())
|
||
|
+ bounding_box.Scale(GetDocument().GetNoiseFactorX(), GetDocument().GetNoiseFactorY());
|
||
|
if (layout_object->IsSVGInline()) {
|
||
|
UseCounter::Count(GetDocument(), WebFeature::kGetBBoxForText);
|
||
|
}
|
||
|
diff --git a/third_party/blink/renderer/core/svg/svg_text_content_element.cc b/third_party/blink/renderer/core/svg/svg_text_content_element.cc
|
||
|
--- a/third_party/blink/renderer/core/svg/svg_text_content_element.cc
|
||
|
+++ b/third_party/blink/renderer/core/svg/svg_text_content_element.cc
|
||
|
@@ -111,11 +111,16 @@ float SVGTextContentElement::getComputedTextLength() {
|
||
|
GetDocument().UpdateStyleAndLayoutForNode(this,
|
||
|
DocumentUpdateReason::kJavaScript);
|
||
|
auto* layout_object = GetLayoutObject();
|
||
|
+ float value = 0;
|
||
|
if (IsNGTextOrInline(layout_object)) {
|
||
|
SvgTextQuery query(*layout_object);
|
||
|
- return query.SubStringLength(0, query.NumberOfCharacters());
|
||
|
+ value = query.SubStringLength(0, query.NumberOfCharacters());
|
||
|
+ } else {
|
||
|
+ value = 0;
|
||
|
}
|
||
|
- return 0;
|
||
|
+ return value *
|
||
|
+ (RuntimeEnabledFeatures::FingerprintingCanvasMeasureTextNoiseEnabled() ?
|
||
|
+ GetDocument().GetNoiseFactorX() : 1);
|
||
|
}
|
||
|
|
||
|
float SVGTextContentElement::getSubStringLength(
|
||
|
@@ -138,9 +143,13 @@ float SVGTextContentElement::getSubStringLength(
|
||
|
nchars = number_of_chars - charnum;
|
||
|
|
||
|
auto* layout_object = GetLayoutObject();
|
||
|
+ float value = 0;
|
||
|
if (IsNGTextOrInline(layout_object))
|
||
|
- return SvgTextQuery(*layout_object).SubStringLength(charnum, nchars);
|
||
|
- return 0;
|
||
|
+ value = SvgTextQuery(*layout_object).SubStringLength(charnum, nchars);
|
||
|
+ else
|
||
|
+ value = 0;
|
||
|
+ return value * (RuntimeEnabledFeatures::FingerprintingCanvasMeasureTextNoiseEnabled() ?
|
||
|
+ GetDocument().GetNoiseFactorX() : 1);
|
||
|
}
|
||
|
|
||
|
SVGPointTearOff* SVGTextContentElement::getStartPositionOfChar(
|
||
|
@@ -162,6 +171,8 @@ SVGPointTearOff* SVGTextContentElement::getStartPositionOfChar(
|
||
|
if (IsNGTextOrInline(layout_object)) {
|
||
|
point = SvgTextQuery(*layout_object).StartPositionOfCharacter(charnum);
|
||
|
}
|
||
|
+ if (RuntimeEnabledFeatures::FingerprintingCanvasMeasureTextNoiseEnabled())
|
||
|
+ point.Scale(GetDocument().GetNoiseFactorX(), GetDocument().GetNoiseFactorY());
|
||
|
return SVGPointTearOff::CreateDetached(point);
|
||
|
}
|
||
|
|
||
|
@@ -184,6 +195,8 @@ SVGPointTearOff* SVGTextContentElement::getEndPositionOfChar(
|
||
|
if (IsNGTextOrInline(layout_object)) {
|
||
|
point = SvgTextQuery(*layout_object).EndPositionOfCharacter(charnum);
|
||
|
}
|
||
|
+ if (RuntimeEnabledFeatures::FingerprintingCanvasMeasureTextNoiseEnabled())
|
||
|
+ point.Scale(GetDocument().GetNoiseFactorX(), GetDocument().GetNoiseFactorY());
|
||
|
return SVGPointTearOff::CreateDetached(point);
|
||
|
}
|
||
|
|
||
|
@@ -206,6 +219,8 @@ SVGRectTearOff* SVGTextContentElement::getExtentOfChar(
|
||
|
if (IsNGTextOrInline(layout_object)) {
|
||
|
rect = SvgTextQuery(*layout_object).ExtentOfCharacter(charnum);
|
||
|
}
|
||
|
+ if (RuntimeEnabledFeatures::FingerprintingCanvasMeasureTextNoiseEnabled())
|
||
|
+ rect.Scale(GetDocument().GetNoiseFactorX(), GetDocument().GetNoiseFactorY());
|
||
|
return SVGRectTearOff::CreateDetached(rect);
|
||
|
}
|
||
|
|
||
|
@@ -235,9 +250,12 @@ int SVGTextContentElement::getCharNumAtPosition(
|
||
|
GetDocument().UpdateStyleAndLayoutForNode(this,
|
||
|
DocumentUpdateReason::kJavaScript);
|
||
|
auto* layout_object = GetLayoutObject();
|
||
|
+ gfx::PointF target = gfx::PointF(point->Target()->Value());
|
||
|
+ if (RuntimeEnabledFeatures::FingerprintingCanvasMeasureTextNoiseEnabled())
|
||
|
+ target.Scale(GetDocument().GetNoiseFactorX(), GetDocument().GetNoiseFactorY());
|
||
|
if (IsNGTextOrInline(layout_object)) {
|
||
|
return SvgTextQuery(*layout_object)
|
||
|
- .CharacterNumberAtPosition(point->Target()->Value());
|
||
|
+ .CharacterNumberAtPosition(target);
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
|
||
|
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
|
||
|
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
|
||
|
@@ -44,6 +44,7 @@
|
||
|
#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
|
||
|
#include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h"
|
||
|
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
|
||
|
+#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
|
||
|
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
|
||
|
#include "third_party/blink/renderer/platform/graphics/stroke_data.h"
|
||
|
#include "third_party/blink/renderer/platform/graphics/video_frame_image_util.h"
|
||
|
@@ -53,6 +54,9 @@
|
||
|
#include "ui/gfx/geometry/quad_f.h"
|
||
|
#include "ui/gfx/geometry/skia_conversions.h"
|
||
|
|
||
|
+#include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
|
||
|
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
|
||
|
+
|
||
|
namespace blink {
|
||
|
|
||
|
BASE_FEATURE(kDisableCanvasOverdrawOptimization,
|
||
|
@@ -2187,6 +2191,10 @@ ImageData* BaseRenderingContext2D::getImageDataInternal(
|
||
|
snapshot->PaintImageForCurrentFrame().GetSkImageInfo().bounds();
|
||
|
DCHECK(!bounds.intersect(SkIRect::MakeXYWH(sx, sy, sw, sh)));
|
||
|
}
|
||
|
+
|
||
|
+ if (read_pixels_successful && RuntimeEnabledFeatures::FingerprintingCanvasImageDataNoiseEnabled()) {
|
||
|
+ StaticBitmapImage::ShuffleSubchannelColorData(image_data_pixmap.addr(), image_data_pixmap.info(), sx, sy);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
return image_data;
|
||
|
@@ -2864,9 +2872,23 @@ TextMetrics* BaseRenderingContext2D::measureText(const String& text) {
|
||
|
|
||
|
TextDirection direction = ToTextDirection(GetState().GetDirection(), canvas);
|
||
|
|
||
|
- return MakeGarbageCollected<TextMetrics>(font, direction,
|
||
|
+ auto* text_metrics = MakeGarbageCollected<TextMetrics>(font, direction,
|
||
|
GetState().GetTextBaseline(),
|
||
|
GetState().GetTextAlign(), text);
|
||
|
+ // Scale text metrics if enabled
|
||
|
+ if (RuntimeEnabledFeatures::FingerprintingCanvasMeasureTextNoiseEnabled()) {
|
||
|
+ OffscreenCanvas* offscreen_canvas = HostAsOffscreenCanvas();
|
||
|
+ if (offscreen_canvas) {
|
||
|
+ ExecutionContext* execution_context = GetTopExecutionContext();
|
||
|
+ if (auto* window = DynamicTo<LocalDOMWindow>(execution_context)) {
|
||
|
+ Document* document = window->GetFrame()->GetDocument();
|
||
|
+ text_metrics->Shuffle(document->GetNoiseFactorX());
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else
|
||
|
+ text_metrics->Shuffle(canvas->GetDocument().GetNoiseFactorX());
|
||
|
+ }
|
||
|
+ return text_metrics;
|
||
|
}
|
||
|
|
||
|
void BaseRenderingContext2D::SnapshotStateForFilter() {
|
||
|
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
|
||
|
--- a/third_party/blink/renderer/platform/BUILD.gn
|
||
|
+++ b/third_party/blink/renderer/platform/BUILD.gn
|
||
|
@@ -1648,7 +1648,9 @@ component("platform") {
|
||
|
"//third_party/blink/renderer:non_test_config",
|
||
|
]
|
||
|
|
||
|
- include_dirs = []
|
||
|
+ include_dirs = [
|
||
|
+ "//third_party/skia/include/private", # For shuffler in graphics/static_bitmap_image.cc
|
||
|
+ ]
|
||
|
|
||
|
allow_circular_includes_from = [
|
||
|
"//third_party/blink/renderer/platform/blob",
|
||
|
@@ -1722,6 +1724,7 @@ component("platform") {
|
||
|
"//third_party/blink/public/strings",
|
||
|
"//third_party/blink/renderer/platform/wtf",
|
||
|
"//third_party/ced",
|
||
|
+ "//third_party/ungoogled:switches",
|
||
|
"//third_party/emoji-segmenter",
|
||
|
"//third_party/icu",
|
||
|
"//third_party/libyuv",
|
||
|
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
|
||
|
--- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc
|
||
|
+++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
|
||
|
@@ -65,4 +65,16 @@ void WebRuntimeFeatures::EnableFluentScrollbars(bool enable) {
|
||
|
ScrollbarThemeSettings::SetFluentScrollbarsEnabled(enable);
|
||
|
}
|
||
|
|
||
|
+void WebRuntimeFeatures::EnableFingerprintingClientRectsNoise(bool enable) {
|
||
|
+ RuntimeEnabledFeatures::SetFingerprintingClientRectsNoiseEnabled(enable);
|
||
|
+}
|
||
|
+
|
||
|
+void WebRuntimeFeatures::EnableFingerprintingCanvasMeasureTextNoise(bool enable) {
|
||
|
+ RuntimeEnabledFeatures::SetFingerprintingCanvasMeasureTextNoiseEnabled(enable);
|
||
|
+}
|
||
|
+
|
||
|
+void WebRuntimeFeatures::EnableFingerprintingCanvasImageDataNoise(bool enable) {
|
||
|
+ RuntimeEnabledFeatures::SetFingerprintingCanvasImageDataNoiseEnabled(enable);
|
||
|
+}
|
||
|
+
|
||
|
} // namespace blink
|
||
|
diff --git a/third_party/blink/renderer/platform/graphics/image_data_buffer.cc b/third_party/blink/renderer/platform/graphics/image_data_buffer.cc
|
||
|
--- a/third_party/blink/renderer/platform/graphics/image_data_buffer.cc
|
||
|
+++ b/third_party/blink/renderer/platform/graphics/image_data_buffer.cc
|
||
|
@@ -36,6 +36,8 @@
|
||
|
|
||
|
#include "base/compiler_specific.h"
|
||
|
#include "base/memory/ptr_util.h"
|
||
|
+#include "base/rand_util.h"
|
||
|
+#include "base/logging.h"
|
||
|
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
|
||
|
#include "third_party/blink/renderer/platform/image-encoders/image_encoder.h"
|
||
|
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
|
||
|
@@ -146,6 +148,11 @@ bool ImageDataBuffer::EncodeImageInternal(const ImageEncodingMimeType mime_type,
|
||
|
const SkPixmap& pixmap) const {
|
||
|
DCHECK(is_valid_);
|
||
|
|
||
|
+ if (RuntimeEnabledFeatures::FingerprintingCanvasImageDataNoiseEnabled()) {
|
||
|
+ // shuffle subchannel color data within the pixmap
|
||
|
+ StaticBitmapImage::ShuffleSubchannelColorData(pixmap_.writable_addr(), pixmap_.info(), 0, 0);
|
||
|
+ }
|
||
|
+
|
||
|
if (mime_type == kMimeTypeJpeg) {
|
||
|
SkJpegEncoder::Options options;
|
||
|
options.fQuality = ImageEncoder::ComputeJpegQuality(quality);
|
||
|
diff --git a/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
|
||
|
--- a/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
|
||
|
+++ b/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
|
||
|
@@ -4,6 +4,8 @@
|
||
|
|
||
|
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
|
||
|
|
||
|
+#include "base/logging.h"
|
||
|
+#include "base/rand_util.h"
|
||
|
#include "base/numerics/checked_math.h"
|
||
|
#include "gpu/command_buffer/client/gles2_interface.h"
|
||
|
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
|
||
|
@@ -18,6 +20,9 @@
|
||
|
#include "ui/gfx/geometry/skia_conversions.h"
|
||
|
#include "v8/include/v8.h"
|
||
|
|
||
|
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
|
||
|
+#include "third_party/skia/include/private/SkColorData.h"
|
||
|
+
|
||
|
namespace blink {
|
||
|
|
||
|
scoped_refptr<StaticBitmapImage> StaticBitmapImage::Create(
|
||
|
@@ -115,4 +120,154 @@ void StaticBitmapImage::DrawHelper(cc::PaintCanvas* canvas,
|
||
|
WebCoreClampingModeToSkiaRectConstraint(draw_options.clamping_mode));
|
||
|
}
|
||
|
|
||
|
+// set the component to maximum-delta if it is >= maximum, or add to existing color component (color + delta)
|
||
|
+#define shuffleComponent(color, max, delta) ( (color) >= (max) ? ((max)-(delta)) : ((color)+(delta)) )
|
||
|
+
|
||
|
+#define writable_addr(T, p, stride, x, y) (T*)((const char *)p + y * stride + x * sizeof(T))
|
||
|
+
|
||
|
+void StaticBitmapImage::ShuffleSubchannelColorData(const void *addr, const SkImageInfo& info, int srcX, int srcY) {
|
||
|
+ auto w = info.width() - srcX, h = info.height() - srcY;
|
||
|
+
|
||
|
+ // skip tiny images; info.width()/height() can also be 0
|
||
|
+ if ((w < 8) || (h < 8)) {
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ // generate the first random number here
|
||
|
+ double shuffleX = base::RandDouble();
|
||
|
+
|
||
|
+ // cap maximum pixels to change
|
||
|
+ auto pixels = (w + h) / 8;
|
||
|
+ if (pixels > 100) {
|
||
|
+ pixels = 100;
|
||
|
+ } else if (pixels < 2) {
|
||
|
+ pixels = 2;
|
||
|
+ }
|
||
|
+
|
||
|
+ auto colorType = info.colorType();
|
||
|
+ auto fRowBytes = info.minRowBytes(); // stride
|
||
|
+
|
||
|
+ DLOG(INFO) << "BRM: ShuffleSubchannelColorData() w=" << w << " h=" << h << " colorType=" << colorType << " fRowBytes=" << fRowBytes;
|
||
|
+
|
||
|
+ // second random number (for y/height)
|
||
|
+ double shuffleY = base::RandDouble();
|
||
|
+
|
||
|
+ // calculate random coordinates using bisection
|
||
|
+ auto currentW = w, currentH = h;
|
||
|
+ for(;pixels >= 0; pixels--) {
|
||
|
+ int x = currentW * shuffleX, y = currentH * shuffleY;
|
||
|
+
|
||
|
+ // calculate randomisation amounts for each RGB component
|
||
|
+ uint8_t shuffleR = base::RandInt(0, 4);
|
||
|
+ uint8_t shuffleG = (shuffleR + x) % 4;
|
||
|
+ uint8_t shuffleB = (shuffleG + y) % 4;
|
||
|
+
|
||
|
+ // manipulate pixel data to slightly change the R, G, B components
|
||
|
+ switch (colorType) {
|
||
|
+ case kAlpha_8_SkColorType:
|
||
|
+ {
|
||
|
+ auto *pixel = writable_addr(uint8_t, addr, fRowBytes, x, y);
|
||
|
+ auto r = SkColorGetR(*pixel), g = SkColorGetG(*pixel), b = SkColorGetB(*pixel), a = SkColorGetA(*pixel);
|
||
|
+
|
||
|
+ r = shuffleComponent(r, UINT8_MAX-1, shuffleR);
|
||
|
+ g = shuffleComponent(g, UINT8_MAX-1, shuffleG);
|
||
|
+ b = shuffleComponent(b, UINT8_MAX-1, shuffleB);
|
||
|
+ // alpha is left unchanged
|
||
|
+
|
||
|
+ *pixel = SkColorSetARGB(a, r, g, b);
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case kGray_8_SkColorType:
|
||
|
+ {
|
||
|
+ auto *pixel = writable_addr(uint8_t, addr, fRowBytes, x, y);
|
||
|
+ *pixel = shuffleComponent(*pixel, UINT8_MAX-1, shuffleB);
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case kRGB_565_SkColorType:
|
||
|
+ {
|
||
|
+ auto *pixel = writable_addr(uint16_t, addr, fRowBytes, x, y);
|
||
|
+ unsigned r = SkPacked16ToR32(*pixel);
|
||
|
+ unsigned g = SkPacked16ToG32(*pixel);
|
||
|
+ unsigned b = SkPacked16ToB32(*pixel);
|
||
|
+
|
||
|
+ r = shuffleComponent(r, 31, shuffleR);
|
||
|
+ g = shuffleComponent(g, 63, shuffleG);
|
||
|
+ b = shuffleComponent(b, 31, shuffleB);
|
||
|
+
|
||
|
+ unsigned r16 = (r & SK_R16_MASK) << SK_R16_SHIFT;
|
||
|
+ unsigned g16 = (g & SK_G16_MASK) << SK_G16_SHIFT;
|
||
|
+ unsigned b16 = (b & SK_B16_MASK) << SK_B16_SHIFT;
|
||
|
+
|
||
|
+ *pixel = r16 | g16 | b16;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case kARGB_4444_SkColorType:
|
||
|
+ {
|
||
|
+ auto *pixel = writable_addr(uint16_t, addr, fRowBytes, x, y);
|
||
|
+ auto a = SkGetPackedA4444(*pixel), r = SkGetPackedR4444(*pixel), g = SkGetPackedG4444(*pixel), b = SkGetPackedB4444(*pixel);
|
||
|
+
|
||
|
+ r = shuffleComponent(r, 15, shuffleR);
|
||
|
+ g = shuffleComponent(g, 15, shuffleG);
|
||
|
+ b = shuffleComponent(b, 15, shuffleB);
|
||
|
+ // alpha is left unchanged
|
||
|
+
|
||
|
+ unsigned a4 = (a & 0xF) << SK_A4444_SHIFT;
|
||
|
+ unsigned r4 = (r & 0xF) << SK_R4444_SHIFT;
|
||
|
+ unsigned g4 = (g & 0xF) << SK_G4444_SHIFT;
|
||
|
+ unsigned b4 = (b & 0xF) << SK_B4444_SHIFT;
|
||
|
+
|
||
|
+ *pixel = r4 | b4 | g4 | a4;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case kRGBA_8888_SkColorType:
|
||
|
+ {
|
||
|
+ auto *pixel = writable_addr(uint32_t, addr, fRowBytes, x, y);
|
||
|
+ auto a = SkGetPackedA32(*pixel), r = SkGetPackedR32(*pixel), g = SkGetPackedG32(*pixel), b = SkGetPackedB32(*pixel);
|
||
|
+
|
||
|
+ r = shuffleComponent(r, UINT8_MAX-1, shuffleR);
|
||
|
+ g = shuffleComponent(g, UINT8_MAX-1, shuffleG);
|
||
|
+ b = shuffleComponent(b, UINT8_MAX-1, shuffleB);
|
||
|
+ // alpha is left unchanged
|
||
|
+
|
||
|
+ *pixel = (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
|
||
|
+ (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case kBGRA_8888_SkColorType:
|
||
|
+ {
|
||
|
+ auto *pixel = writable_addr(uint32_t, addr, fRowBytes, x, y);
|
||
|
+ auto a = SkGetPackedA32(*pixel), b = SkGetPackedR32(*pixel), g = SkGetPackedG32(*pixel), r = SkGetPackedB32(*pixel);
|
||
|
+
|
||
|
+ r = shuffleComponent(r, UINT8_MAX-1, shuffleR);
|
||
|
+ g = shuffleComponent(g, UINT8_MAX-1, shuffleG);
|
||
|
+ b = shuffleComponent(b, UINT8_MAX-1, shuffleB);
|
||
|
+ // alpha is left unchanged
|
||
|
+
|
||
|
+ *pixel = (a << SK_BGRA_A32_SHIFT) | (r << SK_BGRA_R32_SHIFT) |
|
||
|
+ (g << SK_BGRA_G32_SHIFT) | (b << SK_BGRA_B32_SHIFT);
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ // the remaining formats are not expected to be used in Chromium
|
||
|
+ LOG(WARNING) << "BRM: ShuffleSubchannelColorData(): Ignoring pixel format";
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ // keep bisecting or reset current width/height as needed
|
||
|
+ if (x == 0) {
|
||
|
+ currentW = w;
|
||
|
+ } else {
|
||
|
+ currentW = x;
|
||
|
+ }
|
||
|
+ if (y == 0) {
|
||
|
+ currentH = h;
|
||
|
+ } else {
|
||
|
+ currentH = y;
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+#undef writable_addr
|
||
|
+#undef shuffleComponent
|
||
|
+
|
||
|
} // namespace blink
|
||
|
diff --git a/third_party/blink/renderer/platform/graphics/static_bitmap_image.h b/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
|
||
|
--- a/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
|
||
|
+++ b/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
|
||
|
@@ -37,6 +37,8 @@ class PLATFORM_EXPORT StaticBitmapImage : public Image {
|
||
|
|
||
|
StaticBitmapImage(ImageOrientation orientation) : orientation_(orientation) {}
|
||
|
|
||
|
+ static void ShuffleSubchannelColorData(const void *addr, const SkImageInfo& info, int srcX, int srcY);
|
||
|
+
|
||
|
bool IsStaticBitmapImage() const override { return true; }
|
||
|
|
||
|
// Methods overridden by all sub-classes
|
||
|
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||
|
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||
|
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||
|
@@ -3122,6 +3122,15 @@
|
||
|
status: {"Android": "", "default": "stable"},
|
||
|
base_feature: "none",
|
||
|
},
|
||
|
+ {
|
||
|
+ name: "FingerprintingClientRectsNoise",
|
||
|
+ },
|
||
|
+ {
|
||
|
+ name: "FingerprintingCanvasMeasureTextNoise",
|
||
|
+ },
|
||
|
+ {
|
||
|
+ name: "FingerprintingCanvasImageDataNoise",
|
||
|
+ },
|
||
|
{
|
||
|
name: "RemotePlayback",
|
||
|
public: true,
|
||
|
diff --git a/third_party/ungoogled/BUILD.gn b/third_party/ungoogled/BUILD.gn
|
||
|
new file mode 100644
|
||
|
--- /dev/null
|
||
|
+++ b/third_party/ungoogled/BUILD.gn
|
||
|
@@ -0,0 +1,10 @@
|
||
|
+# Copyright (c) 2018 The ungoogled-chromium Authors. All rights reserved.
|
||
|
+# Use of this source code is governed by a BSD-style license that can be
|
||
|
+# found in the LICENSE file.
|
||
|
+
|
||
|
+component("switches") {
|
||
|
+ sources = [
|
||
|
+ "ungoogled_switches.h",
|
||
|
+ "ungoogled_switches.cc",
|
||
|
+ ]
|
||
|
+}
|
||
|
diff --git a/third_party/ungoogled/ungoogled_switches.cc b/third_party/ungoogled/ungoogled_switches.cc
|
||
|
new file mode 100644
|
||
|
--- /dev/null
|
||
|
+++ b/third_party/ungoogled/ungoogled_switches.cc
|
||
|
@@ -0,0 +1,18 @@
|
||
|
+// Copyright (c) 2018 The ungoogled-chromium Authors. All rights reserved.
|
||
|
+// Use of this source code is governed by a BSD-style license that can be
|
||
|
+// found in the LICENSE file.
|
||
|
+
|
||
|
+#include "third_party/ungoogled/ungoogled_switches.h"
|
||
|
+
|
||
|
+namespace switches {
|
||
|
+
|
||
|
+// Enable fingerprinting deception for getClientRects and getBoundingClientRect
|
||
|
+const char kFingerprintingClientRectsNoise[] = "fingerprinting-client-rects-noise";
|
||
|
+
|
||
|
+// Enable fingerprinting deception for measureText
|
||
|
+const char kFingerprintingCanvasMeasureTextNoise[] = "fingerprinting-canvas-measuretext-noise";
|
||
|
+
|
||
|
+// Enable fingerprinting deception for Canvas image data
|
||
|
+const char kFingerprintingCanvasImageDataNoise[] = "fingerprinting-canvas-image-data-noise";
|
||
|
+
|
||
|
+} // namespace switches
|
||
|
diff --git a/third_party/ungoogled/ungoogled_switches.h b/third_party/ungoogled/ungoogled_switches.h
|
||
|
new file mode 100644
|
||
|
--- /dev/null
|
||
|
+++ b/third_party/ungoogled/ungoogled_switches.h
|
||
|
@@ -0,0 +1,18 @@
|
||
|
+// Copyright (c) 2018 The ungoogled-chromium Authors. All rights reserved.
|
||
|
+// Use of this source code is governed by a BSD-style license that can be
|
||
|
+// found in the LICENSE file.
|
||
|
+
|
||
|
+// Defines all the fingerprinting command-line switches.
|
||
|
+
|
||
|
+#ifndef THIRD_PARTY_UNGOOGLED_FINGERPRINTING_SWITCHES_H_
|
||
|
+#define THIRD_PARTY_UNGOOGLED_FINGERPRINTING_SWITCHES_H_
|
||
|
+
|
||
|
+namespace switches {
|
||
|
+
|
||
|
+extern const char kFingerprintingClientRectsNoise[];
|
||
|
+extern const char kFingerprintingCanvasMeasureTextNoise[];
|
||
|
+extern const char kFingerprintingCanvasImageDataNoise[];
|
||
|
+
|
||
|
+}
|
||
|
+
|
||
|
+#endif // THIRD_PARTY_UNGOOGLED_FINGERPRINTING_SWITCHES_H_
|
||
|
--
|
||
|
2.25.1
|