Backed out 5 changesets (bug 1846224, bug 1845940) for causing spidermonkey build bustages on TestingUtility.cpp. CLOSED TREE

Backed out changeset fc9692101130 (bug 1846224)
Backed out changeset 61486ba55cae (bug 1846224)
Backed out changeset a85aaad7d2f8 (bug 1846224)
Backed out changeset e90bc9bc5729 (bug 1846224)
Backed out changeset 38262976d922 (bug 1845940)
This commit is contained in:
Iulian Moraru 2023-09-08 17:13:44 +03:00
parent efd25593ba
commit dd918f58bd
30 changed files with 143 additions and 266 deletions

View File

@ -152,43 +152,3 @@ add_task(async function test_timezone_exempt_wrong_domain() {
await SpecialPowers.popPrefEnv();
});
add_task(async function test_timezone_exmpt_browser() {
SpecialPowers.Cu.getJSTestingFunctions().setTimeZone("PST8PDT");
is(
Intl.DateTimeFormat("en-US").resolvedOptions().timeZone,
"PST8PDT",
"Default time zone should have changed"
);
await SpecialPowers.pushPrefEnv({
set: [["privacy.resistFingerprinting", true]],
});
is(
Intl.DateTimeFormat("en-US").resolvedOptions().timeZone,
"PST8PDT",
"Timezone in chrome should be unaffected by resistFingerprinting"
);
let newWindow = Services.ww.openWindow(
null,
AppConstants.BROWSER_CHROME_URL,
"_blank",
"chrome,dialog=no,all,alwaysRaised",
null
);
is(
newWindow.Intl.DateTimeFormat("en-US").resolvedOptions().timeZone,
"PST8PDT",
"Timezone in new chrome window should be unaffected by resistFingerprinting"
);
newWindow.close();
await SpecialPowers.popPrefEnv();
// Reset timezone
SpecialPowers.Cu.getJSTestingFunctions().setTimeZone(undefined);
});

View File

@ -2787,10 +2787,10 @@ nsresult Document::Init(nsIPrincipal* aPrincipal,
if (aPrincipal) {
SetPrincipals(aPrincipal, aPartitionedPrincipal);
} else {
RecomputeResistFingerprinting();
}
RecomputeResistFingerprinting();
return NS_OK;
}
@ -4241,8 +4241,6 @@ void Document::SetPrincipals(nsIPrincipal* aNewPrincipal,
mCSSLoader->RegisterInSheetCache();
RecomputeResistFingerprinting();
#ifdef DEBUG
// Validate that the docgroup is set correctly by calling its getter and
// triggering its sanity check.

View File

@ -2045,8 +2045,7 @@ static nsresult CreateNativeGlobalForInner(
xpc::InitGlobalObjectOptions(
options, principal->IsSystemPrincipal(),
aDocument->ShouldResistFingerprinting(RFPTarget::JSDateTimeUTC),
aDocument->ShouldResistFingerprinting(RFPTarget::JSMathFdlibm),
aDocument->ShouldResistFingerprinting(RFPTarget::JSLocale));
aDocument->ShouldResistFingerprinting(RFPTarget::JSMathFdlibm));
// Determine if we need the Components object.
bool needComponents = principal->IsSystemPrincipal();

View File

@ -47,7 +47,20 @@ bool AudioWorkletGlobalScope::WrapGlobalObject(
// The graph needs a handle on the JSContext so it can interrupt JS.
Impl()->DestinationTrack()->Graph()->NotifyJSContext(aCx);
JS::RealmOptions options = CreateRealmOptions();
JS::RealmOptions options;
options.creationOptions().setForceUTC(
ShouldResistFingerprinting(RFPTarget::JSDateTimeUTC));
options.creationOptions().setAlwaysUseFdlibm(
ShouldResistFingerprinting(RFPTarget::JSMathFdlibm));
// The SharedArrayBuffer global constructor property should not be present in
// a fresh global object when shared memory objects aren't allowed (because
// COOP/COEP support isn't enabled, or because COOP/COEP don't act to isolate
// this worklet to a separate process).
options.creationOptions().setDefineSharedArrayBufferConstructor(
IsSharedMemoryAllowed());
return AudioWorkletGlobalScope_Binding::Wrap(
aCx, this, this, options, BasePrincipal::Cast(mImpl->Principal()), true,
aReflector);

View File

@ -2452,12 +2452,6 @@ WorkerPrivate::WorkerPrivate(
contentCreationOptions.setAlwaysUseFdlibm(
ShouldResistFingerprinting(RFPTarget::JSMathFdlibm));
if (ShouldResistFingerprinting(RFPTarget::JSLocale)) {
nsCString locale = nsRFPService::GetSpoofedJSLocale();
chromeCreationOptions.setLocaleCopyZ(locale.get());
contentCreationOptions.setLocaleCopyZ(locale.get());
}
// Check if it's a privileged addon executing in order to allow access
// to SharedArrayBuffer
if (mLoadInfo.mPrincipal) {

View File

@ -10,10 +10,8 @@
#include "mozilla/dom/WorkletThread.h"
#include "mozilla/dom/worklet/WorkletModuleLoader.h"
#include "mozilla/dom/Console.h"
#include "js/RealmOptions.h"
#include "nsContentUtils.h"
#include "nsJSUtils.h"
#include "nsRFPService.h"
using JS::loader::ModuleLoaderBase;
using mozilla::dom::loader::WorkletModuleLoader;
@ -115,26 +113,4 @@ void WorkletGlobalScope::Dump(const Optional<nsAString>& aString) const {
fflush(stdout);
}
JS::RealmOptions WorkletGlobalScope::CreateRealmOptions() const {
JS::RealmOptions options;
options.creationOptions().setForceUTC(
ShouldResistFingerprinting(RFPTarget::JSDateTimeUTC));
options.creationOptions().setAlwaysUseFdlibm(
ShouldResistFingerprinting(RFPTarget::JSMathFdlibm));
if (ShouldResistFingerprinting(RFPTarget::JSLocale)) {
nsCString locale = nsRFPService::GetSpoofedJSLocale();
options.creationOptions().setLocaleCopyZ(locale.get());
}
// The SharedArrayBuffer global constructor property should not be present in
// a fresh global object when shared memory objects aren't allowed (because
// COOP/COEP support isn't enabled, or because COOP/COEP don't act to isolate
// this worklet to a separate process).
options.creationOptions().setDefineSharedArrayBufferConstructor(
IsSharedMemoryAllowed());
return options;
}
} // namespace mozilla::dom

View File

@ -22,10 +22,6 @@
} \
}
namespace JS {
class RealmOptions;
}
namespace JS::loader {
class ModuleLoaderBase;
}
@ -90,8 +86,6 @@ class WorkletGlobalScope : public nsIGlobalObject, public nsWrapperCache {
protected:
~WorkletGlobalScope();
JS::RealmOptions CreateRealmOptions() const;
const RefPtr<WorkletImpl> mImpl;
private:

View File

@ -18,7 +18,6 @@
#include "jstypes.h" // JS_PUBLIC_API
#include "js/Class.h" // JSTraceOp
#include "js/RefCounted.h"
struct JS_PUBLIC_API JSContext;
class JS_PUBLIC_API JSObject;
@ -61,14 +60,6 @@ enum class WeakRefSpecifier {
EnabledWithoutCleanupSome
};
struct LocaleString : js::RefCounted<LocaleString> {
const char* chars_;
explicit LocaleString(const char* chars) : chars_(chars) {}
auto chars() const { return chars_; }
};
/**
* RealmCreationOptions specifies options relevant to creating a new realm, that
* are either immutable characteristics of that realm or that are discarded
@ -268,9 +259,6 @@ class JS_PUBLIC_API RealmCreationOptions {
return *this;
}
RefPtr<LocaleString> locale() const { return locale_; }
RealmCreationOptions& setLocaleCopyZ(const char* locale);
// Always use the fdlibm implementation of math functions instead of the
// platform native libc implementations. Useful for fingerprinting protection
// and cross-platform consistency.
@ -294,7 +282,6 @@ class JS_PUBLIC_API RealmCreationOptions {
Zone* zone_;
};
uint64_t profilerRealmID_ = 0;
RefPtr<LocaleString> locale_;
WeakRefSpecifier weakRefs_ = WeakRefSpecifier::Disabled;
bool invisibleToDebugger_ = false;
bool preserveJitCode_ = false;

View File

@ -7813,12 +7813,34 @@ static bool SetDefaultLocale(JSContext* cx, unsigned argc, Value* vp) {
}
if (args[0].isString() && !args[0].toString()->empty()) {
RootedString str(cx, args[0].toString());
UniqueChars locale = StringToLocale(cx, callee, str);
Rooted<JSLinearString*> str(cx, args[0].toString()->ensureLinear(cx));
if (!str) {
return false;
}
if (!StringIsAscii(str)) {
ReportUsageErrorASCII(cx, callee,
"First argument contains non-ASCII characters");
return false;
}
UniqueChars locale = JS_EncodeStringToASCII(cx, str);
if (!locale) {
return false;
}
bool containsOnlyValidBCP47Characters =
mozilla::IsAsciiAlpha(locale[0]) &&
std::all_of(locale.get(), locale.get() + str->length(), [](auto c) {
return mozilla::IsAsciiAlphanumeric(c) || c == '-';
});
if (!containsOnlyValidBCP47Characters) {
ReportUsageErrorASCII(cx, callee,
"First argument should be a BCP47 language tag");
return false;
}
if (!JS_SetDefaultLocale(cx->runtime(), locale.get())) {
ReportOutOfMemory(cx);
return false;

View File

@ -255,36 +255,3 @@ bool js::ParseDebugMetadata(JSContext* cx, JS::Handle<JSObject*> opts,
return true;
}
JS::UniqueChars js::StringToLocale(JSContext* cx, JS::Handle<JSObject*> callee,
JS::Handle<JSString*> str_) {
Rooted<JSLinearString*> str(cx, str_->ensureLinear(cx));
if (!str) {
return nullptr;
}
if (!StringIsAscii(str)) {
ReportUsageErrorASCII(cx, callee,
"First argument contains non-ASCII characters");
return nullptr;
}
UniqueChars locale = JS_EncodeStringToASCII(cx, str);
if (!locale) {
return nullptr;
}
bool containsOnlyValidBCP47Characters =
mozilla::IsAsciiAlpha(locale[0]) &&
std::all_of(locale.get(), locale.get() + str->length(), [](auto c) {
return mozilla::IsAsciiAlphanumeric(c) || c == '-';
});
if (!containsOnlyValidBCP47Characters) {
ReportUsageErrorASCII(cx, callee,
"First argument should be a BCP47 language tag");
return nullptr;
}
return locale;
}

View File

@ -59,10 +59,6 @@ JSObject* CreateScriptPrivate(JSContext* cx,
JS::MutableHandle<JS::Value> privateValue,
JS::MutableHandle<JSString*> elementAttributeName);
[[nodiscard]] JS::UniqueChars StringToLocale(JSContext* cx,
JS::Handle<JSObject*> callee,
JS::Handle<JSString*> str_);
} /* namespace js */
#endif /* builtin_TestingUtility_h */

View File

@ -1,19 +0,0 @@
// |jit-test| skip-if: typeof Intl === 'undefined'
function test(locale, timeZone) {
let global = newGlobal({locale, forceUTC: true});
const constructors = ["Collator", "DateTimeFormat", "ListFormat",
"NumberFormat", "PluralRules", "RelativeTimeFormat"];
for (const constructor of constructors) {
let intl = new global.Intl[constructor];
assertEq(intl.resolvedOptions().locale, locale);
}
const date = new global.Date(2012, 0, 10);
let tzRE = /\(([^\)]+)\)/;
assertEq(tzRE.exec(date)[1], timeZone)
}
test("de-CH", "Koordinierte Weltzeit");
test("en", "Coordinated Universal Time");

View File

@ -1722,24 +1722,6 @@ JS::RealmCreationOptions& JS::RealmCreationOptions::setCoopAndCoepEnabled(
return *this;
}
JS::RealmCreationOptions& JS::RealmCreationOptions::setLocaleCopyZ(
const char* locale) {
const size_t size = strlen(locale) + 1;
AutoEnterOOMUnsafeRegion oomUnsafe;
char* memoryPtr = js_pod_malloc<char>(sizeof(LocaleString) + size);
if (!memoryPtr) {
oomUnsafe.crash("RealmCreationOptions::setLocaleCopyZ");
}
char* localePtr = memoryPtr + sizeof(LocaleString);
memcpy(localePtr, locale, size);
locale_ = new (memoryPtr) LocaleString(localePtr);
return *this;
}
const JS::RealmBehaviors& JS::RealmBehaviorsRef(JS::Realm* realm) {
return realm->behaviors();
}

View File

@ -156,8 +156,7 @@ class DateTimeHelper {
static double UTC(DateTimeInfo::ForceUTC forceUTC, double t);
static JSString* timeZoneComment(JSContext* cx,
DateTimeInfo::ForceUTC forceUTC,
const char* locale, double utcTime,
double localTime);
double utcTime, double localTime);
#if !JS_HAS_INTL_API
static size_t formatTime(DateTimeInfo::ForceUTC forceUTC, char* buf,
size_t buflen, const char* fmt, double utcTime,
@ -2945,8 +2944,8 @@ static bool date_toJSON(JSContext* cx, unsigned argc, Value* vp) {
#if JS_HAS_INTL_API
JSString* DateTimeHelper::timeZoneComment(JSContext* cx,
DateTimeInfo::ForceUTC forceUTC,
const char* locale, double utcTime,
double localTime) {
double utcTime, double localTime) {
const char* locale = cx->runtime()->getDefaultLocale();
if (!locale) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_DEFAULT_LOCALE_ERROR);
@ -3019,8 +3018,7 @@ size_t DateTimeHelper::formatTime(DateTimeInfo::ForceUTC forceUTC, char* buf,
JSString* DateTimeHelper::timeZoneComment(JSContext* cx,
DateTimeInfo::ForceUTC forceUTC,
const char* locale, double utcTime,
double localTime) {
double utcTime, double localTime) {
char tzbuf[100];
size_t tzlen =
@ -3057,7 +3055,7 @@ JSString* DateTimeHelper::timeZoneComment(JSContext* cx,
enum class FormatSpec { DateTime, Date, Time };
static bool FormatDate(JSContext* cx, DateTimeInfo::ForceUTC forceUTC,
const char* locale, double utcTime, FormatSpec format,
double utcTime, FormatSpec format,
MutableHandleValue rval) {
if (!std::isfinite(utcTime)) {
rval.setString(cx->names().Invalid_Date_);
@ -3093,8 +3091,8 @@ static bool FormatDate(JSContext* cx, DateTimeInfo::ForceUTC forceUTC,
// also means the time zone string may not fit into Latin-1.
// Get a time zone string from the OS or ICU to include as a comment.
timeZoneComment = DateTimeHelper::timeZoneComment(cx, forceUTC, locale,
utcTime, localTime);
timeZoneComment =
DateTimeHelper::timeZoneComment(cx, forceUTC, utcTime, localTime);
if (!timeZoneComment) {
return false;
}
@ -3144,12 +3142,9 @@ static bool FormatDate(JSContext* cx, DateTimeInfo::ForceUTC forceUTC,
}
#if !JS_HAS_INTL_API
static bool ToLocaleFormatHelper(JSContext* cx, DateObject* unwrapped,
const char* format, MutableHandleValue rval) {
DateTimeInfo::ForceUTC forceUTC = unwrapped->forceUTC();
const char* locale = unwrapped->realm()->getLocale();
double utcTime = unwrapped->UTCTime().toNumber();
static bool ToLocaleFormatHelper(JSContext* cx, DateTimeInfo::ForceUTC forceUTC,
double utcTime, const char* format,
MutableHandleValue rval) {
char buf[100];
if (!std::isfinite(utcTime)) {
strcpy(buf, "InvalidDate");
@ -3162,8 +3157,7 @@ static bool ToLocaleFormatHelper(JSContext* cx, DateObject* unwrapped,
/* If it failed, default to toString. */
if (result_len == 0) {
return FormatDate(cx, forceUTC, locale, utcTime, FormatSpec::DateTime,
rval);
return FormatDate(cx, forceUTC, utcTime, FormatSpec::DateTime, rval);
}
/* Hacked check against undesired 2-digit year 00/00/00 form. */
@ -3218,7 +3212,9 @@ static bool date_toLocaleString(JSContext* cx, unsigned argc, Value* vp) {
# endif
;
return ToLocaleFormatHelper(cx, unwrapped, format, args.rval());
return ToLocaleFormatHelper(cx, unwrapped->forceUTC(),
unwrapped->UTCTime().toNumber(), format,
args.rval());
}
static bool date_toLocaleDateString(JSContext* cx, unsigned argc, Value* vp) {
@ -3244,7 +3240,9 @@ static bool date_toLocaleDateString(JSContext* cx, unsigned argc, Value* vp) {
# endif
;
return ToLocaleFormatHelper(cx, unwrapped, format, args.rval());
return ToLocaleFormatHelper(cx, unwrapped->forceUTC(),
unwrapped->UTCTime().toNumber(), format,
args.rval());
}
static bool date_toLocaleTimeString(JSContext* cx, unsigned argc, Value* vp) {
@ -3258,7 +3256,9 @@ static bool date_toLocaleTimeString(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
return ToLocaleFormatHelper(cx, unwrapped, "%X", args.rval());
return ToLocaleFormatHelper(cx, unwrapped->forceUTC(),
unwrapped->UTCTime().toNumber(), "%X",
args.rval());
}
#endif /* !JS_HAS_INTL_API */
@ -3272,9 +3272,8 @@ static bool date_toTimeString(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
return FormatDate(cx, unwrapped->forceUTC(), unwrapped->realm()->getLocale(),
unwrapped->UTCTime().toNumber(), FormatSpec::Time,
args.rval());
return FormatDate(cx, unwrapped->forceUTC(), unwrapped->UTCTime().toNumber(),
FormatSpec::Time, args.rval());
}
static bool date_toDateString(JSContext* cx, unsigned argc, Value* vp) {
@ -3287,9 +3286,8 @@ static bool date_toDateString(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
return FormatDate(cx, unwrapped->forceUTC(), unwrapped->realm()->getLocale(),
unwrapped->UTCTime().toNumber(), FormatSpec::Date,
args.rval());
return FormatDate(cx, unwrapped->forceUTC(), unwrapped->UTCTime().toNumber(),
FormatSpec::Date, args.rval());
}
static bool date_toSource(JSContext* cx, unsigned argc, Value* vp) {
@ -3325,9 +3323,8 @@ bool date_toString(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
return FormatDate(cx, unwrapped->forceUTC(), unwrapped->realm()->getLocale(),
unwrapped->UTCTime().toNumber(), FormatSpec::DateTime,
args.rval());
return FormatDate(cx, unwrapped->forceUTC(), unwrapped->UTCTime().toNumber(),
FormatSpec::DateTime, args.rval());
}
bool js::date_valueOf(JSContext* cx, unsigned argc, Value* vp) {
@ -3483,8 +3480,8 @@ static bool NewDateObject(JSContext* cx, const CallArgs& args, ClippedTime t) {
}
static bool ToDateString(JSContext* cx, const CallArgs& args, ClippedTime t) {
return FormatDate(cx, ForceUTC(cx->realm()), cx->realm()->getLocale(),
t.toDouble(), FormatSpec::DateTime, args.rval());
return FormatDate(cx, ForceUTC(cx->realm()), t.toDouble(),
FormatSpec::DateTime, args.rval());
}
static bool DateNoArguments(JSContext* cx, const CallArgs& args) {

View File

@ -6776,9 +6776,6 @@ static bool WrapWithProto(JSContext* cx, unsigned argc, Value* vp) {
}
static bool NewGlobal(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject callee(cx, &args.callee());
JS::RealmOptions options;
JS::RealmCreationOptions& creationOptions = options.creationOptions();
JS::RealmBehaviors& behaviors = options.behaviors();
@ -6797,6 +6794,7 @@ static bool NewGlobal(JSContext* cx, unsigned argc, Value* vp) {
JS::AutoHoldPrincipals principals(cx);
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() == 1 && args[0].isObject()) {
RootedObject opts(cx, &args[0].toObject());
RootedValue v(cx);
@ -6916,18 +6914,6 @@ static bool NewGlobal(JSContext* cx, unsigned argc, Value* vp) {
if (v.isBoolean()) {
creationOptions.setAlwaysUseFdlibm(v.toBoolean());
}
if (!JS_GetProperty(cx, opts, "locale", &v)) {
return false;
}
if (v.isString()) {
RootedString str(cx, v.toString());
UniqueChars locale = StringToLocale(cx, callee, str);
if (!locale) {
return false;
}
creationOptions.setLocaleCopyZ(locale.get());
}
}
if (!CheckRealmOptions(cx, options, principals.get())) {

View File

@ -488,14 +488,6 @@ void Realm::clearScriptCounts() { zone()->clearScriptCounts(this); }
void Realm::clearScriptLCov() { zone()->clearScriptLCov(this); }
const char* Realm::getLocale() const {
if (RefPtr<LocaleString> locale = creationOptions_.locale()) {
return locale->chars();
}
return runtime_->getDefaultLocale();
}
void ObjectRealm::addSizeOfExcludingThis(
mozilla::MallocSizeOf mallocSizeOf, size_t* innerViewsArg,
size_t* objectMetadataTablesArg,

View File

@ -673,9 +673,6 @@ class JS::Realm : public JS::shadow::Realm {
bool shouldCaptureStackForThrow();
// Returns the locale for this realm. (Pointer must NOT be freed!)
const char* getLocale() const;
// Initializes randomNumberGenerator if needed.
mozilla::non_crypto::XorShift128PlusRNG& getOrCreateRandomNumberGenerator();

View File

@ -1593,7 +1593,7 @@ static bool intrinsic_RuntimeDefaultLocale(JSContext* cx, unsigned argc,
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 0);
const char* locale = cx->realm()->getLocale();
const char* locale = cx->runtime()->getDefaultLocale();
if (!locale) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_DEFAULT_LOCALE_ERROR);
@ -1622,7 +1622,7 @@ static bool intrinsic_IsRuntimeDefaultLocale(JSContext* cx, unsigned argc,
return true;
}
const char* locale = cx->realm()->getLocale();
const char* locale = cx->runtime()->getDefaultLocale();
if (!locale) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_DEFAULT_LOCALE_ERROR);

View File

@ -43,12 +43,16 @@ void XPCLocaleObserver::Init() {
mozilla::services::GetObserverService();
observerService->AddObserver(this, "intl:app-locales-changed", false);
Preferences::AddStrongObserver(this, "javascript.use_us_english_locale");
}
NS_IMETHODIMP
XPCLocaleObserver::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) {
if (!strcmp(aTopic, "intl:app-locales-changed")) {
if (!strcmp(aTopic, "intl:app-locales-changed") ||
(!strcmp(aTopic, "nsPref:changed") &&
!NS_strcmp(aData, u"javascript.use_us_english_locale"))) {
JSRuntime* rt = CycleCollectedJSRuntime::Get()->Runtime();
if (!xpc_LocalizeRuntime(rt)) {
return NS_ERROR_OUT_OF_MEMORY;
@ -125,7 +129,16 @@ bool xpc_LocalizeRuntime(JSRuntime* rt) {
JS_SetLocaleCallbacks(rt, new XPCLocaleCallbacks());
}
// Set the default locale from the regional prefs locales.
// Set the default locale.
// Check a pref to see if we should use US English locale regardless
// of the system locale.
if (Preferences::GetBool("javascript.use_us_english_locale", false)) {
return JS_SetDefaultLocale(rt, "en-US");
}
// No pref has been found, so get the default locale from the
// regional prefs locales.
AutoTArray<nsCString, 10> rpLocales;
LocaleService::GetInstance()->GetRegionalPrefsLocales(rpLocales);

View File

@ -47,7 +47,6 @@
#include "nsContentUtils.h"
#include "nsScriptError.h"
#include "nsJSUtils.h"
#include "nsRFPService.h"
#include "prsystem.h"
#include "xpcprivate.h"
@ -484,7 +483,7 @@ JSObject* CreateGlobalObject(JSContext* cx, const JSClass* clasp,
void InitGlobalObjectOptions(JS::RealmOptions& aOptions,
bool aIsSystemPrincipal, bool aForceUTC,
bool aAlwaysUseFdlibm, bool aLocaleEnUS) {
bool aAlwaysUseFdlibm) {
bool shouldDiscardSystemSource = ShouldDiscardSystemSource();
if (aIsSystemPrincipal) {
@ -497,10 +496,6 @@ void InitGlobalObjectOptions(JS::RealmOptions& aOptions,
aOptions.creationOptions().setForceUTC(aForceUTC);
aOptions.creationOptions().setAlwaysUseFdlibm(aAlwaysUseFdlibm);
if (aLocaleEnUS) {
nsCString locale = nsRFPService::GetSpoofedJSLocale();
aOptions.creationOptions().setLocaleCopyZ(locale.get());
}
if (shouldDiscardSystemSource) {
aOptions.behaviors().setDiscardSource(aIsSystemPrincipal);
@ -553,8 +548,7 @@ nsresult InitClassesWithNewWrappedGlobal(JSContext* aJSContext,
MOZ_RELEASE_ASSERT(aPrincipal->IsSystemPrincipal());
InitGlobalObjectOptions(aOptions, /* aSystemPrincipal */ true,
/* aForceUTC */ false, /* aAlwaysUseFdlibm */ false,
/* aLocaleEnUS */ false);
/* aForceUTC */ false, /* aAlwaysUseFdlibm */ false);
// Call into XPCWrappedNative to make a new global object, scope, and global
// prototype.

View File

@ -2418,7 +2418,7 @@ JSObject* CreateGlobalObject(JSContext* cx, const JSClass* clasp,
// object.)
void InitGlobalObjectOptions(JS::RealmOptions& aOptions,
bool aIsSystemPrincipal, bool aForceUTC,
bool aAlwaysUseFdlibm, bool aLocaleEnUS);
bool aAlwaysUseFdlibm);
// Finish initializing an already-created, not-yet-exposed-to-script global
// object. This will attach a Components object (if necessary) and call

View File

@ -21,7 +21,20 @@ PaintWorkletImpl* PaintWorkletGlobalScope::Impl() const {
bool PaintWorkletGlobalScope::WrapGlobalObject(
JSContext* aCx, JS::MutableHandle<JSObject*> aReflector) {
JS::RealmOptions options = CreateRealmOptions();
JS::RealmOptions options;
options.creationOptions().setForceUTC(
ShouldResistFingerprinting(RFPTarget::JSDateTimeUTC));
options.creationOptions().setAlwaysUseFdlibm(
ShouldResistFingerprinting(RFPTarget::JSMathFdlibm));
// The SharedArrayBuffer global constructor property should not be present in
// a fresh global object when shared memory objects aren't allowed (because
// COOP/COEP support isn't enabled, or because COOP/COEP don't act to isolate
// this worker to a separate process).
options.creationOptions().setDefineSharedArrayBufferConstructor(
IsSharedMemoryAllowed());
return PaintWorkletGlobalScope_Binding::Wrap(
aCx, this, this, options, nsJSPrincipals::get(mImpl->Principal()), true,
aReflector);

View File

@ -167,12 +167,18 @@ class _RFPHelper {
// Works like disabling accept-language spoofing.
// fall through
case 1: // don't spoof
if (
Services.prefs.prefHasUserValue("javascript.use_us_english_locale")
) {
Services.prefs.clearUserPref("javascript.use_us_english_locale");
}
// We don't reset intl.accept_languages. Instead, setting
// privacy.spoof_english to 1 allows user to change preferred language
// settings through Preferences UI.
break;
case 2: // spoof
Services.prefs.setCharPref("intl.accept_languages", "en-US, en");
Services.prefs.setBoolPref("javascript.use_us_english_locale", true);
break;
default:
break;

View File

@ -25,7 +25,7 @@ ITEM_VALUE(CanvasImageExtractionPrompt, 1llu << 9)
ITEM_VALUE(CanvasExtractionFromThirdPartiesIsBlocked, 1llu << 10)
ITEM_VALUE(CanvasExtractionBeforeUserInputIsBlocked, 1llu << 11)
ITEM_VALUE(JSLocale, 1llu << 12)
// UNUSED: 1llu << 12
// Various "client identification" values of the navigator object
ITEM_VALUE(NavigatorAppVersion, 1llu << 13)

View File

@ -191,9 +191,6 @@ bool nsRFPService::IsRFPEnabledFor(RFPTarget aTarget) {
if (StaticPrefs::privacy_resistFingerprinting_DoNotUseDirectly() ||
StaticPrefs::privacy_resistFingerprinting_pbmode_DoNotUseDirectly()) {
if (aTarget == RFPTarget::JSLocale) {
return StaticPrefs::privacy_spoof_english() == 2;
}
return true;
}
@ -884,9 +881,6 @@ void nsRFPService::GetSpoofedUserAgent(nsACString& userAgent,
MOZ_ASSERT(userAgent.Length() <= preallocatedLength);
}
/* static */
nsCString nsRFPService::GetSpoofedJSLocale() { return "en-US"_ns; }
// ============================================================================
// ============================================================================
// ============================================================================

View File

@ -223,12 +223,6 @@ class nsRFPService final : public nsIObserver {
// --------------------------------------------------------------------------
// This method generates the locale string (e.g. "en-US") that should be
// spoofed by the JavaScript engine.
static nsCString GetSpoofedJSLocale();
// --------------------------------------------------------------------------
/**
* This method for getting spoofed modifier states for the given keyboard
* event.

View File

@ -20,7 +20,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1486258
</pre>
<script type="text/javascript">
/* global SpecialPowers, content */
/* global SpecialPowers */
const { BrowserTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/BrowserTestUtils.sys.mjs"
@ -35,12 +35,11 @@ const kSpoofEnglish = 2;
async function runTest(locale) {
return BrowserTestUtils.withNewTab("http://example.com/", browser => {
return SpecialPowers.spawn(browser, [locale], _locale => {
let locale = JSON.stringify(_locale);
return content.eval(`({
locale: new Intl.PluralRules(${locale}).resolvedOptions().locale,
weekday: new Date(0).toLocaleString(${locale}, {weekday: "long"}),
currency: Number(1000).toLocaleString(${locale}, {currency: "USD"}),
})`);
return {
locale: new Intl.PluralRules(_locale).resolvedOptions().locale,
weekday: new Date(0).toLocaleString(_locale, {weekday: "long"}),
currency: Number(1000).toLocaleString(_locale, {currency: "USD"}),
};
});
});
}
@ -55,6 +54,10 @@ async function runSpoofTest(spoof) {
],
});
is(SpecialPowers.getBoolPref("javascript.use_us_english_locale", false),
spoof == kSpoofEnglish,
"use_us_english_locale");
let results = await runTest(undefined);
await SpecialPowers.popPrefEnv();
@ -86,11 +89,11 @@ async function clearLocale() {
let enResults = await runTest("en-US");
is(enResults.locale, "en-US", "default locale");
let deResults = await runTest("de-DE");
is(deResults.locale, "de-DE", "default locale");
let deResults = await runTest("de");
is(deResults.locale, "de", "default locale");
// 3. set system locale to German
await setupLocale("de-DE");
await setupLocale("de");
// 4. log non-spoofed results
let nonSpoofedResults = await runSpoofTest(kDoNotSpoof);

View File

@ -5440,6 +5440,8 @@ nsresult XREMain::XRE_mainRun() {
mozilla::FilePreferences::InitDirectoriesAllowlist();
mozilla::FilePreferences::InitPrefs();
OverrideDefaultLocaleIfNeeded();
nsCString userAgentLocale;
LocaleService::GetInstance()->GetAppLocaleAsBCP47(userAgentLocale);
CrashReporter::AnnotateCrashReport(
@ -6112,6 +6114,20 @@ void SetupErrorHandling(const char* progname) {
setbuf(stdout, 0);
}
// Note: This function should not be needed anymore. See Bug 818634 for details.
void OverrideDefaultLocaleIfNeeded() {
// Read pref to decide whether to override default locale with US English.
if (mozilla::Preferences::GetBool("javascript.use_us_english_locale",
false)) {
// Set the application-wide C-locale. Needed to resist fingerprinting
// of Date.toLocaleFormat(). We use the locale to "C.UTF-8" if possible,
// to avoid interfering with non-ASCII keyboard input on some Linux
// desktops. Otherwise fall back to the "C" locale, which is available on
// all platforms.
setlocale(LC_ALL, "C.UTF-8") || setlocale(LC_ALL, "C");
}
}
static bool gRunSelfAsContentProc = false;
void XRE_EnableSameExecutableForContentProc() {

View File

@ -104,6 +104,8 @@ nsresult NS_LockProfilePath(nsIFile* aPath, nsIFile* aTempPath,
void WriteConsoleLog();
void OverrideDefaultLocaleIfNeeded();
/**
* Allow exit() calls to complete. This should be done from a proper Gecko
* shutdown path. Otherwise we aim to catch improper shutdowns.

View File

@ -646,6 +646,7 @@ nsresult XRE_InitChildProcess(int aArgc, char* aArgv[],
// these...
mozilla::FilePreferences::InitDirectoriesAllowlist();
mozilla::FilePreferences::InitPrefs();
OverrideDefaultLocaleIfNeeded();
}
#if defined(MOZ_SANDBOX)