Commit 19da8e28 authored by Georg Koppen's avatar Georg Koppen Committed by Mike Perry
Browse files

Bug 13027: Backport of Navigator.* spoofing patch.

It turned out Web Workers ignored general.*.override values which
got fixed by Mozilla with
https://hg.mozilla.org/mozilla-central/rev/b0b831a03d9ch
https://hg.mozilla.org/mozilla-central/rev/eeb169601087 (bug 1062920
and 1060621).

This is an ESR 31 specific backport which was at least partly
necessary due to the big worker related patchset (bug 949325) which
landed in Firefox 32.
parent 1a7aacc0
Loading
Loading
Loading
Loading
+32 −29
Original line number Diff line number Diff line
@@ -337,13 +337,13 @@ Navigator::GetAppCodeName(nsAString& aAppCodeName)
NS_IMETHODIMP
Navigator::GetAppVersion(nsAString& aAppVersion)
{
  return NS_GetNavigatorAppVersion(aAppVersion);
  return GetAppVersion(aAppVersion, /* aUsePrefOverriddenValue */ true);
}

NS_IMETHODIMP
Navigator::GetAppName(nsAString& aAppName)
{
  NS_GetNavigatorAppName(aAppName);
  AppName(aAppName, /* aUsePrefOverriddenValue */ true);
  return NS_OK;
}

@@ -406,7 +406,7 @@ Navigator::GetLanguage(nsAString& aLanguage)
NS_IMETHODIMP
Navigator::GetPlatform(nsAString& aPlatform)
{
  return NS_GetNavigatorPlatform(aPlatform);
  return GetPlatform(aPlatform, /* aUsePrefOverriddenValue */ true);
}

NS_IMETHODIMP
@@ -2356,29 +2356,12 @@ Navigator::GetWindowFromGlobal(JSObject* aGlobal)
  return win.forget();
}

} // namespace dom
} // namespace mozilla

nsresult
NS_GetNavigatorUserAgent(nsAString& aUserAgent)
Navigator::GetPlatform(nsAString& aPlatform, bool aUsePrefOverriddenValue)
{
  nsresult rv;

  nsCOMPtr<nsIHttpProtocolHandler>
    service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  nsAutoCString ua;
  rv = service->GetUserAgent(ua);
  CopyASCIItoUTF16(ua, aUserAgent);

  return rv;
}
  MOZ_ASSERT(NS_IsMainThread());

nsresult
NS_GetNavigatorPlatform(nsAString& aPlatform)
{
  if (!nsContentUtils::IsCallerChrome()) {
  if (aUsePrefOverriddenValue && !nsContentUtils::IsCallerChrome()) {
    const nsAdoptingString& override =
      mozilla::Preferences::GetString("general.platform.override");

@@ -2417,10 +2400,11 @@ NS_GetNavigatorPlatform(nsAString& aPlatform)

  return rv;
}
nsresult
NS_GetNavigatorAppVersion(nsAString& aAppVersion)

/* static */ nsresult
Navigator::GetAppVersion(nsAString& aAppVersion, bool aUsePrefOverriddenValue)
{
  if (!nsContentUtils::IsCallerChrome()) {
  if (aUsePrefOverriddenValue && !nsContentUtils::IsCallerChrome()) {
    const nsAdoptingString& override =
      mozilla::Preferences::GetString("general.appversion.override");

@@ -2452,10 +2436,10 @@ NS_GetNavigatorAppVersion(nsAString& aAppVersion)
  return rv;
}

void
NS_GetNavigatorAppName(nsAString& aAppName)
/* static */ void
Navigator::AppName(nsAString& aAppName, bool aUsePrefOverriddenValue)
{
  if (!nsContentUtils::IsCallerChrome()) {
  if (aUsePrefOverriddenValue && !nsContentUtils::IsCallerChrome()) {
    const nsAdoptingString& override =
      mozilla::Preferences::GetString("general.appname.override");

@@ -2467,3 +2451,22 @@ NS_GetNavigatorAppName(nsAString& aAppName)

  aAppName.AssignLiteral("Netscape");
}

} // namespace dom
} // namespace mozilla

nsresult
NS_GetNavigatorUserAgent(nsAString& aUserAgent)
{
  nsresult rv;

  nsCOMPtr<nsIHttpProtocolHandler>
    service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  nsAutoCString ua;
  rv = service->GetUserAgent(ua);
  CopyASCIItoUTF16(ua, aUserAgent);

  return rv;
}
+9 −4
Original line number Diff line number Diff line
@@ -46,8 +46,6 @@ class nsIDOMMozIccManager;
// Navigator: Script "navigator" object
//*****************************************************************************

void NS_GetNavigatorAppName(nsAString& aAppName);

namespace mozilla {
namespace dom {

@@ -156,6 +154,15 @@ public:
  // The XPCOM GetDoNotTrack is ok
  Geolocation* GetGeolocation(ErrorResult& aRv);
  battery::BatteryManager* GetBattery(ErrorResult& aRv);

  static void AppName(nsAString& aAppName, bool aUsePrefOverriddenValue);

  static nsresult GetPlatform(nsAString& aPlatform,
                              bool aUsePrefOverriddenValue);

  static nsresult GetAppVersion(nsAString& aAppVersion,
                                bool aUsePrefOverriddenValue);

  already_AddRefed<Promise> GetDataStores(const nsAString &aName,
                                          ErrorResult& aRv);
  bool Vibrate(uint32_t aDuration);
@@ -361,7 +368,5 @@ private:
} // namespace mozilla

nsresult NS_GetNavigatorUserAgent(nsAString& aUserAgent);
nsresult NS_GetNavigatorPlatform(nsAString& aPlatform);
nsresult NS_GetNavigatorAppVersion(nsAString& aAppVersion);

#endif // mozilla_dom_Navigator_h
+44 −3
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include "mozilla/dom/WorkerNavigatorBinding.h"

#include "RuntimeService.h"
#include "WorkerPrivate.h"

BEGIN_WORKERS_NAMESPACE

@@ -26,9 +27,7 @@ WorkerNavigator::Create(bool aOnLine)
    rts->GetNavigatorProperties();

  nsRefPtr<WorkerNavigator> navigator =
    new WorkerNavigator(properties.mAppName, properties.mAppVersion,
                        properties.mPlatform, properties.mUserAgent,
                        aOnLine);
    new WorkerNavigator(properties, aOnLine);

  return navigator.forget();
}
@@ -39,4 +38,46 @@ WorkerNavigator::WrapObject(JSContext* aCx)
  return WorkerNavigatorBinding_workers::Wrap(aCx, this);
}

void
WorkerNavigator::GetAppName(nsString& aAppName) const
{
  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
  MOZ_ASSERT(workerPrivate);

  if (!mProperties.mAppNameOverridden.IsEmpty() &&
      !workerPrivate->UsesSystemPrincipal()) {
    aAppName = mProperties.mAppNameOverridden;
  } else {
    aAppName = mProperties.mAppName;
  }
}

void
WorkerNavigator::GetAppVersion(nsString& aAppVersion) const
{
  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
  MOZ_ASSERT(workerPrivate);

  if (!mProperties.mAppVersionOverridden.IsEmpty() &&
      !workerPrivate->UsesSystemPrincipal()) {
    aAppVersion = mProperties.mAppVersionOverridden;
  } else {
    aAppVersion = mProperties.mAppVersion;
  }
}

void
WorkerNavigator::GetPlatform(nsString& aPlatform) const
{
  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
  MOZ_ASSERT(workerPrivate);

  if (!mProperties.mPlatformOverridden.IsEmpty() &&
      !workerPrivate->UsesSystemPrincipal()) {
    aPlatform = mProperties.mPlatformOverridden;
  } else {
    aPlatform = mProperties.mPlatform;
  }
}

END_WORKERS_NAMESPACE
+12 −25
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#define mozilla_dom_workers_navigator_h__

#include "Workers.h"
#include "RuntimeService.h"
#include "nsString.h"
#include "nsWrapperCache.h"

@@ -14,21 +15,14 @@ BEGIN_WORKERS_NAMESPACE

class WorkerNavigator MOZ_FINAL : public nsWrapperCache
{
  nsString mAppName;
  nsString mAppVersion;
  nsString mPlatform;
  nsString mUserAgent;
  typedef struct RuntimeService::NavigatorProperties NavigatorProperties;

  NavigatorProperties mProperties;
  bool mOnline;

  WorkerNavigator(const nsAString& aAppName,
                  const nsAString& aAppVersion,
                  const nsAString& aPlatform,
                  const nsAString& aUserAgent,
  WorkerNavigator(const NavigatorProperties& aProperties,
                  bool aOnline)
    : mAppName(aAppName)
    , mAppVersion(aAppVersion)
    , mPlatform(aPlatform)
    , mUserAgent(aUserAgent)
    : mProperties(aProperties)
    , mOnline(aOnline)
  {
    MOZ_COUNT_CTOR(WorkerNavigator);
@@ -59,24 +53,17 @@ public:
  {
    aAppCodeName.AssignLiteral("Mozilla");
  }
  void GetAppName(nsString& aAppName) const
  {
    aAppName = mAppName;
  }
  void GetAppName(nsString& aAppName) const;

  void GetAppVersion(nsString& aAppVersion) const
  {
    aAppVersion = mAppVersion;
  }
  void GetAppVersion(nsString& aAppVersion) const;

  void GetPlatform(nsString& aPlatform) const;

  void GetPlatform(nsString& aPlatform) const
  {
    aPlatform = mPlatform;
  }
  void GetProduct(nsString& aProduct) const
  {
    aProduct.AssignLiteral("Gecko");
  }

  bool TaintEnabled() const
  {
    return false;
@@ -84,7 +71,7 @@ public:

  void GetUserAgent(nsString& aUserAgent) const
  {
    aUserAgent = mUserAgent;
    aUserAgent = mProperties.mUserAgent;
  }

  bool OnLine() const
+101 −3
Original line number Diff line number Diff line
@@ -110,6 +110,10 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 1,
#define CC_REQUEST_OBSERVER_TOPIC "child-cc-request"
#define MEMORY_PRESSURE_OBSERVER_TOPIC "memory-pressure"

#define PREF_GENERAL_APPNAME_OVERRIDE "general.appname.override"
#define PREF_GENERAL_APPVERSION_OVERRIDE "general.appversion.override"
#define PREF_GENERAL_PLATFORM_OVERRIDE "general.platform.override"

#define BROADCAST_ALL_WORKERS(_func, ...)                                      \
  PR_BEGIN_MACRO                                                               \
    AssertIsOnMainThread();                                                    \
@@ -981,6 +985,48 @@ private:
  }
};

void
AppNameOverrideChanged(const char* /* aPrefName */, void* /* aClosure */)
{
  AssertIsOnMainThread();

  const nsAdoptingString& override =
    mozilla::Preferences::GetString(PREF_GENERAL_APPNAME_OVERRIDE);

  RuntimeService* runtime = RuntimeService::GetService();
  if (runtime) {
    runtime->UpdateAppNameOverridePreference(override);
  }
}

void
AppVersionOverrideChanged(const char* /* aPrefName */, void* /* aClosure */)
{
  AssertIsOnMainThread();

  const nsAdoptingString& override =
    mozilla::Preferences::GetString(PREF_GENERAL_APPVERSION_OVERRIDE);

  RuntimeService* runtime = RuntimeService::GetService();
  if (runtime) {
    runtime->UpdateAppVersionOverridePreference(override);
  }
}

void
PlatformOverrideChanged(const char* /* aPrefName */, void* /* aClosure */)
{
  AssertIsOnMainThread();

  const nsAdoptingString& override =
    mozilla::Preferences::GetString(PREF_GENERAL_PLATFORM_OVERRIDE);

  RuntimeService* runtime = RuntimeService::GetService();
  if (runtime) {
    runtime->UpdatePlatformOverridePreference(override);
  }
}

} /* anonymous namespace */

class RuntimeService::WorkerThread MOZ_FINAL : public nsThread
@@ -1347,15 +1393,25 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
  }
  else {
    if (!mNavigatorPropertiesLoaded) {
      NS_GetNavigatorAppName(mNavigatorProperties.mAppName);
      if (NS_FAILED(NS_GetNavigatorAppVersion(mNavigatorProperties.mAppVersion)) ||
          NS_FAILED(NS_GetNavigatorPlatform(mNavigatorProperties.mPlatform)) ||
      Navigator::AppName(mNavigatorProperties.mAppName,
                         false /* aUsePrefOverriddenValue */);
      if (NS_FAILED(Navigator::GetAppVersion(mNavigatorProperties.mAppVersion,
                                             false /* aUsePrefOverriddenValue */)) ||
          NS_FAILED(Navigator::GetPlatform(mNavigatorProperties.mPlatform,
                                           false /* aUsePrefOverriddenValue */)) ||
          NS_FAILED(NS_GetNavigatorUserAgent(mNavigatorProperties.mUserAgent))) {
        JS_ReportError(aCx, "Failed to load navigator strings!");
        UnregisterWorker(aCx, aWorkerPrivate);
        return false;
      }

      mNavigatorProperties.mAppNameOverridden =
        mozilla::Preferences::GetString(PREF_GENERAL_APPNAME_OVERRIDE);
      mNavigatorProperties.mAppVersionOverridden =
        mozilla::Preferences::GetString(PREF_GENERAL_APPVERSION_OVERRIDE);
      mNavigatorProperties.mPlatformOverridden =
        mozilla::Preferences::GetString(PREF_GENERAL_PLATFORM_OVERRIDE);

      mNavigatorPropertiesLoaded = true;
    }

@@ -1695,6 +1751,18 @@ RuntimeService::Init()
                                                   LoadRuntimeAndContextOptions,
                                                   PREF_WORKERS_OPTIONS_PREFIX,
                                                   nullptr)) ||
      NS_FAILED(Preferences::RegisterCallbackAndCall(
                                                  AppNameOverrideChanged,
                                                  PREF_GENERAL_APPNAME_OVERRIDE,
                                                  nullptr)) ||
      NS_FAILED(Preferences::RegisterCallbackAndCall(
                                               AppVersionOverrideChanged,
                                               PREF_GENERAL_APPVERSION_OVERRIDE,
                                               nullptr)) ||
      NS_FAILED(Preferences::RegisterCallbackAndCall(
                                                 PlatformOverrideChanged,
                                                 PREF_GENERAL_PLATFORM_OVERRIDE,
                                                 nullptr)) ||
      NS_FAILED(Preferences::RegisterCallbackAndCall(
                                                 JSVersionChanged,
                                                 PREF_WORKERS_LATEST_JS_VERSION,
@@ -1841,6 +1909,15 @@ RuntimeService::Cleanup()
    if (NS_FAILED(Preferences::UnregisterCallback(JSVersionChanged,
                                                  PREF_WORKERS_LATEST_JS_VERSION,
                                                  nullptr)) ||
        NS_FAILED(Preferences::UnregisterCallback(AppNameOverrideChanged,
                                                  PREF_GENERAL_APPNAME_OVERRIDE,
                                                  nullptr)) ||
        NS_FAILED(Preferences::UnregisterCallback(AppVersionOverrideChanged,
                                                  PREF_GENERAL_APPVERSION_OVERRIDE,
                                                  nullptr)) ||
        NS_FAILED(Preferences::UnregisterCallback(PlatformOverrideChanged,
                                                  PREF_GENERAL_PLATFORM_OVERRIDE,
                                                  nullptr)) ||
        NS_FAILED(Preferences::UnregisterCallback(LoadRuntimeAndContextOptions,
                                                  PREF_JS_OPTIONS_PREFIX,
                                                  nullptr)) ||
@@ -2234,6 +2311,27 @@ RuntimeService::UpdateAllWorkerRuntimeAndContextOptions()
                        sDefaultJSSettings.chrome.contextOptions);
}

void
RuntimeService::UpdateAppNameOverridePreference(const nsAString& aValue)
{
  AssertIsOnMainThread();
  mNavigatorProperties.mAppNameOverridden = aValue;
}

void
RuntimeService::UpdateAppVersionOverridePreference(const nsAString& aValue)
{
  AssertIsOnMainThread();
  mNavigatorProperties.mAppVersionOverridden = aValue;
}

void
RuntimeService::UpdatePlatformOverridePreference(const nsAString& aValue)
{
  AssertIsOnMainThread();
  mNavigatorProperties.mPlatformOverridden = aValue;
}

void
RuntimeService::UpdateAllWorkerPreference(WorkerPreference aPref, bool aValue)
{
Loading