This is an automated email from the git hooks/post-receive script.
richard pushed a commit to branch tor-browser-102.2.0esr-12.0-2 in repository tor-browser.
commit 80d4757bf4395a12db494f64f0d7bf2952b357cc Author: Igor Oliveira igor.oliveira@posteo.net AuthorDate: Sun Dec 10 18:16:59 2017 -0200
Bug 23104: Add a default line height compensation
Many fonts have issues with their vertical metrics. they are used to influence the height of ascenders and depth of descenders. Gecko uses it to calculate the line height (font height + ascender + descender), however because of that idiosyncratic behavior across multiple operating systems, it can be used to identify the user's OS.
The solution proposed in the patch uses a default factor to be multiplied with the font size, simulating the concept of ascender and descender. This way all operating systems will have the same line height only and only if the frame is outside the chrome. --- layout/generic/ReflowInput.cpp | 19 +++++++++--- layout/generic/test/mochitest.ini | 1 + layout/generic/test/test_tor_bug23104.html | 50 ++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 5 deletions(-)
diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp index 7bc03d10bd2ab..befa9c8b1deff 100644 --- a/layout/generic/ReflowInput.cpp +++ b/layout/generic/ReflowInput.cpp @@ -34,6 +34,7 @@ #include "nsTableCellFrame.h" #include "nsTableFrame.h" #include "StickyScrollContainer.h" +#include "nsContentUtils.h"
using namespace mozilla; using namespace mozilla::css; @@ -2715,7 +2716,8 @@ void ReflowInput::CalculateBlockSideMargins() {
// For risk management, we use preference to control the behavior, and // eNoExternalLeading is the old behavior. -static nscoord GetNormalLineHeight(nsFontMetrics* aFontMetrics) { +static nscoord GetNormalLineHeight(nsIContent* aContent, + nsFontMetrics* aFontMetrics) { MOZ_ASSERT(nullptr != aFontMetrics, "no font metrics");
nscoord normalLineHeight; @@ -2723,6 +2725,12 @@ static nscoord GetNormalLineHeight(nsFontMetrics* aFontMetrics) { nscoord externalLeading = aFontMetrics->ExternalLeading(); nscoord internalLeading = aFontMetrics->InternalLeading(); nscoord emHeight = aFontMetrics->EmHeight(); + + if (nsContentUtils::ShouldResistFingerprinting() && + !aContent->IsInChromeDocument()) { + return NSToCoordRound(emHeight * NORMAL_LINE_HEIGHT_FACTOR); + } + switch (GetNormalLineHeightCalcControl()) { case eIncludeExternalLeading: normalLineHeight = emHeight + internalLeading + externalLeading; @@ -2740,7 +2748,8 @@ static nscoord GetNormalLineHeight(nsFontMetrics* aFontMetrics) { return normalLineHeight; }
-static inline nscoord ComputeLineHeight(const ComputedStyle* aComputedStyle, +static inline nscoord ComputeLineHeight(nsIContent* aContent, + const ComputedStyle* aComputedStyle, nsPresContext* aPresContext, nscoord aBlockBSize, float aFontSizeInflation) { @@ -2769,7 +2778,7 @@ static inline nscoord ComputeLineHeight(const ComputedStyle* aComputedStyle,
RefPtr<nsFontMetrics> fm = nsLayoutUtils::GetFontMetricsForComputedStyle( aComputedStyle, aPresContext, aFontSizeInflation); - return GetNormalLineHeight(fm); + return GetNormalLineHeight(aContent, fm); }
nscoord ReflowInput::GetLineHeight() const { @@ -2806,7 +2815,7 @@ nscoord ReflowInput::CalcLineHeight(nsIContent* aContent, float aFontSizeInflation) { MOZ_ASSERT(aComputedStyle, "Must have a ComputedStyle");
- nscoord lineHeight = ComputeLineHeight(aComputedStyle, aPresContext, + nscoord lineHeight = ComputeLineHeight(aContent, aComputedStyle, aPresContext, aBlockBSize, aFontSizeInflation);
NS_ASSERTION(lineHeight >= 0, "ComputeLineHeight screwed up"); @@ -2819,7 +2828,7 @@ nscoord ReflowInput::CalcLineHeight(nsIContent* aContent, if (!lh.IsNormal()) { RefPtr<nsFontMetrics> fm = nsLayoutUtils::GetFontMetricsForComputedStyle( aComputedStyle, aPresContext, aFontSizeInflation); - nscoord normal = GetNormalLineHeight(fm); + nscoord normal = GetNormalLineHeight(aContent, fm); if (lineHeight < normal) { lineHeight = normal; } diff --git a/layout/generic/test/mochitest.ini b/layout/generic/test/mochitest.ini index 448f8bab86ef5..54926eb0c155f 100644 --- a/layout/generic/test/mochitest.ini +++ b/layout/generic/test/mochitest.ini @@ -150,3 +150,4 @@ support-files = file_reframe_for_lazy_load_image.html [test_bug1655135.html] [test_bug1756831.html] +[test_tor_bug23104.html] diff --git a/layout/generic/test/test_tor_bug23104.html b/layout/generic/test/test_tor_bug23104.html new file mode 100644 index 0000000000000..8ff1d2190c45f --- /dev/null +++ b/layout/generic/test/test_tor_bug23104.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<meta charset="UTF-8"> +<html> +<head> + <title>Test for Tor Bug #23104: CSS line-height reveals the platform Tor browser is running</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> + <style type="text/css"> + span { + background-color: #000; + color: #fff; + font-size: 16.5px; + } + </style> +</head> +<body> +<span id="test1">Test1</span> +<span id="test2">كلمة</span> +<span id="test3">ação</span> +<script> + +let setPref = async function (key, value) { + await SpecialPowers.pushPrefEnv({"set": [[key, value]]}); +} + +function getStyle(el, styleprop) { + el = document.getElementById(el); + return document.defaultView.getComputedStyle(el, null).getPropertyValue(styleprop); +} + +function validateElement(elementName, isFingerprintResistent) { + var fontSize = getStyle(elementName, 'font-size'); + var lineHeight = getStyle(elementName, 'line-height'); + var validationCb = isFingerprintResistent ? is : isnot; + validationCb(parseFloat(lineHeight), Math.round(parseFloat(fontSize)) * 1.2, 'Line Height validation'); +} + +add_task(async function() { + await setPref("layout.css.line-height.normal-as-resolved-value.enabled", false); + for (let resistFingerprintingValue of [true, false]) { + await setPref("privacy.resistFingerprinting", resistFingerprintingValue); + for (let elementId of ['test1', 'test2', 'test3']) { + validateElement(elementId, resistFingerprintingValue); + } + } +}); + +</script> +</body> +</html>