Bug 1834744 - Split up RealmBehaviors::shouldResistFingerprinting in js/src. r=spidermonkey-reviewers,jandem

Differential Revision: https://phabricator.services.mozilla.com/D179534
This commit is contained in:
Tom Schuster 2023-06-07 10:52:30 +00:00
parent 2b402cbc3b
commit ca61e81327
18 changed files with 181 additions and 181 deletions

View File

@ -153,8 +153,8 @@ class JS_PUBLIC_API TransitiveCompileOptions {
// strict-mode.
bool forceStrictMode_ = false;
// The Realm of this script is configured to resist fingerprinting.
bool shouldResistFingerprinting_ = false;
// The Realm of this script is configured to use fdlibm math library.
bool alwaysUseFdlibm_ = false;
// The context has specified that source pragmas should be parsed.
bool sourcePragmas_ = true;
@ -268,9 +268,7 @@ class JS_PUBLIC_API TransitiveCompileOptions {
// Read-only accessors for non-POD options. The proper way to set these
// depends on the derived type.
bool mutedErrors() const { return mutedErrors_; }
bool shouldResistFingerprinting() const {
return shouldResistFingerprinting_;
}
bool alwaysUseFdlibm() const { return alwaysUseFdlibm_; }
bool forceFullParse() const {
return eagerDelazificationIsOneOf<
DelazificationOption::ParseEverythingEagerly>();
@ -315,7 +313,7 @@ class JS_PUBLIC_API TransitiveCompileOptions {
PrintFields_(sourceMapURL_);
PrintFields_(mutedErrors_);
PrintFields_(forceStrictMode_);
PrintFields_(shouldResistFingerprinting_);
PrintFields_(alwaysUseFdlibm_);
PrintFields_(sourcePragmas_);
PrintFields_(skipFilenameValidation_);
PrintFields_(hideScriptFromDebugger_);

View File

@ -187,11 +187,9 @@ JS_PUBLIC_API double DayFromYear(double year);
JS_PUBLIC_API double DayWithinYear(double time, double year);
// The callback will be a wrapper function that accepts a double (the time
// to clamp and jitter) as well as a bool indicating if we should be resisting
// fingerprinting. Inside the JS Engine, other parameters that may be
// to clamp and jitter). Inside the JS Engine, other parameters that may be
// needed are all constant, so they are handled inside the wrapper function
using ReduceMicrosecondTimePrecisionCallback = double (*)(double, bool,
JSContext*);
using ReduceMicrosecondTimePrecisionCallback = double (*)(double, JSContext*);
// Set a callback into the toolkit/components/resistfingerprinting function that
// will centralize time resolution and jitter into one place.

View File

@ -259,6 +259,23 @@ class JS_PUBLIC_API RealmCreationOptions {
return *this;
}
// Force all date/time methods in JavaScript to use the UTC timezone for
// fingerprinting protection.
bool forceUTC() const { return forceUTC_; }
RealmCreationOptions& setForceUTC(bool flag) {
forceUTC_ = flag;
return *this;
}
// Always use the fdlibm implementation of math functions instead of the
// platform native libc implementations. Useful for fingerprinting protection
// and cross-platform consistency.
bool alwaysUseFdlibm() const { return alwaysUseFdlibm_; }
RealmCreationOptions& setAlwaysUseFdlibm(bool flag) {
alwaysUseFdlibm_ = flag;
return *this;
}
uint64_t profilerRealmID() const { return profilerRealmID_; }
RealmCreationOptions& setProfilerRealmID(uint64_t id) {
profilerRealmID_ = id;
@ -295,6 +312,8 @@ class JS_PUBLIC_API RealmCreationOptions {
#endif
bool secureContext_ = false;
bool freezeBuiltins_ = false;
bool forceUTC_ = false;
bool alwaysUseFdlibm_ = false;
};
/**
@ -319,14 +338,6 @@ class JS_PUBLIC_API RealmBehaviors {
return *this;
}
bool shouldResistFingerprinting() const {
return shouldResistFingerprinting_;
}
RealmBehaviors& setShouldResistFingerprinting(bool flag) {
shouldResistFingerprinting_ = flag;
return *this;
}
class Override {
public:
Override() : mode_(Default) {}
@ -362,7 +373,6 @@ class JS_PUBLIC_API RealmBehaviors {
private:
bool discardSource_ = false;
bool clampAndJitterTime_ = true;
bool shouldResistFingerprinting_ = false;
bool isNonLive_ = false;
};

View File

@ -8360,7 +8360,7 @@ static bool GetICUOptions(JSContext* cx, unsigned argc, Value* vp) {
intl::FormatBuffer<char16_t, intl::INITIAL_CHAR_BUFFER_SIZE> buf(cx);
if (auto ok = DateTimeInfo::timeZoneId(DateTimeInfo::ShouldRFP::No, buf);
if (auto ok = DateTimeInfo::timeZoneId(DateTimeInfo::ForceUTC::No, buf);
ok.isErr()) {
intl::ReportInternalError(cx, ok.unwrapErr());
return false;

View File

@ -404,7 +404,7 @@ bool js::intl_defaultTimeZone(JSContext* cx, unsigned argc, Value* vp) {
FormatBuffer<char16_t, intl::INITIAL_CHAR_BUFFER_SIZE> timeZone(cx);
auto result =
DateTimeInfo::timeZoneId(DateTimeInfo::shouldRFP(cx->realm()), timeZone);
DateTimeInfo::timeZoneId(DateTimeInfo::forceUTC(cx->realm()), timeZone);
if (result.isErr()) {
intl::ReportInternalError(cx, result.unwrapErr());
return false;
@ -424,7 +424,7 @@ bool js::intl_defaultTimeZoneOffset(JSContext* cx, unsigned argc, Value* vp) {
MOZ_ASSERT(args.length() == 0);
auto offset =
DateTimeInfo::getRawOffsetMs(DateTimeInfo::shouldRFP(cx->realm()));
DateTimeInfo::getRawOffsetMs(DateTimeInfo::forceUTC(cx->realm()));
if (offset.isErr()) {
intl::ReportInternalError(cx, offset.unwrapErr());
return false;
@ -448,7 +448,7 @@ bool js::intl_isDefaultTimeZone(JSContext* cx, unsigned argc, Value* vp) {
FormatBuffer<char16_t, intl::INITIAL_CHAR_BUFFER_SIZE> chars(cx);
auto result =
DateTimeInfo::timeZoneId(DateTimeInfo::shouldRFP(cx->realm()), chars);
DateTimeInfo::timeZoneId(DateTimeInfo::forceUTC(cx->realm()), chars);
if (result.isErr()) {
intl::ReportInternalError(cx, result.unwrapErr());
return false;

View File

@ -2,7 +2,7 @@
load(libdir + "asm.js");
var g = newGlobal({shouldResistFingerprinting: true})
var g = newGlobal({alwaysUseFdlibm: true})
var code = (fun) => {
return `(function asm(glob) {

View File

@ -1,4 +1,4 @@
let g = newGlobal({shouldResistFingerprinting: true});
let g = newGlobal({alwaysUseFdlibm: true});
// Adapted from https://github.com/arkenfox/TZP/blob/master/tests/math.html
// Tests all values that differed from libm for me on Linux and Windows.

View File

@ -13,7 +13,7 @@ let originalDT = Intl.DateTimeFormat("en-US", {
assertEq(originalDT.format(original).endsWith("Pacific Standard Time"), true);
assertEq(originalDT.resolvedOptions().timeZone, "PST8PDT");
let global = newGlobal({shouldResistFingerprinting: true});
let global = newGlobal({forceUTC: true});
let date = new global.Date();
assertEq(tzRE.exec(date.toString())[1], "Coordinated Universal Time");

View File

@ -7975,7 +7975,7 @@ AttachDecision InlinableNativeIRGenerator::tryAttachMathFunction(
}
if (math_use_fdlibm_for_sin_cos_tan() ||
callee_->realm()->behaviors().shouldResistFingerprinting()) {
callee_->realm()->creationOptions().alwaysUseFdlibm()) {
switch (fun) {
case UnaryMathFunction::SinNative:
fun = UnaryMathFunction::SinFdlibm;

View File

@ -2301,7 +2301,7 @@ void JS::TransitiveCompileOptions::copyPODTransitiveOptions(
mutedErrors_ = rhs.mutedErrors_;
forceStrictMode_ = rhs.forceStrictMode_;
shouldResistFingerprinting_ = rhs.shouldResistFingerprinting_;
alwaysUseFdlibm_ = rhs.alwaysUseFdlibm_;
sourcePragmas_ = rhs.sourcePragmas_;
skipFilenameValidation_ = rhs.skipFilenameValidation_;
hideScriptFromDebugger_ = rhs.hideScriptFromDebugger_;
@ -2427,8 +2427,7 @@ JS::CompileOptions::CompileOptions(JSContext* cx) : ReadOnlyCompileOptions() {
// Note: If we parse outside of a specific realm, we do not inherit any realm
// behaviours. These can still be set manually on the options though.
if (Realm* realm = cx->realm()) {
shouldResistFingerprinting_ =
realm->behaviors().shouldResistFingerprinting();
alwaysUseFdlibm_ = realm->creationOptions().alwaysUseFdlibm();
discardSource = realm->behaviors().discardSource();
}
}

View File

@ -138,25 +138,25 @@ namespace {
class DateTimeHelper {
private:
#if JS_HAS_INTL_API
static double localTZA(DateTimeInfo::ShouldRFP shouldRFP, double t,
static double localTZA(DateTimeInfo::ForceUTC forceUTC, double t,
DateTimeInfo::TimeZoneOffset offset);
#else
static int equivalentYearForDST(int year);
static bool isRepresentableAsTime32(double t);
static double daylightSavingTA(DateTimeInfo::ShouldRFP shouldRFP, double t);
static double adjustTime(DateTimeInfo::ShouldRFP shouldRFP, double date);
static PRMJTime toPRMJTime(DateTimeInfo::ShouldRFP shouldRFP,
double localTime, double utcTime);
static double daylightSavingTA(DateTimeInfo::ForceUTC forceUTC, double t);
static double adjustTime(DateTimeInfo::ForceUTC forceUTC, double date);
static PRMJTime toPRMJTime(DateTimeInfo::ForceUTC forceUTC, double localTime,
double utcTime);
#endif
public:
static double localTime(DateTimeInfo::ShouldRFP shouldRFP, double t);
static double UTC(DateTimeInfo::ShouldRFP shouldRFP, double t);
static double localTime(DateTimeInfo::ForceUTC forceUTC, double t);
static double UTC(DateTimeInfo::ForceUTC forceUTC, double t);
static JSString* timeZoneComment(JSContext* cx,
DateTimeInfo::ShouldRFP shouldRFP,
DateTimeInfo::ForceUTC forceUTC,
double utcTime, double localTime);
#if !JS_HAS_INTL_API
static size_t formatTime(DateTimeInfo::ShouldRFP shouldRFP, char* buf,
static size_t formatTime(DateTimeInfo::ForceUTC forceUTC, char* buf,
size_t buflen, const char* fmt, double utcTime,
double localTime);
#endif
@ -164,10 +164,9 @@ class DateTimeHelper {
} // namespace
static DateTimeInfo::ShouldRFP ShouldRFP(const Realm* realm) {
return realm->behaviors().shouldResistFingerprinting()
? DateTimeInfo::ShouldRFP::Yes
: DateTimeInfo::ShouldRFP::No;
static DateTimeInfo::ForceUTC ForceUTC(const Realm* realm) {
return realm->creationOptions().forceUTC() ? DateTimeInfo::ForceUTC::Yes
: DateTimeInfo::ForceUTC::No;
}
// ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557
@ -460,30 +459,30 @@ JS_PUBLIC_API void JS::SetTimeResolutionUsec(uint32_t resolution, bool jitter) {
#if JS_HAS_INTL_API
// ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557
// 20.3.1.7 LocalTZA ( t, isUTC )
double DateTimeHelper::localTZA(DateTimeInfo::ShouldRFP shouldRFP, double t,
double DateTimeHelper::localTZA(DateTimeInfo::ForceUTC forceUTC, double t,
DateTimeInfo::TimeZoneOffset offset) {
MOZ_ASSERT(std::isfinite(t));
int64_t milliseconds = static_cast<int64_t>(t);
int32_t offsetMilliseconds =
DateTimeInfo::getOffsetMilliseconds(shouldRFP, milliseconds, offset);
DateTimeInfo::getOffsetMilliseconds(forceUTC, milliseconds, offset);
return static_cast<double>(offsetMilliseconds);
}
// ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557
// 20.3.1.8 LocalTime ( t )
double DateTimeHelper::localTime(DateTimeInfo::ShouldRFP shouldRFP, double t) {
double DateTimeHelper::localTime(DateTimeInfo::ForceUTC forceUTC, double t) {
if (!std::isfinite(t)) {
return GenericNaN();
}
MOZ_ASSERT(StartOfTime <= t && t <= EndOfTime);
return t + localTZA(shouldRFP, t, DateTimeInfo::TimeZoneOffset::UTC);
return t + localTZA(forceUTC, t, DateTimeInfo::TimeZoneOffset::UTC);
}
// ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557
// 20.3.1.9 UTC ( t )
double DateTimeHelper::UTC(DateTimeInfo::ShouldRFP shouldRFP, double t) {
double DateTimeHelper::UTC(DateTimeInfo::ForceUTC forceUTC, double t) {
if (!std::isfinite(t)) {
return GenericNaN();
}
@ -492,7 +491,7 @@ double DateTimeHelper::UTC(DateTimeInfo::ShouldRFP shouldRFP, double t) {
return GenericNaN();
}
return t - localTZA(shouldRFP, t, DateTimeInfo::TimeZoneOffset::Local);
return t - localTZA(forceUTC, t, DateTimeInfo::TimeZoneOffset::Local);
}
#else
/*
@ -539,7 +538,7 @@ bool DateTimeHelper::isRepresentableAsTime32(double t) {
}
/* ES5 15.9.1.8. */
double DateTimeHelper::daylightSavingTA(DateTimeInfo::ShouldRFP shouldRFP,
double DateTimeHelper::daylightSavingTA(DateTimeInfo::ForceUTC forceUTC,
double t) {
if (!std::isfinite(t)) {
return GenericNaN();
@ -557,24 +556,24 @@ double DateTimeHelper::daylightSavingTA(DateTimeInfo::ShouldRFP shouldRFP,
int64_t utcMilliseconds = static_cast<int64_t>(t);
int32_t offsetMilliseconds =
DateTimeInfo::getDSTOffsetMilliseconds(shouldRFP, utcMilliseconds);
DateTimeInfo::getDSTOffsetMilliseconds(forceUTC, utcMilliseconds);
return static_cast<double>(offsetMilliseconds);
}
double DateTimeHelper::adjustTime(DateTimeInfo::ShouldRFP shouldRFP,
double DateTimeHelper::adjustTime(DateTimeInfo::ForceUTC forceUTC,
double date) {
double localTZA = DateTimeInfo::localTZA(shouldRFP);
double t = daylightSavingTA(shouldRFP, date) + localTZA;
double localTZA = DateTimeInfo::localTZA(forceUTC);
double t = daylightSavingTA(forceUTC, date) + localTZA;
t = (localTZA >= 0) ? fmod(t, msPerDay) : -fmod(msPerDay - t, msPerDay);
return t;
}
/* ES5 15.9.1.9. */
double DateTimeHelper::localTime(DateTimeInfo::ShouldRFP shouldRFP, double t) {
return t + adjustTime(shouldRFP, t);
double DateTimeHelper::localTime(DateTimeInfo::ForceUTC forceUTC, double t) {
return t + adjustTime(forceUTC, t);
}
double DateTimeHelper::UTC(DateTimeInfo::ShouldRFP shouldRFP, double t) {
double DateTimeHelper::UTC(DateTimeInfo::ForceUTC forceUTC, double t) {
// Following the ES2017 specification creates undesirable results at DST
// transitions. For example when transitioning from PST to PDT,
// |new Date(2016,2,13,2,0,0).toTimeString()| returns the string value
@ -582,17 +581,17 @@ double DateTimeHelper::UTC(DateTimeInfo::ShouldRFP shouldRFP, double t) {
// V8 and subtract one hour before computing the offset.
// Spec bug: https://bugs.ecmascript.org/show_bug.cgi?id=4007
return t - adjustTime(shouldRFP,
t - DateTimeInfo::localTZA(shouldRFP) - msPerHour);
return t -
adjustTime(forceUTC, t - DateTimeInfo::localTZA(forceUTC) - msPerHour);
}
#endif /* JS_HAS_INTL_API */
static double LocalTime(DateTimeInfo::ShouldRFP shouldRFP, double t) {
return DateTimeHelper::localTime(shouldRFP, t);
static double LocalTime(DateTimeInfo::ForceUTC forceUTC, double t) {
return DateTimeHelper::localTime(forceUTC, t);
}
static double UTC(DateTimeInfo::ShouldRFP shouldRFP, double t) {
return DateTimeHelper::UTC(shouldRFP, t);
static double UTC(DateTimeInfo::ForceUTC forceUTC, double t) {
return DateTimeHelper::UTC(forceUTC, t);
}
/* ES5 15.9.1.10. */
@ -883,7 +882,7 @@ static int DaysInMonth(int year, int month) {
* TZD = time zone designator (Z or +hh:mm or -hh:mm or missing for local)
*/
template <typename CharT>
static bool ParseISOStyleDate(DateTimeInfo::ShouldRFP shouldRFP, const CharT* s,
static bool ParseISOStyleDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
size_t length, ClippedTime* result) {
size_t i = 0;
size_t pre = 0;
@ -1033,7 +1032,7 @@ done:
MakeTime(hour, min, sec, frac * 1000.0));
if (isLocalTime) {
msec = UTC(shouldRFP, msec);
msec = UTC(forceUTC, msec);
} else {
msec -= tzMul * (tzHour * msPerHour + tzMin * msPerMinute);
}
@ -1224,9 +1223,9 @@ constexpr size_t MinKeywordLength(const CharsAndAction (&keywords)[N]) {
}
template <typename CharT>
static bool ParseDate(DateTimeInfo::ShouldRFP shouldRFP, const CharT* s,
static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
size_t length, ClippedTime* result) {
if (ParseISOStyleDate(shouldRFP, s, length, result)) {
if (ParseISOStyleDate(forceUTC, s, length, result)) {
return true;
}
@ -1619,7 +1618,7 @@ static bool ParseDate(DateTimeInfo::ShouldRFP shouldRFP, const CharT* s,
double msec = MakeDate(MakeDay(year, mon, mday), MakeTime(hour, min, sec, 0));
if (tzOffset == -1) { /* no time zone specified, have to use local */
msec = UTC(shouldRFP, msec);
msec = UTC(forceUTC, msec);
} else {
msec += tzOffset * msPerMinute;
}
@ -1628,12 +1627,12 @@ static bool ParseDate(DateTimeInfo::ShouldRFP shouldRFP, const CharT* s,
return true;
}
static bool ParseDate(DateTimeInfo::ShouldRFP shouldRFP, JSLinearString* s,
static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, JSLinearString* s,
ClippedTime* result) {
AutoCheckCannotGC nogc;
return s->hasLatin1Chars()
? ParseDate(shouldRFP, s->latin1Chars(nogc), s->length(), result)
: ParseDate(shouldRFP, s->twoByteChars(nogc), s->length(), result);
? ParseDate(forceUTC, s->latin1Chars(nogc), s->length(), result)
: ParseDate(forceUTC, s->twoByteChars(nogc), s->length(), result);
}
static bool date_parse(JSContext* cx, unsigned argc, Value* vp) {
@ -1655,7 +1654,7 @@ static bool date_parse(JSContext* cx, unsigned argc, Value* vp) {
}
ClippedTime result;
if (!ParseDate(ShouldRFP(cx->realm()), linearStr, &result)) {
if (!ParseDate(ForceUTC(cx->realm()), linearStr, &result)) {
args.rval().setNaN();
return true;
}
@ -1671,11 +1670,8 @@ static ClippedTime NowAsMillis(JSContext* cx) {
double now = PRMJ_Now();
bool clampAndJitter = cx->realm()->behaviors().clampAndJitterTime();
bool shouldResistFingerprinting =
cx->realm()->behaviors().shouldResistFingerprinting();
if (clampAndJitter && sReduceMicrosecondTimePrecisionCallback) {
now = sReduceMicrosecondTimePrecisionCallback(
now, shouldResistFingerprinting, cx);
now = sReduceMicrosecondTimePrecisionCallback(now, cx);
} else if (clampAndJitter && sResolutionUsec) {
double clamped = floor(now / sResolutionUsec) * sResolutionUsec;
@ -1719,8 +1715,8 @@ bool js::date_now(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
DateTimeInfo::ShouldRFP DateObject::shouldRFP() const {
return ShouldRFP(realm());
DateTimeInfo::ForceUTC DateObject::forceUTC() const {
return ForceUTC(realm());
}
void DateObject::setUTCTime(ClippedTime t) {
@ -1738,7 +1734,7 @@ void DateObject::setUTCTime(ClippedTime t, MutableHandleValue vp) {
void DateObject::fillLocalTimeSlots() {
const int32_t utcTZOffset =
DateTimeInfo::utcToLocalStandardOffsetSeconds(shouldRFP());
DateTimeInfo::utcToLocalStandardOffsetSeconds(forceUTC());
/* Check if the cache is already populated. */
if (!getReservedSlot(LOCAL_TIME_SLOT).isUndefined() &&
@ -1758,7 +1754,7 @@ void DateObject::fillLocalTimeSlots() {
return;
}
double localTime = LocalTime(shouldRFP(), utcTime);
double localTime = LocalTime(forceUTC(), utcTime);
setReservedSlot(LOCAL_TIME_SLOT, DoubleValue(localTime));
@ -2261,7 +2257,7 @@ static bool date_setMilliseconds(JSContext* cx, unsigned argc, Value* vp) {
if (!unwrapped) {
return false;
}
double t = LocalTime(unwrapped->shouldRFP(), unwrapped->UTCTime().toNumber());
double t = LocalTime(unwrapped->forceUTC(), unwrapped->UTCTime().toNumber());
// Step 2.
double ms;
@ -2273,7 +2269,7 @@ static bool date_setMilliseconds(JSContext* cx, unsigned argc, Value* vp) {
double time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms);
// Step 4.
ClippedTime u = TimeClip(UTC(unwrapped->shouldRFP(), MakeDate(Day(t), time)));
ClippedTime u = TimeClip(UTC(unwrapped->forceUTC(), MakeDate(Day(t), time)));
// Steps 5-6.
unwrapped->setUTCTime(u, args.rval());
@ -2320,7 +2316,7 @@ static bool date_setSeconds(JSContext* cx, unsigned argc, Value* vp) {
}
// Steps 1-2.
double t = LocalTime(unwrapped->shouldRFP(), unwrapped->UTCTime().toNumber());
double t = LocalTime(unwrapped->forceUTC(), unwrapped->UTCTime().toNumber());
// Steps 3-4.
double s;
@ -2339,7 +2335,7 @@ static bool date_setSeconds(JSContext* cx, unsigned argc, Value* vp) {
MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli));
// Step 8.
ClippedTime u = TimeClip(UTC(unwrapped->shouldRFP(), date));
ClippedTime u = TimeClip(UTC(unwrapped->forceUTC(), date));
// Step 9.
unwrapped->setUTCTime(u, args.rval());
@ -2394,7 +2390,7 @@ static bool date_setMinutes(JSContext* cx, unsigned argc, Value* vp) {
}
// Steps 1-2.
double t = LocalTime(unwrapped->shouldRFP(), unwrapped->UTCTime().toNumber());
double t = LocalTime(unwrapped->forceUTC(), unwrapped->UTCTime().toNumber());
// Steps 3-4.
double m;
@ -2418,7 +2414,7 @@ static bool date_setMinutes(JSContext* cx, unsigned argc, Value* vp) {
double date = MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli));
// Step 10.
ClippedTime u = TimeClip(UTC(unwrapped->shouldRFP(), date));
ClippedTime u = TimeClip(UTC(unwrapped->forceUTC(), date));
// Steps 11-12.
unwrapped->setUTCTime(u, args.rval());
@ -2478,7 +2474,7 @@ static bool date_setHours(JSContext* cx, unsigned argc, Value* vp) {
}
// Steps 1-2.
double t = LocalTime(unwrapped->shouldRFP(), unwrapped->UTCTime().toNumber());
double t = LocalTime(unwrapped->forceUTC(), unwrapped->UTCTime().toNumber());
// Steps 3-4.
double h;
@ -2508,7 +2504,7 @@ static bool date_setHours(JSContext* cx, unsigned argc, Value* vp) {
double date = MakeDate(Day(t), MakeTime(h, m, s, milli));
// Step 12.
ClippedTime u = TimeClip(UTC(unwrapped->shouldRFP(), date));
ClippedTime u = TimeClip(UTC(unwrapped->forceUTC(), date));
// Steps 13-14.
unwrapped->setUTCTime(u, args.rval());
@ -2574,7 +2570,7 @@ static bool date_setDate(JSContext* cx, unsigned argc, Value* vp) {
}
/* Step 1. */
double t = LocalTime(unwrapped->shouldRFP(), unwrapped->UTCTime().toNumber());
double t = LocalTime(unwrapped->forceUTC(), unwrapped->UTCTime().toNumber());
/* Step 2. */
double date;
@ -2587,7 +2583,7 @@ static bool date_setDate(JSContext* cx, unsigned argc, Value* vp) {
TimeWithinDay(t));
/* Step 4. */
ClippedTime u = TimeClip(UTC(unwrapped->shouldRFP(), newDate));
ClippedTime u = TimeClip(UTC(unwrapped->forceUTC(), newDate));
/* Steps 5-6. */
unwrapped->setUTCTime(u, args.rval());
@ -2653,7 +2649,7 @@ static bool date_setMonth(JSContext* cx, unsigned argc, Value* vp) {
}
/* Step 1. */
double t = LocalTime(unwrapped->shouldRFP(), unwrapped->UTCTime().toNumber());
double t = LocalTime(unwrapped->forceUTC(), unwrapped->UTCTime().toNumber());
/* Step 2. */
double m;
@ -2672,7 +2668,7 @@ static bool date_setMonth(JSContext* cx, unsigned argc, Value* vp) {
MakeDate(MakeDay(YearFromTime(t), m, date), TimeWithinDay(t));
/* Step 5. */
ClippedTime u = TimeClip(UTC(unwrapped->shouldRFP(), newDate));
ClippedTime u = TimeClip(UTC(unwrapped->forceUTC(), newDate));
/* Steps 6-7. */
unwrapped->setUTCTime(u, args.rval());
@ -2716,13 +2712,13 @@ static bool date_setUTCMonth(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
static double ThisLocalTimeOrZero(DateTimeInfo::ShouldRFP shouldRFP,
static double ThisLocalTimeOrZero(DateTimeInfo::ForceUTC forceUTC,
Handle<DateObject*> dateObj) {
double t = dateObj->UTCTime().toNumber();
if (std::isnan(t)) {
return +0;
}
return LocalTime(shouldRFP, t);
return LocalTime(forceUTC, t);
}
static double ThisUTCTimeOrZero(Handle<DateObject*> dateObj) {
@ -2741,7 +2737,7 @@ static bool date_setFullYear(JSContext* cx, unsigned argc, Value* vp) {
}
/* Step 1. */
double t = ThisLocalTimeOrZero(unwrapped->shouldRFP(), unwrapped);
double t = ThisLocalTimeOrZero(unwrapped->forceUTC(), unwrapped);
/* Step 2. */
double y;
@ -2765,7 +2761,7 @@ static bool date_setFullYear(JSContext* cx, unsigned argc, Value* vp) {
double newDate = MakeDate(MakeDay(y, m, date), TimeWithinDay(t));
/* Step 6. */
ClippedTime u = TimeClip(UTC(unwrapped->shouldRFP(), newDate));
ClippedTime u = TimeClip(UTC(unwrapped->forceUTC(), newDate));
/* Steps 7-8. */
unwrapped->setUTCTime(u, args.rval());
@ -2825,7 +2821,7 @@ static bool date_setYear(JSContext* cx, unsigned argc, Value* vp) {
}
/* Step 1. */
double t = ThisLocalTimeOrZero(unwrapped->shouldRFP(), unwrapped);
double t = ThisLocalTimeOrZero(unwrapped->forceUTC(), unwrapped);
/* Step 2. */
double y;
@ -2849,7 +2845,7 @@ static bool date_setYear(JSContext* cx, unsigned argc, Value* vp) {
double day = MakeDay(yint, MonthFromTime(t), DateFromTime(t));
/* Step 6. */
double u = UTC(unwrapped->shouldRFP(), MakeDate(day, TimeWithinDay(t)));
double u = UTC(unwrapped->forceUTC(), MakeDate(day, TimeWithinDay(t)));
/* Steps 7-8. */
unwrapped->setUTCTime(TimeClip(u), args.rval());
@ -2977,7 +2973,7 @@ static bool date_toJSON(JSContext* cx, unsigned argc, Value* vp) {
#if JS_HAS_INTL_API
JSString* DateTimeHelper::timeZoneComment(JSContext* cx,
DateTimeInfo::ShouldRFP shouldRFP,
DateTimeInfo::ForceUTC forceUTC,
double utcTime, double localTime) {
const char* locale = cx->runtime()->getDefaultLocale();
if (!locale) {
@ -2996,7 +2992,7 @@ JSString* DateTimeHelper::timeZoneComment(JSContext* cx,
int64_t utcMilliseconds = static_cast<int64_t>(utcTime);
if (!DateTimeInfo::timeZoneDisplayName(
shouldRFP, timeZoneStart, remainingSpace, utcMilliseconds, locale)) {
forceUTC, timeZoneStart, remainingSpace, utcMilliseconds, locale)) {
JS_ReportOutOfMemory(cx);
return nullptr;
}
@ -3014,7 +3010,7 @@ JSString* DateTimeHelper::timeZoneComment(JSContext* cx,
}
#else
/* Interface to PRMJTime date struct. */
PRMJTime DateTimeHelper::toPRMJTime(DateTimeInfo::ShouldRFP shouldRFP,
PRMJTime DateTimeHelper::toPRMJTime(DateTimeInfo::ForceUTC forceUTC,
double localTime, double utcTime) {
double year = YearFromTime(localTime);
@ -3028,15 +3024,15 @@ PRMJTime DateTimeHelper::toPRMJTime(DateTimeInfo::ShouldRFP shouldRFP,
prtm.tm_wday = int8_t(WeekDay(localTime));
prtm.tm_year = year;
prtm.tm_yday = int16_t(DayWithinYear(localTime, year));
prtm.tm_isdst = (daylightSavingTA(shouldRFP, utcTime) != 0);
prtm.tm_isdst = (daylightSavingTA(forceUTC, utcTime) != 0);
return prtm;
}
size_t DateTimeHelper::formatTime(DateTimeInfo::ShouldRFP shouldRFP, char* buf,
size_t DateTimeHelper::formatTime(DateTimeInfo::ForceUTC forceUTC, char* buf,
size_t buflen, const char* fmt,
double utcTime, double localTime) {
PRMJTime prtm = toPRMJTime(shouldRFP, localTime, utcTime);
PRMJTime prtm = toPRMJTime(forceUTC, localTime, utcTime);
// If an equivalent year was used to compute the date/time components, use
// the same equivalent year to determine the time zone name and offset in
@ -3051,12 +3047,12 @@ size_t DateTimeHelper::formatTime(DateTimeInfo::ShouldRFP shouldRFP, char* buf,
}
JSString* DateTimeHelper::timeZoneComment(JSContext* cx,
DateTimeInfo::ShouldRFP shouldRFP,
DateTimeInfo::ForceUTC forceUTC,
double utcTime, double localTime) {
char tzbuf[100];
size_t tzlen =
formatTime(shouldRFP, tzbuf, sizeof tzbuf, " (%Z)", utcTime, localTime);
formatTime(forceUTC, tzbuf, sizeof tzbuf, " (%Z)", utcTime, localTime);
if (tzlen != 0) {
// Decide whether to use the resulting time zone string.
//
@ -3088,7 +3084,7 @@ JSString* DateTimeHelper::timeZoneComment(JSContext* cx,
enum class FormatSpec { DateTime, Date, Time };
static bool FormatDate(JSContext* cx, DateTimeInfo::ShouldRFP shouldRFP,
static bool FormatDate(JSContext* cx, DateTimeInfo::ForceUTC forceUTC,
double utcTime, FormatSpec format,
MutableHandleValue rval) {
if (!std::isfinite(utcTime)) {
@ -3098,7 +3094,7 @@ static bool FormatDate(JSContext* cx, DateTimeInfo::ShouldRFP shouldRFP,
MOZ_ASSERT(NumbersAreIdentical(TimeClip(utcTime).toDouble(), utcTime));
double localTime = LocalTime(shouldRFP, utcTime);
double localTime = LocalTime(forceUTC, utcTime);
int offset = 0;
RootedString timeZoneComment(cx);
@ -3126,7 +3122,7 @@ static bool FormatDate(JSContext* cx, DateTimeInfo::ShouldRFP shouldRFP,
// Get a time zone string from the OS or ICU to include as a comment.
timeZoneComment =
DateTimeHelper::timeZoneComment(cx, shouldRFP, utcTime, localTime);
DateTimeHelper::timeZoneComment(cx, forceUTC, utcTime, localTime);
if (!timeZoneComment) {
return false;
}
@ -3176,23 +3172,22 @@ static bool FormatDate(JSContext* cx, DateTimeInfo::ShouldRFP shouldRFP,
}
#if !JS_HAS_INTL_API
static bool ToLocaleFormatHelper(JSContext* cx,
DateTimeInfo::ShouldRFP shouldRFP,
static bool ToLocaleFormatHelper(JSContext* cx, DateTimeInfo::ForceUTC forceUTC,
double utcTime, const char* format,
MutableHandleValue rval) {
char buf[100];
if (!std::isfinite(utcTime)) {
strcpy(buf, js_InvalidDate_str);
} else {
double localTime = LocalTime(shouldRFP, utcTime);
double localTime = LocalTime(forceUTC, utcTime);
/* Let PRMJTime format it. */
size_t result_len = DateTimeHelper::formatTime(shouldRFP, buf, sizeof buf,
size_t result_len = DateTimeHelper::formatTime(forceUTC, buf, sizeof buf,
format, utcTime, localTime);
/* If it failed, default to toString. */
if (result_len == 0) {
return FormatDate(cx, shouldRFP, utcTime, FormatSpec::DateTime, rval);
return FormatDate(cx, forceUTC, utcTime, FormatSpec::DateTime, rval);
}
/* Hacked check against undesired 2-digit year 00/00/00 form. */
@ -3247,7 +3242,7 @@ static bool date_toLocaleString(JSContext* cx, unsigned argc, Value* vp) {
# endif
;
return ToLocaleFormatHelper(cx, unwrapped->shouldRFP(),
return ToLocaleFormatHelper(cx, unwrapped->forceUTC(),
unwrapped->UTCTime().toNumber(), format,
args.rval());
}
@ -3275,7 +3270,7 @@ static bool date_toLocaleDateString(JSContext* cx, unsigned argc, Value* vp) {
# endif
;
return ToLocaleFormatHelper(cx, unwrapped->shouldRFP(),
return ToLocaleFormatHelper(cx, unwrapped->forceUTC(),
unwrapped->UTCTime().toNumber(), format,
args.rval());
}
@ -3291,7 +3286,7 @@ static bool date_toLocaleTimeString(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
return ToLocaleFormatHelper(cx, unwrapped->shouldRFP(),
return ToLocaleFormatHelper(cx, unwrapped->forceUTC(),
unwrapped->UTCTime().toNumber(), "%X",
args.rval());
}
@ -3307,7 +3302,7 @@ static bool date_toTimeString(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
return FormatDate(cx, unwrapped->shouldRFP(), unwrapped->UTCTime().toNumber(),
return FormatDate(cx, unwrapped->forceUTC(), unwrapped->UTCTime().toNumber(),
FormatSpec::Time, args.rval());
}
@ -3321,7 +3316,7 @@ static bool date_toDateString(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
return FormatDate(cx, unwrapped->shouldRFP(), unwrapped->UTCTime().toNumber(),
return FormatDate(cx, unwrapped->forceUTC(), unwrapped->UTCTime().toNumber(),
FormatSpec::Date, args.rval());
}
@ -3358,7 +3353,7 @@ bool date_toString(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
return FormatDate(cx, unwrapped->shouldRFP(), unwrapped->UTCTime().toNumber(),
return FormatDate(cx, unwrapped->forceUTC(), unwrapped->UTCTime().toNumber(),
FormatSpec::DateTime, args.rval());
}
@ -3476,7 +3471,7 @@ static bool NewDateObject(JSContext* cx, const CallArgs& args, ClippedTime t) {
}
static bool ToDateString(JSContext* cx, const CallArgs& args, ClippedTime t) {
return FormatDate(cx, ShouldRFP(cx->realm()), t.toDouble(),
return FormatDate(cx, ForceUTC(cx->realm()), t.toDouble(),
FormatSpec::DateTime, args.rval());
}
@ -3525,7 +3520,7 @@ static bool DateOneArgument(JSContext* cx, const CallArgs& args) {
return false;
}
if (!ParseDate(ShouldRFP(cx->realm()), linearStr, &t)) {
if (!ParseDate(ForceUTC(cx->realm()), linearStr, &t)) {
t = ClippedTime::invalid();
}
} else {
@ -3623,7 +3618,7 @@ static bool DateMultipleArguments(JSContext* cx, const CallArgs& args) {
// Steps 3q-t.
return NewDateObject(cx, args,
TimeClip(UTC(ShouldRFP(cx->realm()), finalDate)));
TimeClip(UTC(ForceUTC(cx->realm()), finalDate)));
}
return ToDateString(cx, args, NowAsMillis(cx));
@ -3699,8 +3694,7 @@ JS_PUBLIC_API JSObject* js::NewDateObject(JSContext* cx, int year, int mon,
MOZ_ASSERT(mon < 12);
double msec_time =
MakeDate(MakeDay(year, mon, mday), MakeTime(hour, min, sec, 0.0));
return NewDateObjectMsec(cx,
TimeClip(UTC(ShouldRFP(cx->realm()), msec_time)));
return NewDateObjectMsec(cx, TimeClip(UTC(ForceUTC(cx->realm()), msec_time)));
}
JS_PUBLIC_API bool js::DateIsValid(JSContext* cx, HandleObject obj,

View File

@ -58,7 +58,7 @@ bool js::math_use_fdlibm_for_sin_cos_tan() { return sUseFdlibmForSinCosTan; }
static inline bool UseFdlibmForSinCosTan(const CallArgs& args) {
return sUseFdlibmForSinCosTan ||
args.callee().nonCCWRealm()->behaviors().shouldResistFingerprinting();
args.callee().nonCCWRealm()->creationOptions().alwaysUseFdlibm();
}
template <UnaryMathFunctionType F>

View File

@ -6641,11 +6641,18 @@ static bool NewGlobal(JSContext* cx, unsigned argc, Value* vp) {
creationOptions.setDefineSharedArrayBufferConstructor(v.toBoolean());
}
if (!JS_GetProperty(cx, opts, "shouldResistFingerprinting", &v)) {
if (!JS_GetProperty(cx, opts, "forceUTC", &v)) {
return false;
}
if (v.isBoolean()) {
behaviors.setShouldResistFingerprinting(v.toBoolean());
creationOptions.setForceUTC(v.toBoolean());
}
if (!JS_GetProperty(cx, opts, "alwaysUseFdlibm", &v)) {
return false;
}
if (v.isBoolean()) {
creationOptions.setAlwaysUseFdlibm(v.toBoolean());
}
}

View File

@ -57,7 +57,7 @@ class DateObject : public NativeObject {
static const JSClass class_;
static const JSClass protoClass_;
js::DateTimeInfo::ShouldRFP shouldRFP() const;
js::DateTimeInfo::ForceUTC forceUTC() const;
JS::ClippedTime clippedTime() const {
double t = getFixedSlot(UTC_TIME_SLOT).toDouble();

View File

@ -38,10 +38,9 @@
#include "vm/Realm.h"
/* static */
js::DateTimeInfo::ShouldRFP js::DateTimeInfo::shouldRFP(JS::Realm* realm) {
return realm->behaviors().shouldResistFingerprinting()
? DateTimeInfo::ShouldRFP::Yes
: DateTimeInfo::ShouldRFP::No;
js::DateTimeInfo::ForceUTC js::DateTimeInfo::forceUTC(JS::Realm* realm) {
return realm->creationOptions().forceUTC() ? DateTimeInfo::ForceUTC::Yes
: DateTimeInfo::ForceUTC::No;
}
static bool ComputeLocalTime(time_t local, struct tm* ptm) {
@ -233,8 +232,7 @@ void js::DateTimeInfo::updateTimeZone() {
}
}
js::DateTimeInfo::DateTimeInfo(bool shouldResistFingerprinting)
: shouldResistFingerprinting_(shouldResistFingerprinting) {
js::DateTimeInfo::DateTimeInfo(bool forceUTC) : forceUTC_(forceUTC) {
// Set the time zone status into the invalid state, so we compute the actual
// defaults on first access. We don't yet want to initialize neither <ctime>
// nor ICU's time zone classes, because that may cause I/O operations slowing
@ -486,7 +484,7 @@ mozilla::intl::TimeZone* js::DateTimeInfo::timeZone() {
if (!timeZone_) {
// For resist finger printing mode we always use the UTC time zone.
mozilla::Maybe<mozilla::Span<const char16_t>> timeZoneOverride;
if (shouldResistFingerprinting_) {
if (forceUTC_) {
timeZoneOverride = mozilla::Some(mozilla::MakeStringSpan(u"UTC"));
}
@ -506,17 +504,17 @@ mozilla::intl::TimeZone* js::DateTimeInfo::timeZone() {
#endif /* JS_HAS_INTL_API */
/* static */ js::ExclusiveData<js::DateTimeInfo>* js::DateTimeInfo::instance;
/* static */ js::ExclusiveData<js::DateTimeInfo>* js::DateTimeInfo::instanceRFP;
/* static */ js::ExclusiveData<js::DateTimeInfo>* js::DateTimeInfo::instanceUTC;
bool js::InitDateTimeState() {
MOZ_ASSERT(!DateTimeInfo::instance && !DateTimeInfo::instanceRFP,
MOZ_ASSERT(!DateTimeInfo::instance && !DateTimeInfo::instanceUTC,
"we should be initializing only once");
DateTimeInfo::instance =
js_new<ExclusiveData<DateTimeInfo>>(mutexid::DateTimeInfoMutex, false);
DateTimeInfo::instanceRFP =
DateTimeInfo::instanceUTC =
js_new<ExclusiveData<DateTimeInfo>>(mutexid::DateTimeInfoMutex, true);
return DateTimeInfo::instance && DateTimeInfo::instanceRFP;
return DateTimeInfo::instance && DateTimeInfo::instanceUTC;
}
/* static */
@ -755,7 +753,7 @@ void js::DateTimeInfo::internalResyncICUDefaultTimeZone() {
// instance depending on the resist fingerprinting status. For now we return
// early to prevent overwriting the default time zone with the UTC time zone
// used by RFP.
if (shouldResistFingerprinting_) {
if (forceUTC_) {
return;
}

View File

@ -113,25 +113,25 @@ extern void ResetTimeZoneInternal(ResetTimeZoneMode mode);
*/
class DateTimeInfo {
public:
// Whether we should resist fingerprinting. For realms in RFP mode a separate
// DateTimeInfo instance is used that is always in the UTC time zone.
enum class ShouldRFP { No, Yes };
// For realms that force the UTC time zone (for fingerprinting protection) a
// separate DateTimeInfo instance is used that is always in the UTC time zone.
enum class ForceUTC { No, Yes };
private:
static ExclusiveData<DateTimeInfo>* instance;
static ExclusiveData<DateTimeInfo>* instanceRFP;
static ExclusiveData<DateTimeInfo>* instanceUTC;
friend class ExclusiveData<DateTimeInfo>;
friend bool InitDateTimeState();
friend void FinishDateTimeState();
explicit DateTimeInfo(bool shouldResistFingerprinting);
explicit DateTimeInfo(bool forceUTC);
~DateTimeInfo();
static auto acquireLockWithValidTimeZone(ShouldRFP shouldRFP) {
static auto acquireLockWithValidTimeZone(ForceUTC forceUTC) {
auto guard =
shouldRFP == ShouldRFP::Yes ? instanceRFP->lock() : instance->lock();
forceUTC == ForceUTC::Yes ? instanceUTC->lock() : instance->lock();
if (guard->timeZoneStatus_ != TimeZoneStatus::Valid) {
guard->updateTimeZone();
}
@ -139,7 +139,7 @@ class DateTimeInfo {
}
public:
static ShouldRFP shouldRFP(JS::Realm* realm);
static ForceUTC forceUTC(JS::Realm* realm);
// The spec implicitly assumes DST and time zone adjustment information
// never change in the course of a function -- sometimes even across
@ -151,9 +151,9 @@ class DateTimeInfo {
* zone (Lord Howe Island, Australia) has a fractional-hour offset, just to
* keep things interesting.
*/
static int32_t getDSTOffsetMilliseconds(ShouldRFP shouldRFP,
static int32_t getDSTOffsetMilliseconds(ForceUTC forceUTC,
int64_t utcMilliseconds) {
auto guard = acquireLockWithValidTimeZone(shouldRFP);
auto guard = acquireLockWithValidTimeZone(forceUTC);
return guard->internalGetDSTOffsetMilliseconds(utcMilliseconds);
}
@ -162,8 +162,8 @@ class DateTimeInfo {
* standard time (i.e. not including any offset due to DST) as computed by the
* operating system.
*/
static int32_t utcToLocalStandardOffsetSeconds(ShouldRFP shouldRFP) {
auto guard = acquireLockWithValidTimeZone(shouldRFP);
static int32_t utcToLocalStandardOffsetSeconds(ForceUTC forceUTC) {
auto guard = acquireLockWithValidTimeZone(forceUTC);
return guard->utcToLocalStandardOffsetSeconds_;
}
@ -174,10 +174,9 @@ class DateTimeInfo {
* Return the time zone offset, including DST, in milliseconds at the
* given time. The input time can be either at UTC or at local time.
*/
static int32_t getOffsetMilliseconds(ShouldRFP shouldRFP,
int64_t milliseconds,
static int32_t getOffsetMilliseconds(ForceUTC forceUTC, int64_t milliseconds,
TimeZoneOffset offset) {
auto guard = acquireLockWithValidTimeZone(shouldRFP);
auto guard = acquireLockWithValidTimeZone(forceUTC);
return guard->internalGetOffsetMilliseconds(milliseconds, offset);
}
@ -187,10 +186,10 @@ class DateTimeInfo {
* buffer is too small, an empty string is stored. The stored display name
* is null-terminated in any case.
*/
static bool timeZoneDisplayName(ShouldRFP shouldRFP, char16_t* buf,
static bool timeZoneDisplayName(ForceUTC forceUTC, char16_t* buf,
size_t buflen, int64_t utcMilliseconds,
const char* locale) {
auto guard = acquireLockWithValidTimeZone(shouldRFP);
auto guard = acquireLockWithValidTimeZone(forceUTC);
return guard->internalTimeZoneDisplayName(buf, buflen, utcMilliseconds,
locale);
}
@ -200,8 +199,8 @@ class DateTimeInfo {
* buffer.
*/
template <typename B>
static mozilla::intl::ICUResult timeZoneId(ShouldRFP shouldRFP, B& buffer) {
auto guard = acquireLockWithValidTimeZone(shouldRFP);
static mozilla::intl::ICUResult timeZoneId(ForceUTC forceUTC, B& buffer) {
auto guard = acquireLockWithValidTimeZone(forceUTC);
return guard->timeZone()->GetId(buffer);
}
@ -209,8 +208,8 @@ class DateTimeInfo {
* A number indicating the raw offset from GMT in milliseconds.
*/
static mozilla::Result<int32_t, mozilla::intl::ICUError> getRawOffsetMs(
ShouldRFP shouldRFP) {
auto guard = acquireLockWithValidTimeZone(shouldRFP);
ForceUTC forceUTC) {
auto guard = acquireLockWithValidTimeZone(forceUTC);
return guard->timeZone()->GetRawOffsetMs();
}
#else
@ -218,8 +217,8 @@ class DateTimeInfo {
* Return the local time zone adjustment (ES2019 20.3.1.7) as computed by
* the operating system.
*/
static int32_t localTZA(ShouldRFP shouldRFP) {
return utcToLocalStandardOffsetSeconds(shouldRFP) * msPerSecond;
static int32_t localTZA(ForceUTC forceUTC) {
return utcToLocalStandardOffsetSeconds(forceUTC) * msPerSecond;
}
#endif /* JS_HAS_INTL_API */
@ -235,7 +234,7 @@ class DateTimeInfo {
{
// Only needed to initialize the default state and any later call will
// perform an unnecessary reset.
auto guard = instanceRFP->lock();
auto guard = instanceUTC->lock();
guard->internalResetTimeZone(mode);
}
}
@ -255,7 +254,7 @@ class DateTimeInfo {
void sanityCheck();
};
bool shouldResistFingerprinting_;
bool forceUTC_;
enum class TimeZoneStatus : uint8_t { Valid, NeedsUpdate, UpdateIfChanged };

View File

@ -367,7 +367,7 @@ struct js::AsmJSMetadata : Metadata, AsmJSMetadataCacheablePod {
uint32_t toStringStart;
uint32_t srcStart;
bool strict;
bool shouldResistFingerprinting = false;
bool alwaysUseFdlibm = false;
RefPtr<ScriptSource> source;
uint32_t srcEndBeforeCurly() const { return srcStart + srcLength; }
@ -1988,8 +1988,7 @@ class MOZ_STACK_CLASS ModuleValidator : public ModuleValidatorShared {
asmJSMetadata_->srcStart = moduleFunctionNode_->body()->pn_pos.begin;
asmJSMetadata_->strict = parser_.pc_->sc()->strict() &&
!parser_.pc_->sc()->hasExplicitUseStrict();
asmJSMetadata_->shouldResistFingerprinting =
parser_.options().shouldResistFingerprinting();
asmJSMetadata_->alwaysUseFdlibm = parser_.options().alwaysUseFdlibm();
asmJSMetadata_->source = do_AddRef(parser_.ss);
if (!initModuleEnvironment()) {
@ -2002,9 +2001,7 @@ class MOZ_STACK_CLASS ModuleValidator : public ModuleValidatorShared {
auto& tokenStream() const { return parser_.tokenStream; }
bool shouldResistFingerprinting() const {
return asmJSMetadata_->shouldResistFingerprinting;
}
bool alwaysUseFdlibm() const { return asmJSMetadata_->alwaysUseFdlibm; }
public:
bool addFuncDef(TaggedParserAtomIndex name, uint32_t firstUse, FuncType&& sig,
@ -4359,7 +4356,7 @@ static bool CheckMathBuiltinCall(FunctionValidator<Unit>& f,
break;
case AsmJSMathBuiltin_sin:
arity = 1;
if (!f.m().shouldResistFingerprinting()) {
if (!f.m().alwaysUseFdlibm()) {
mozf64 = MozOp::F64SinNative;
} else {
mozf64 = MozOp::F64SinFdlibm;
@ -4368,7 +4365,7 @@ static bool CheckMathBuiltinCall(FunctionValidator<Unit>& f,
break;
case AsmJSMathBuiltin_cos:
arity = 1;
if (!f.m().shouldResistFingerprinting()) {
if (!f.m().alwaysUseFdlibm()) {
mozf64 = MozOp::F64CosNative;
} else {
mozf64 = MozOp::F64CosFdlibm;
@ -4377,7 +4374,7 @@ static bool CheckMathBuiltinCall(FunctionValidator<Unit>& f,
break;
case AsmJSMathBuiltin_tan:
arity = 1;
if (!f.m().shouldResistFingerprinting()) {
if (!f.m().alwaysUseFdlibm()) {
mozf64 = MozOp::F64TanNative;
} else {
mozf64 = MozOp::F64TanFdlibm;
@ -6756,11 +6753,11 @@ static bool ValidateMathBuiltinFunction(JSContext* cx,
fun->jitInfo()->inlinableNative != native) {
return LinkFail(cx, "bad Math.* builtin function");
}
if (fun->realm()->behaviors().shouldResistFingerprinting() !=
metadata.shouldResistFingerprinting) {
if (fun->realm()->creationOptions().alwaysUseFdlibm() !=
metadata.alwaysUseFdlibm) {
return LinkFail(cx,
"Math.* builtin function and asm.js module have a "
"different resist fingerprinting mode");
"Math.* builtin function and asm.js use different native"
" math implementations.");
}
return true;

View File

@ -1936,11 +1936,11 @@ void* wasm::MaybeGetBuiltinThunk(JSFunction* f, const FuncType& funcType) {
const BuiltinThunks& thunks = *builtinThunks;
// If this function should resist fingerprinting first try to lookup
// If this function must use the fdlibm implementation first try to lookup
// the fdlibm version. If that version doesn't exist we still fallback to
// the normal native.
if (math_use_fdlibm_for_sin_cos_tan() ||
f->realm()->behaviors().shouldResistFingerprinting()) {
f->realm()->creationOptions().alwaysUseFdlibm()) {
TypedNative typedNative(f->jitInfo()->inlinableNative, *abiType,
TypedNative::FdlibmImpl::Yes);
auto p =