tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 527055fac7f9602a28c885dabbdd5f878ec723e6
parent a2ee9ef2cf4d68b359f8f60649b9cfe90fb0619c
Author: Jonathan Kew <jkew@mozilla.com>
Date:   Fri,  5 Dec 2025 18:22:47 +0000

Bug 2003721 - Canonicalize lang-subtag case during attribute mapping. r=layout-reviewers,emilio

Differential Revision: https://phabricator.services.mozilla.com/D275267

Diffstat:
Mdom/html/nsGenericHTMLElement.cpp | 38+++++++++++++++++++++++++++++++++++---
1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp @@ -57,6 +57,7 @@ #include "mozilla/dom/ToggleEvent.h" #include "mozilla/dom/TouchEvent.h" #include "mozilla/dom/UnbindContext.h" +#include "mozilla/intl/Locale.h" #include "nsAtom.h" #include "nsAttrValueOrString.h" #include "nsCOMPtr.h" @@ -1281,10 +1282,41 @@ static inline void MapLangAttributeInto(MappedDeclarationsBuilder& aBuilder) { return; } MOZ_ASSERT(langValue->Type() == nsAttrValue::eAtom); - aBuilder.SetIdentAtomValueIfUnset(eCSSProperty__x_lang, - langValue->GetAtomValue()); + + // Adaptor for nsCString to expose the Buffer interface to Locale::ToString. + class BufferAdaptor { + public: + using CharType = char; + + explicit BufferAdaptor(nsCString& aString) : mString(aString) {} + char* data() { return mString.BeginWriting(); } + size_t capacity() const { return mString.Length(); } + bool reserve(size_t aLen) { return mString.SetLength(aLen, fallible); } + void written(size_t aLen) { mString.SetLength(aLen); } + + private: + nsCString& mString; + }; + + // Try parsing lang as a Locale and canonicalizing the subtags; if parsing + // succeeds, we record the canonicalized version rather than the original, + // so that code checking for particular codes can assume canonical casing. + // Note that in some cases this will also map 3-character ISO 639-3 tags to + // their corresponding 2-char ISO 639-1 tags. + RefPtr<nsAtom> lang = langValue->GetAtomValue(); + nsAtomCString langStr(lang); + intl::Locale loc; + if (intl::LocaleParser::TryParse(langStr, loc).isOk() && + loc.Canonicalize().isOk()) { + nsAutoCString canonical; + BufferAdaptor buffer(canonical); + if (loc.ToString(buffer).isOk() && canonical != langStr) { + lang = NS_Atomize(canonical); + } + } + + aBuilder.SetIdentAtomValueIfUnset(eCSSProperty__x_lang, lang); if (!aBuilder.PropertyIsSet(eCSSProperty_text_emphasis_position)) { - const nsAtom* lang = langValue->GetAtomValue(); if (nsStyleUtil::MatchesLanguagePrefix(lang, u"zh")) { aBuilder.SetKeywordValue(eCSSProperty_text_emphasis_position, StyleTextEmphasisPosition::UNDER._0);