зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1440539 - Support time jitter in the JS Shell, and expose a function to enable it. r=luke
This adds jittering to the already existing logic for time clamping. It also exposes a testing function allowing those interested to enable time clamping or time clamping and jittering. Neither (clamping nor jittering) is enabled by default. MozReview-Commit-ID: JcHCEwRQPch --HG-- extra : amend_source : 81d9a0c425ed2549561e5b6711f4c654614b1f38
This commit is contained in:
Родитель
5345bfb157
Коммит
e120c89f6d
|
@ -4939,6 +4939,33 @@ IsLegacyIterator(JSContext* cx, unsigned argc, Value* vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
SetTimeResolution(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
RootedObject callee(cx, &args.callee());
|
||||
|
||||
if (!args.requireAtLeast(cx, "setTimeResolution", 2))
|
||||
return false;
|
||||
|
||||
if (!args[0].isInt32()) {
|
||||
ReportUsageErrorASCII(cx, callee, "First argument must be an Int32.");
|
||||
return false;
|
||||
}
|
||||
int32_t resolution = args[0].toInt32();
|
||||
|
||||
if (!args[1].isBoolean()) {
|
||||
ReportUsageErrorASCII(cx, callee, "Second argument must be a Boolean");
|
||||
return false;
|
||||
}
|
||||
bool jitter = args[1].toBoolean();
|
||||
|
||||
JS::SetTimeResolutionUsec(resolution, jitter);
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
EnableExpressionClosures(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
|
@ -5705,6 +5732,11 @@ gc::ZealModeHelpText),
|
|||
"getTimeZone()",
|
||||
" Get the current time zone.\n"),
|
||||
|
||||
JS_FN_HELP("setTimeResolution", SetTimeResolution, 2, 0,
|
||||
"setTimeResolution(resolution, jitter)",
|
||||
" Enables time clamping and jittering. Specify a time resolution in\n"
|
||||
" microseconds and whether or not to jitter\n"),
|
||||
|
||||
JS_FN_HELP("enableExpressionClosures", EnableExpressionClosures, 0, 0,
|
||||
"enableExpressionClosures()",
|
||||
" Enables the deprecated, non-standard expression closures.\n"),
|
||||
|
|
|
@ -1310,8 +1310,37 @@ NowAsMillis()
|
|||
double now = PRMJ_Now();
|
||||
if (sReduceMicrosecondTimePrecisionCallback)
|
||||
now = sReduceMicrosecondTimePrecisionCallback(now);
|
||||
else if (sResolutionUsec)
|
||||
now = floor(now / sResolutionUsec) * sResolutionUsec;
|
||||
else if (sResolutionUsec) {
|
||||
double clamped = floor(now / sResolutionUsec) * sResolutionUsec;
|
||||
|
||||
if (sJitter) {
|
||||
// Calculate a random midpoint for jittering. In the browser, we are adversarial:
|
||||
// Web Content may try to calculate the midpoint themselves and use that to bypass
|
||||
// it's security. In the JS Shell, we are not adversarial, we want to jitter the
|
||||
// time to recreate the operating environment, but we do not concern ourselves
|
||||
// with trying to prevent an attacker from calculating the midpoint themselves.
|
||||
// So we use a very simple, very fast CRC with a hardcoded seed.
|
||||
|
||||
uint64_t midpoint = *((uint64_t*)&clamped);
|
||||
midpoint ^= 0x0F00DD1E2BAD2DED; // XOR in a 'secret'
|
||||
// MurmurHash3 internal component from
|
||||
// https://searchfox.org/mozilla-central/rev/61d400da1c692453c2dc2c1cf37b616ce13dea5b/dom/canvas/MurmurHash3.cpp#85
|
||||
midpoint ^= midpoint >> 33;
|
||||
midpoint *= uint64_t{0xFF51AFD7ED558CCD};
|
||||
midpoint ^= midpoint >> 33;
|
||||
midpoint *= uint64_t{0xC4CEB9FE1A85EC53};
|
||||
midpoint ^= midpoint >> 33;
|
||||
midpoint %= sResolutionUsec;
|
||||
|
||||
if (now > clamped + midpoint) { // We're jittering up to the next step
|
||||
now = clamped + sResolutionUsec;
|
||||
} else { // We're staying at the clamped value
|
||||
now = clamped;
|
||||
}
|
||||
} else { //No jitter, only clamping
|
||||
now = clamped;
|
||||
}
|
||||
}
|
||||
|
||||
return TimeClip(now / PRMJ_USEC_PER_MSEC);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче