From c3f777e8b0ca57c36b46bb2fde49b9f0be3b6b26 Mon Sep 17 00:00:00 2001
From: Arthur Edelstein <arthuredelstein@gmail.com>
Date: Mon, 16 Jul 2018 17:58:33 -0700
Subject: [PATCH] Bug 26520: Fix sec slider/NoScript for TOR_SKIP_LAUNCH=1

We need to wait for NoScript to have launched before we
send the first settings message from the security slider.
So wait for NoScript to send us a message first.
---
 src/modules/noscript-control.js | 75 +++++++++++++++++++--------------
 1 file changed, 44 insertions(+), 31 deletions(-)

diff --git a/src/modules/noscript-control.js b/src/modules/noscript-control.js
index 196d14c2..14f78c49 100644
--- a/src/modules/noscript-control.js
+++ b/src/modules/noscript-control.js
@@ -9,6 +9,9 @@ const { LegacyExtensionContext } =
       Cu.import("resource://gre/modules/LegacyExtensionsUtils.jsm", {});
 const { bindPrefAndInit } =
       Cu.import("resource://torbutton/modules/utils.js", {});
+let logger = Components.classes["@torproject.org/torbutton-logger;1"]
+    .getService(Components.interfaces.nsISupports).wrappedJSObject;
+let log = (level, msg) => logger.log(level, msg);
 
 // ## NoScript settings
 
@@ -80,34 +83,6 @@ let noscriptSettings = safetyLevel => (
 // The extension ID for NoScript (WebExtension)
 const noscriptID = "{73a6fe31-595d-460b-a920-fcc0f8843232}";
 
-// A mock extension object that can communicate with another extension
-// via the WebExtensions sendMessage/onMessage mechanism.
-let extensionContext = new LegacyExtensionContext({ id : noscriptID });
-
-// The component that handles WebExtensions' sendMessage.
-let messageManager = extensionContext.messenger.messageManagers[0];
-
-// __setNoScriptSettings(settings)__.
-// NoScript listens for internal settings with onMessage. We can send
-// a new settings JSON object according to NoScript's
-// protocol and these are accepted! See the use of
-// `browser.runtime.onMessage.addListener(...)` in NoScript's bg/main.js.
-let sendNoScriptSettings = settings =>
-    extensionContext.messenger.sendMessage(messageManager, settings, noscriptID);
-
-// __setNoScriptSafetyLevel(safetyLevel)__.
-// Set NoScript settings according to a particular safety level
-// (security slider level): 0 = Standard, 1 = Safer, 2 = Safest
-let setNoScriptSafetyLevel = safetyLevel =>
-    sendNoScriptSettings(noscriptSettings(safetyLevel));
-
-// ## Slider binding
-
-// __securitySliderToSafetyLevel(sliderState)__.
-// Converts the "extensions.torbutton.security_slider" pref value
-// to a "safety level" value: 0 = Standard, 1 = Safer, 2 = Safest
-let securitySliderToSafetyLevel = sliderState => [undefined, 2, 1, 1, 0][sliderState];
-
 // Ensure binding only occurs once.
 let initialized = false;
 
@@ -119,9 +94,47 @@ var initialize = () => {
     return;
   }
   initialized = true;
-  bindPrefAndInit(
-    "extensions.torbutton.security_slider",
-    sliderState => setNoScriptSafetyLevel(securitySliderToSafetyLevel(sliderState)));
+
+  try {
+    // A mock extension object that can communicate with another extension
+    // via the WebExtensions sendMessage/onMessage mechanism.
+    let extensionContext = new LegacyExtensionContext({ id : noscriptID });
+
+    // The component that handles WebExtensions' sendMessage.
+    let messageManager = extensionContext.messenger.messageManagers[0];
+
+    // __setNoScriptSettings(settings)__.
+    // NoScript listens for internal settings with onMessage. We can send
+    // a new settings JSON object according to NoScript's
+    // protocol and these are accepted! See the use of
+    // `browser.runtime.onMessage.addListener(...)` in NoScript's bg/main.js.
+    let sendNoScriptSettings = settings =>
+        extensionContext.messenger.sendMessage(messageManager, settings, noscriptID);
+
+    // __setNoScriptSafetyLevel(safetyLevel)__.
+    // Set NoScript settings according to a particular safety level
+    // (security slider level): 0 = Standard, 1 = Safer, 2 = Safest
+    let setNoScriptSafetyLevel = safetyLevel =>
+        sendNoScriptSettings(noscriptSettings(safetyLevel));
+
+    // __securitySliderToSafetyLevel(sliderState)__.
+    // Converts the "extensions.torbutton.security_slider" pref value
+    // to a "safety level" value: 0 = Standard, 1 = Safer, 2 = Safest
+    let securitySliderToSafetyLevel = sliderState =>
+        [undefined, 2, 1, 1, 0][sliderState];
+
+    // Wait for the first message from NoScript to arrive, and then
+    // bind the security_slider pref to the NoScript settings.
+    let messageListener = (a,b,c) => {
+      extensionContext.api.browser.runtime.onMessage.removeListener(messageListener);
+      bindPrefAndInit(
+        "extensions.torbutton.security_slider",
+        sliderState => setNoScriptSafetyLevel(securitySliderToSafetyLevel(sliderState)));
+    };
+    extensionContext.api.browser.runtime.onMessage.addListener(messageListener);
+  } catch (e) {
+    log(5, e.message);
+  }
 };
 
 // Export initialize() function for external use.
-- 
2.17.1

