Pier Angelo Vendrame pushed to branch mullvad-browser-140.10.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
-
9a7a95dc
by Jonathan Kew at 2026-04-16T09:17:32+02:00
-
f3289251
by Pier Angelo Vendrame at 2026-04-16T09:17:33+02:00
7 changed files:
- dom/xml/nsXMLContentSink.cpp
- + dom/xml/test/file_bug1666613.xml
- dom/xml/test/mochitest.toml
- + dom/xml/test/test_bug1666613.html
- gfx/thebes/gfxHarfBuzzShaper.cpp
- gfx/thebes/gfxHarfBuzzShaper.h
- layout/style/res/ua.css
Changes:
| ... | ... | @@ -54,6 +54,7 @@ |
| 54 | 54 | #include "mozilla/dom/ScriptLoader.h"
|
| 55 | 55 | #include "mozilla/dom/txMozillaXSLTProcessor.h"
|
| 56 | 56 | #include "mozilla/dom/nsCSPUtils.h"
|
| 57 | +#include "mozilla/intl/LocaleService.h"
|
|
| 57 | 58 | #include "mozilla/CycleCollectedJSContext.h"
|
| 58 | 59 | #include "mozilla/LoadInfo.h"
|
| 59 | 60 | #include "mozilla/UseCounter.h"
|
| ... | ... | @@ -1370,12 +1371,6 @@ nsXMLContentSink::ReportError(const char16_t* aErrorText, |
| 1370 | 1371 | }
|
| 1371 | 1372 | |
| 1372 | 1373 | // prepare to set <parsererror> as the document root
|
| 1373 | - rv = HandleProcessingInstruction(
|
|
| 1374 | - u"xml-stylesheet",
|
|
| 1375 | - u"href=\"chrome://global/locale/intl.css\" type=\"text/css\"");
|
|
| 1376 | - NS_ENSURE_SUCCESS(rv, rv);
|
|
| 1377 | - |
|
| 1378 | - const char16_t* noAtts[] = {0, 0};
|
|
| 1379 | 1374 | |
| 1380 | 1375 | constexpr auto errorNs =
|
| 1381 | 1376 | u"http://www.mozilla.org/newlayout/xml/parsererror.xml"_ns;
|
| ... | ... | @@ -1384,7 +1379,12 @@ nsXMLContentSink::ReportError(const char16_t* aErrorText, |
| 1384 | 1379 | parsererror.Append((char16_t)0xFFFF);
|
| 1385 | 1380 | parsererror.AppendLiteral("parsererror");
|
| 1386 | 1381 | |
| 1387 | - rv = HandleStartElement(parsererror.get(), noAtts, 0, (uint32_t)-1, 0);
|
|
| 1382 | + const char16_t* dirAttr[] = {u"dir", u"ltr", 0, 0};
|
|
| 1383 | + if (intl::LocaleService::GetInstance()->IsAppLocaleRTL() &&
|
|
| 1384 | + !mDocument->ShouldResistFingerprinting(RFPTarget::JSLocale)) {
|
|
| 1385 | + dirAttr[1] = u"rtl";
|
|
| 1386 | + }
|
|
| 1387 | + rv = HandleStartElement(parsererror.get(), dirAttr, 0, 2, 0);
|
|
| 1388 | 1388 | NS_ENSURE_SUCCESS(rv, rv);
|
| 1389 | 1389 | |
| 1390 | 1390 | rv = HandleCharacterData(aErrorText, NS_strlen(aErrorText), false);
|
| ... | ... | @@ -1394,6 +1394,7 @@ nsXMLContentSink::ReportError(const char16_t* aErrorText, |
| 1394 | 1394 | sourcetext.Append((char16_t)0xFFFF);
|
| 1395 | 1395 | sourcetext.AppendLiteral("sourcetext");
|
| 1396 | 1396 | |
| 1397 | + const char16_t* noAtts[] = {0, 0};
|
|
| 1397 | 1398 | rv = HandleStartElement(sourcetext.get(), noAtts, 0, (uint32_t)-1, 0);
|
| 1398 | 1399 | NS_ENSURE_SUCCESS(rv, rv);
|
| 1399 | 1400 |
| 1 | +<invalid |
| ... | ... | @@ -4,6 +4,7 @@ support-files = [ |
| 4 | 4 | "file_bug293347xslt.xml",
|
| 5 | 5 | "file_bug343870.xml",
|
| 6 | 6 | "file_bug691215.xml",
|
| 7 | + "file_bug1666613.xml",
|
|
| 7 | 8 | ]
|
| 8 | 9 | |
| 9 | 10 | ["test_bug232004.xhtml"]
|
| ... | ... | @@ -19,3 +20,5 @@ skip-if = [ |
| 19 | 20 | "http2",
|
| 20 | 21 | "http3",
|
| 21 | 22 | ]
|
| 23 | + |
|
| 24 | +["test_bug1666613.html"] |
| 1 | +<!DOCTYPE HTML>
|
|
| 2 | +<html>
|
|
| 3 | +<head>
|
|
| 4 | + <title>Test for Bug 1666613</title>
|
|
| 5 | + <script src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
| 6 | + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
|
| 7 | + <style>iframe { width: 90%; }</style>
|
|
| 8 | +</head>
|
|
| 9 | +<body>
|
|
| 10 | +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1666613">Mozilla Bug 691215</a>
|
|
| 11 | +<p id="display"></p>
|
|
| 12 | +<script class="testbody" type="text/javascript">
|
|
| 13 | + |
|
| 14 | +SimpleTest.waitForExplicitFinish();
|
|
| 15 | + |
|
| 16 | +function checkDir(expected) {
|
|
| 17 | + return new Promise(resolve => {
|
|
| 18 | + let iframe = document.createElement("iframe");
|
|
| 19 | + document.body.append(iframe);
|
|
| 20 | + iframe.onload = () => {
|
|
| 21 | + let parserError = iframe.contentDocument.documentElement;
|
|
| 22 | + is(parserError.getAttribute("dir"), expected);
|
|
| 23 | + resolve();
|
|
| 24 | + };
|
|
| 25 | + iframe.src = "file_bug1666613.xml";
|
|
| 26 | + });
|
|
| 27 | +}
|
|
| 28 | + |
|
| 29 | +async function sanityTest() {
|
|
| 30 | + await checkDir("ltr");
|
|
| 31 | + await pseudoBidiTest();
|
|
| 32 | +}
|
|
| 33 | + |
|
| 34 | +async function pseudoBidiTest() {
|
|
| 35 | + await SpecialPowers.pushPrefEnv({
|
|
| 36 | + set: [["intl.l10n.pseudo", "bidi"]]
|
|
| 37 | + });
|
|
| 38 | + await checkDir("rtl");
|
|
| 39 | + SimpleTest.finish();
|
|
| 40 | +}
|
|
| 41 | + |
|
| 42 | +sanityTest();
|
|
| 43 | +</script>
|
|
| 44 | +</body>
|
|
| 45 | +</html> |
| ... | ... | @@ -1181,9 +1181,6 @@ static void AddOpenTypeFeature(uint32_t aTag, uint32_t aValue, void* aUserArg) { |
| 1181 | 1181 | * gfxFontShaper override to initialize the text run using HarfBuzz
|
| 1182 | 1182 | */
|
| 1183 | 1183 | |
| 1184 | -static hb_font_funcs_t* sHBFontFuncs = nullptr;
|
|
| 1185 | -static hb_font_funcs_t* sNominalGlyphFunc = nullptr;
|
|
| 1186 | -static hb_unicode_funcs_t* sHBUnicodeFuncs = nullptr;
|
|
| 1187 | 1184 | MOZ_RUNINIT static const hb_script_t sMathScript =
|
| 1188 | 1185 | hb_ot_tag_to_script(HB_TAG('m', 'a', 't', 'h'));
|
| 1189 | 1186 | |
| ... | ... | @@ -1192,52 +1189,58 @@ bool gfxHarfBuzzShaper::Initialize() { |
| 1192 | 1189 | // other thread can yet be using it.
|
| 1193 | 1190 | MOZ_PUSH_IGNORE_THREAD_SAFETY
|
| 1194 | 1191 | |
| 1195 | - if (!sHBFontFuncs) {
|
|
| 1196 | - // static function callback pointers, initialized by the first
|
|
| 1197 | - // harfbuzz shaper used
|
|
| 1198 | - sHBFontFuncs = hb_font_funcs_create();
|
|
| 1199 | - hb_font_funcs_set_nominal_glyph_func(sHBFontFuncs, HBGetNominalGlyph,
|
|
| 1200 | - nullptr, nullptr);
|
|
| 1201 | - hb_font_funcs_set_nominal_glyphs_func(sHBFontFuncs, HBGetNominalGlyphs,
|
|
| 1202 | - nullptr, nullptr);
|
|
| 1203 | - hb_font_funcs_set_variation_glyph_func(sHBFontFuncs, HBGetVariationGlyph,
|
|
| 1204 | - nullptr, nullptr);
|
|
| 1205 | - hb_font_funcs_set_glyph_h_advance_func(sHBFontFuncs, HBGetGlyphHAdvance,
|
|
| 1206 | - nullptr, nullptr);
|
|
| 1207 | - hb_font_funcs_set_glyph_h_advances_func(sHBFontFuncs, HBGetGlyphHAdvances,
|
|
| 1208 | - nullptr, nullptr);
|
|
| 1209 | - hb_font_funcs_set_glyph_v_advance_func(sHBFontFuncs, HBGetGlyphVAdvance,
|
|
| 1210 | - nullptr, nullptr);
|
|
| 1211 | - hb_font_funcs_set_glyph_v_origin_func(sHBFontFuncs, HBGetGlyphVOrigin,
|
|
| 1212 | - nullptr, nullptr);
|
|
| 1213 | - hb_font_funcs_set_glyph_extents_func(sHBFontFuncs, HBGetGlyphExtents,
|
|
| 1214 | - nullptr, nullptr);
|
|
| 1215 | - hb_font_funcs_set_glyph_contour_point_func(sHBFontFuncs, HBGetContourPoint,
|
|
| 1192 | + // Function callback pointers; these are local statics to ensure thread-safe
|
|
| 1193 | + // initialization on first use.
|
|
| 1194 | + static hb_font_funcs_t* sHBFontFuncs = [] {
|
|
| 1195 | + auto* funcs = hb_font_funcs_create();
|
|
| 1196 | + hb_font_funcs_set_nominal_glyph_func(funcs, HBGetNominalGlyph, nullptr,
|
|
| 1197 | + nullptr);
|
|
| 1198 | + hb_font_funcs_set_nominal_glyphs_func(funcs, HBGetNominalGlyphs, nullptr,
|
|
| 1199 | + nullptr);
|
|
| 1200 | + hb_font_funcs_set_variation_glyph_func(funcs, HBGetVariationGlyph, nullptr,
|
|
| 1201 | + nullptr);
|
|
| 1202 | + hb_font_funcs_set_glyph_h_advance_func(funcs, HBGetGlyphHAdvance, nullptr,
|
|
| 1203 | + nullptr);
|
|
| 1204 | + hb_font_funcs_set_glyph_h_advances_func(funcs, HBGetGlyphHAdvances, nullptr,
|
|
| 1205 | + nullptr);
|
|
| 1206 | + hb_font_funcs_set_glyph_v_advance_func(funcs, HBGetGlyphVAdvance, nullptr,
|
|
| 1207 | + nullptr);
|
|
| 1208 | + hb_font_funcs_set_glyph_v_origin_func(funcs, HBGetGlyphVOrigin, nullptr,
|
|
| 1209 | + nullptr);
|
|
| 1210 | + hb_font_funcs_set_glyph_extents_func(funcs, HBGetGlyphExtents, nullptr,
|
|
| 1211 | + nullptr);
|
|
| 1212 | + hb_font_funcs_set_glyph_contour_point_func(funcs, HBGetContourPoint,
|
|
| 1216 | 1213 | nullptr, nullptr);
|
| 1217 | - hb_font_funcs_set_glyph_h_kerning_func(sHBFontFuncs, HBGetHKerning, nullptr,
|
|
| 1214 | + hb_font_funcs_set_glyph_h_kerning_func(funcs, HBGetHKerning, nullptr,
|
|
| 1218 | 1215 | nullptr);
|
| 1219 | - hb_font_funcs_make_immutable(sHBFontFuncs);
|
|
| 1220 | - |
|
| 1221 | - sNominalGlyphFunc = hb_font_funcs_create();
|
|
| 1222 | - hb_font_funcs_set_nominal_glyph_func(sNominalGlyphFunc, HBGetNominalGlyph,
|
|
| 1223 | - nullptr, nullptr);
|
|
| 1224 | - hb_font_funcs_make_immutable(sNominalGlyphFunc);
|
|
| 1225 | - |
|
| 1226 | - sHBUnicodeFuncs = hb_unicode_funcs_create(hb_unicode_funcs_get_empty());
|
|
| 1227 | - hb_unicode_funcs_set_mirroring_func(sHBUnicodeFuncs, HBGetMirroring,
|
|
| 1228 | - nullptr, nullptr);
|
|
| 1229 | - hb_unicode_funcs_set_script_func(sHBUnicodeFuncs, HBGetScript, nullptr,
|
|
| 1230 | - nullptr);
|
|
| 1231 | - hb_unicode_funcs_set_general_category_func(
|
|
| 1232 | - sHBUnicodeFuncs, HBGetGeneralCategory, nullptr, nullptr);
|
|
| 1233 | - hb_unicode_funcs_set_combining_class_func(
|
|
| 1234 | - sHBUnicodeFuncs, HBGetCombiningClass, nullptr, nullptr);
|
|
| 1235 | - hb_unicode_funcs_set_compose_func(sHBUnicodeFuncs, HBUnicodeCompose,
|
|
| 1236 | - nullptr, nullptr);
|
|
| 1237 | - hb_unicode_funcs_set_decompose_func(sHBUnicodeFuncs, HBUnicodeDecompose,
|
|
| 1238 | - nullptr, nullptr);
|
|
| 1239 | - hb_unicode_funcs_make_immutable(sHBUnicodeFuncs);
|
|
| 1240 | - }
|
|
| 1216 | + hb_font_funcs_make_immutable(funcs);
|
|
| 1217 | + return funcs;
|
|
| 1218 | + }();
|
|
| 1219 | + |
|
| 1220 | + static hb_font_funcs_t* sNominalGlyphFunc = [] {
|
|
| 1221 | + auto* funcs = hb_font_funcs_create();
|
|
| 1222 | + hb_font_funcs_set_nominal_glyph_func(funcs, HBGetNominalGlyph, nullptr,
|
|
| 1223 | + nullptr);
|
|
| 1224 | + hb_font_funcs_make_immutable(funcs);
|
|
| 1225 | + return funcs;
|
|
| 1226 | + }();
|
|
| 1227 | + |
|
| 1228 | + static hb_unicode_funcs_t* sHBUnicodeFuncs = [] {
|
|
| 1229 | + auto* funcs = hb_unicode_funcs_create(hb_unicode_funcs_get_empty());
|
|
| 1230 | + hb_unicode_funcs_set_mirroring_func(funcs, HBGetMirroring, nullptr,
|
|
| 1231 | + nullptr);
|
|
| 1232 | + hb_unicode_funcs_set_script_func(funcs, HBGetScript, nullptr, nullptr);
|
|
| 1233 | + hb_unicode_funcs_set_general_category_func(funcs, HBGetGeneralCategory,
|
|
| 1234 | + nullptr, nullptr);
|
|
| 1235 | + hb_unicode_funcs_set_combining_class_func(funcs, HBGetCombiningClass,
|
|
| 1236 | + nullptr, nullptr);
|
|
| 1237 | + hb_unicode_funcs_set_compose_func(funcs, HBUnicodeCompose, nullptr,
|
|
| 1238 | + nullptr);
|
|
| 1239 | + hb_unicode_funcs_set_decompose_func(funcs, HBUnicodeDecompose, nullptr,
|
|
| 1240 | + nullptr);
|
|
| 1241 | + hb_unicode_funcs_make_immutable(funcs);
|
|
| 1242 | + return funcs;
|
|
| 1243 | + }();
|
|
| 1241 | 1244 | |
| 1242 | 1245 | gfxFontEntry* entry = mFont->GetFontEntry();
|
| 1243 | 1246 | if (!mUseFontGetGlyph) {
|
| ... | ... | @@ -1280,11 +1283,10 @@ bool gfxHarfBuzzShaper::Initialize() { |
| 1280 | 1283 | hb_buffer_set_cluster_level(mBuffer,
|
| 1281 | 1284 | HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
|
| 1282 | 1285 | |
| 1283 | - auto* funcs =
|
|
| 1284 | - mFont->GetFontEntry()->HasFontTable(TRUETYPE_TAG('C', 'F', 'F', ' '))
|
|
| 1285 | - ? sNominalGlyphFunc
|
|
| 1286 | - : sHBFontFuncs;
|
|
| 1287 | - mHBFont = CreateHBFont(mFont, funcs, this);
|
|
| 1286 | + bool isCFF =
|
|
| 1287 | + mFont->GetFontEntry()->HasFontTable(TRUETYPE_TAG('C', 'F', 'F', ' '));
|
|
| 1288 | + auto* funcs = isCFF ? sNominalGlyphFunc : sHBFontFuncs;
|
|
| 1289 | + mHBFont = CreateHBFont(mFont, funcs, this, isCFF);
|
|
| 1288 | 1290 | |
| 1289 | 1291 | MOZ_POP_THREAD_SAFETY
|
| 1290 | 1292 | |
| ... | ... | @@ -1293,12 +1295,13 @@ bool gfxHarfBuzzShaper::Initialize() { |
| 1293 | 1295 | |
| 1294 | 1296 | hb_font_t* gfxHarfBuzzShaper::CreateHBFont(gfxFont* aFont,
|
| 1295 | 1297 | hb_font_funcs_t* aFontFuncs,
|
| 1296 | - void* aCallbackData) {
|
|
| 1298 | + void* aCallbackData,
|
|
| 1299 | + bool aCreateSubfont) {
|
|
| 1297 | 1300 | auto face(aFont->GetFontEntry()->GetHBFace());
|
| 1298 | 1301 | hb_font_t* result = hb_font_create(face);
|
| 1299 | 1302 | |
| 1300 | 1303 | if (aFontFuncs && aCallbackData) {
|
| 1301 | - if (aFontFuncs == sNominalGlyphFunc) {
|
|
| 1304 | + if (aCreateSubfont) {
|
|
| 1302 | 1305 | hb_font_t* subfont = hb_font_create_sub_font(result);
|
| 1303 | 1306 | hb_font_destroy(result);
|
| 1304 | 1307 | result = subfont;
|
| ... | ... | @@ -103,7 +103,8 @@ class gfxHarfBuzzShaper : public gfxFontShaper { |
| 103 | 103 | // bounds, etc; if not, the built-in hb_ot font functions will be used.
|
| 104 | 104 | static hb_font_t* CreateHBFont(gfxFont* aFont,
|
| 105 | 105 | hb_font_funcs_t* aFontFuncs = nullptr,
|
| 106 | - void* aCallbackData = nullptr);
|
|
| 106 | + void* aCallbackData = nullptr,
|
|
| 107 | + bool aCreateSubfont = false);
|
|
| 107 | 108 | |
| 108 | 109 | protected:
|
| 109 | 110 | // Initializes the shaper and returns whether this was successful.
|
| ... | ... | @@ -434,6 +434,10 @@ parsererror|parsererror { |
| 434 | 434 | color: black;
|
| 435 | 435 | }
|
| 436 | 436 | |
| 437 | +parsererror|parsererror[dir="rtl"] {
|
|
| 438 | + direction: rtl;
|
|
| 439 | +}
|
|
| 440 | + |
|
| 437 | 441 | parsererror|sourcetext {
|
| 438 | 442 | display: block;
|
| 439 | 443 | white-space: pre;
|
| ... | ... | @@ -443,6 +447,7 @@ parsererror|sourcetext { |
| 443 | 447 | color: red;
|
| 444 | 448 | font-weight: bold;
|
| 445 | 449 | font-size: 12pt;
|
| 450 | + direction: ltr;
|
|
| 446 | 451 | }
|
| 447 | 452 | |
| 448 | 453 | /* Custom content container in the CanvasFrame, positioned on top of everything
|