Bug 1361500 - Don't call _tzset on startup r?ehsan,arthuredelstein
The reason we call _tzset inside DateTime.cpp is to allow the
privacy.resistFingerprinting pref to mask our timezone by setting
the TZ environment variable. Without _tzset, the changes to the
environment variable won't actually change anything. However, if
a process is started with the TZ environment variable set to
something (like "UTC"), then those changes will be active in
that process. Since we're only masking timezone to JS running in
the content process, and since those content processes will be
started by the parent process which has already set its TZ to UTC,
and will copy that variable to its children, we only need to call
_tzset() when the pref changes, and only in the content process,
provided we are on e10s.
MozReview-Commit-ID: CPU99BGDUPj
--- a/js/src/vm/DateTime.cpp
+++ b/js/src/vm/DateTime.cpp
@@ -67,23 +67,16 @@ ComputeUTCTime(time_t t, struct tm* ptm)
*/
static int32_t
UTCToLocalStandardOffsetSeconds()
{
using js::SecondsPerDay;
using js::SecondsPerHour;
using js::SecondsPerMinute;
-#if defined(XP_WIN)
- // Windows doesn't follow POSIX: updates to the TZ environment variable are
- // not reflected immediately on that platform as they are on other systems
- // without this call.
- _tzset();
-#endif
-
// Get the current time.
time_t currentMaybeWithDST = time(nullptr);
if (currentMaybeWithDST == time_t(-1))
return 0;
// Break down the current time into its (locally-valued, maybe with DST)
// components.
struct tm local;
@@ -175,23 +168,16 @@ js::DateTimeInfo::DateTimeInfo()
}
int64_t
js::DateTimeInfo::computeDSTOffsetMilliseconds(int64_t utcSeconds)
{
MOZ_ASSERT(utcSeconds >= 0);
MOZ_ASSERT(utcSeconds <= MaxUnixTimeT);
-#if defined(XP_WIN)
- // Windows does not follow POSIX. Updates to the TZ environment variable
- // are not reflected immediately on that platform as they are on UNIX
- // systems without this call.
- _tzset();
-#endif
-
struct tm tm;
if (!ComputeLocalTime(static_cast<time_t>(utcSeconds), &tm))
return 0;
int32_t dayoff = int32_t((utcSeconds + utcToLocalStandardOffsetSeconds) % SecondsPerDay);
int32_t tmoff = tm.tm_sec + (tm.tm_min * SecondsPerMinute) + (tm.tm_hour * SecondsPerHour);
int32_t diff = tmoff - dayoff;
--- a/toolkit/components/resistfingerprinting/nsRFPService.cpp
+++ b/toolkit/components/resistfingerprinting/nsRFPService.cpp
@@ -1,23 +1,26 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsRFPService.h"
+#include <time.h>
+
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "nsCOMPtr.h"
#include "nsServiceManagerUtils.h"
#include "nsString.h"
+#include "nsXULAppAPI.h"
#include "nsIObserverService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsJSUtils.h"
#include "prenv.h"
@@ -115,16 +118,29 @@ nsRFPService::Init()
const char* tzValue = PR_GetEnv("TZ");
if (tzValue) {
mInitialTZValue = nsCString(tzValue);
}
// Call UpdatePref() here to cache the value of 'privacy.resistFingerprinting'
// and set the timezone.
UpdatePref();
+
+#if defined(XP_WIN)
+ // If we're e10s, then we don't need to run this, since the child process will
+ // simply inherit the environment variable from the parent process, in which
+ // case it's unnecessary to call _tzset().
+ if (XRE_IsParentProcess() && !XRE_IsE10sParentProcess()) {
+ // Windows does not follow POSIX. Updates to the TZ environment variable
+ // are not reflected immediately on that platform as they are on UNIX
+ // systems without this call.
+ _tzset();
+ }
+#endif
+
return rv;
}
void
nsRFPService::UpdatePref()
{
MOZ_ASSERT(NS_IsMainThread());
sPrivacyResistFingerprinting = Preferences::GetBool(RESIST_FINGERPRINTING_PREF);
@@ -147,18 +163,16 @@ nsRFPService::UpdatePref()
#else
// For Windows, we reset the TZ to an empty string. This will make Windows to use
// its system timezone.
PR_SetEnv("TZ=");
#endif
}
}
- // We don't have to call _tzset() here for Windows since the following
- // function nsJSUtils::ResetTimeZone() will call it for us.
nsJSUtils::ResetTimeZone();
}
void
nsRFPService::StartShutdown()
{
MOZ_ASSERT(NS_IsMainThread());
@@ -179,16 +193,25 @@ NS_IMETHODIMP
nsRFPService::Observe(nsISupports* aObject, const char* aTopic,
const char16_t* aMessage)
{
if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
NS_ConvertUTF16toUTF8 pref(aMessage);
if (pref.EqualsLiteral(RESIST_FINGERPRINTING_PREF)) {
UpdatePref();
+
+#if defined(XP_WIN)
+ if (!XRE_IsE10sParentProcess()) {
+ // Windows does not follow POSIX. Updates to the TZ environment variable
+ // are not reflected immediately on that platform as they are on UNIX
+ // systems without this call.
+ _tzset();
+ }
+#endif
}
}
if (!strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, aTopic)) {
StartShutdown();
}
return NS_OK;