tor-browser

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

commit e4f1380f8cd0bb93ca1f3eacb4374748d8627a0c
parent 675ef662b1ec7d8cc28f1fc067faf31a74e5c91f
Author: Jonathan Kew <jkew@mozilla.com>
Date:   Sat,  6 Dec 2025 00:21:51 +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) {} + CharType* 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);