Bug 1415146 - Use getExposedWebLocales for navigator.language(s) if there are no accept languages. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D59565
This commit is contained in:
Michael Kaply 2020-04-27 20:16:04 +00:00
Родитель 62cc378f74
Коммит 350170619f
4 изменённых файлов: 34 добавлений и 23 удалений

Просмотреть файл

@ -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<nsString>& aLanguages) {
@ -361,29 +369,29 @@ void Navigator::GetAcceptLanguages(nsTArray<nsString>& aLanguages) {
aLanguages.AppendElement(lang);
}
if (aLanguages.Length() == 0) {
nsTArray<nsCString> 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<nsString> 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<nsString>& 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.

Просмотреть файл

@ -25,10 +25,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=889335
var actualLanguageChangesFromHandler = 0;
var actualLanguageChangesFromAVL = 0;
var expectedLanguageChanges = 0;
var emptyLocale = SpecialPowers.Services.locale.webExposedLocales[0];
var testValues = [
{ accept_languages: 'foo', language: 'foo', languages: ['foo'] },
{ accept_languages: '', language: '', languages: [] },
{ accept_languages: '', language: emptyLocale, languages: [emptyLocale] },
{ 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' ] },

Просмотреть файл

@ -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<nsString>& aLanguages) const {

Просмотреть файл

@ -20,8 +20,13 @@ Tests of DOM Worker Navigator
<pre id="test">
<script class="testbody" language="javascript">
var tests = [ 'en,it', 'it,en,fr', '', 'en' ];
var expectedLanguages;
var tests = [
{ expectedLanguages: 'en,it', inputLanguages: 'en,it' },
{ expectedLanguages: 'it,en,fr', inputLanguages: 'it,en,fr' },
{ expectedLanguages: SpecialPowers.Services.locale.webExposedLocales[0], inputLanguages: '' },
{ expectedLanguages: 'en,it', inputLanguages: 'en,it' },
];
var test;
function runTests() {
if (!tests.length) {
worker.postMessage('finish');
@ -29,8 +34,8 @@ Tests of DOM Worker Navigator
return;
}
expectedLanguages = tests.shift();
SpecialPowers.pushPrefEnv({"set": [["intl.accept_languages", expectedLanguages]]}, function() {
test = tests.shift();
SpecialPowers.pushPrefEnv({"set": [["intl.accept_languages", test.inputLanguages]]}, function() {
worker.postMessage(true);
});
}
@ -40,8 +45,8 @@ Tests of DOM Worker Navigator
var worker = new Worker("navigator_languages_worker.js");
worker.onmessage = function(event) {
is(event.data.toString(), navigator.languages.toString(), "The languages mach.");
is(event.data.toString(), expectedLanguages, "This is the correct result.");
is(event.data.toString(), navigator.languages.toString(), "The languages match.");
is(event.data.toString(), test.expectedLanguages, "This is the correct result.");
runTests();
}