From 5ecbd2583efdd026b27aceb143c04d85309d1ca3 Mon Sep 17 00:00:00 2001 From: Michael Kaply Date: Thu, 23 Apr 2020 20:37:25 +0000 Subject: [PATCH] Bug 1415146 - Use getExposedWebLocales for navigator.language(s) if there are no accept languages. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D59565 --- dom/base/Navigator.cpp | 30 ++++++++++++------- dom/base/test/test_navigator_language.html | 2 +- dom/workers/WorkerNavigator.h | 7 ++--- .../test/test_navigator_languages.html | 17 +++++++---- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index 9a916aecb138..409cd4cc689d 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -109,6 +109,8 @@ #include "mozilla/webgpu/Instance.h" #include "mozilla/dom/WindowGlobalChild.h" +#include "mozilla/intl/LocaleService.h" + namespace mozilla { namespace dom { @@ -315,7 +317,13 @@ void Navigator::GetAppName(nsAString& aAppName, CallerType aCallerType) const { * * "en", "en-US" and "i-cherokee" and "" are valid languages tokens. * - * An empty array will be returned if there is no valid languages. + * If there is no valid language, the value of getWebExposedLocales is + * used to ensure that locale spoofing is honored and to reduce + * fingerprinting. + * + * See RFC 7231, Section 9.7 "Browser Fingerprinting" and + * RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers" + * for more detail. */ /* static */ void Navigator::GetAcceptLanguages(nsTArray& aLanguages) { @@ -361,29 +369,29 @@ void Navigator::GetAcceptLanguages(nsTArray& aLanguages) { aLanguages.AppendElement(lang); } + if (aLanguages.Length() == 0) { + nsTArray locales; + mozilla::intl::LocaleService::GetInstance()->GetWebExposedLocales(locales); + aLanguages.AppendElement(NS_ConvertUTF8toUTF16(locales[0])); + } } /** - * Do not use UI language (chosen app locale) here but the first value set in - * the Accept Languages header, see ::GetAcceptLanguages(). + * Returns the first language from GetAcceptLanguages. * - * See RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers" for - * the reasons why. + * Full details above in GetAcceptLanguages. */ void Navigator::GetLanguage(nsAString& aLanguage) { nsTArray languages; GetLanguages(languages); - if (languages.Length() >= 1) { - aLanguage.Assign(languages[0]); - } else { - aLanguage.Truncate(); - } + MOZ_ASSERT(languages.Length() >= 1); + aLanguage.Assign(languages[0]); } void Navigator::GetLanguages(nsTArray& aLanguages) { GetAcceptLanguages(aLanguages); - // The returned value is cached by the binding code. The window listen to the + // The returned value is cached by the binding code. The window listens to the // accept languages change and will clear the cache when needed. It has to // take care of dispatching the DOM event already and the invalidation and the // event has to be timed correctly. diff --git a/dom/base/test/test_navigator_language.html b/dom/base/test/test_navigator_language.html index 7d8cca5fc851..0e0173b5672f 100644 --- a/dom/base/test/test_navigator_language.html +++ b/dom/base/test/test_navigator_language.html @@ -28,7 +28,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=889335 var testValues = [ { accept_languages: 'foo', language: 'foo', languages: ['foo'] }, - { accept_languages: '', language: '', languages: [] }, + { accept_languages: '', language: 'en-US', languages: ['en-US'] }, { accept_languages: 'foo,bar', language: 'foo', languages: [ 'foo', 'bar' ] }, { accept_languages: ' foo , bar ', language: 'foo', languages: [ 'foo', 'bar' ] }, { accept_languages: ' foo ; bar ', language: 'foo ; bar', languages: [ 'foo ; bar' ] }, diff --git a/dom/workers/WorkerNavigator.h b/dom/workers/WorkerNavigator.h index bf186ba1ae36..0b99b02c538b 100644 --- a/dom/workers/WorkerNavigator.h +++ b/dom/workers/WorkerNavigator.h @@ -68,11 +68,8 @@ class WorkerNavigator final : public nsWrapperCache { bool TaintEnabled() const { return false; } void GetLanguage(nsString& aLanguage) const { - if (mProperties.mLanguages.Length() >= 1) { - aLanguage.Assign(mProperties.mLanguages[0]); - } else { - aLanguage.Truncate(); - } + MOZ_ASSERT(mProperties.mLanguages.Length() >= 1); + aLanguage.Assign(mProperties.mLanguages[0]); } void GetLanguages(nsTArray& aLanguages) const { diff --git a/dom/workers/test/test_navigator_languages.html b/dom/workers/test/test_navigator_languages.html index 1d7426cbdc18..68dab11f2971 100644 --- a/dom/workers/test/test_navigator_languages.html +++ b/dom/workers/test/test_navigator_languages.html @@ -20,8 +20,13 @@ Tests of DOM Worker Navigator