Bug 1394490 - Javascript loader environments test. r=kmag
authorTed Campbell <tcampbell@mozilla.com>
Tue, 05 Sep 2017 13:23:31 -0400
changeset 428850 753fa54f005b1fecda05d4c7c989e7c899b3ef32
parent 428849 76e8870c843ecfc9e01faef5c6194fe5449bc62e
child 428851 10405ae76f204c476465dcfaca4cd6b4edfcc444
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1394490
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1394490 - Javascript loader environments test. r=kmag This are some unit tests to track regressions in the environment behavior exposed to embeddings for various javascript loaders inside Gecko. MozReview-Commit-ID: 8pn56Skwbat
js/xpconnect/tests/unit/environment_checkscript.jsm
js/xpconnect/tests/unit/environment_script.js
js/xpconnect/tests/unit/test_ComponentEnvironment.js
js/xpconnect/tests/unit/test_FrameScriptEnvironment.js
js/xpconnect/tests/unit/test_SubscriptLoaderEnvironment.js
js/xpconnect/tests/unit/test_SubscriptLoaderSandboxEnvironment.js
js/xpconnect/tests/unit/xpcshell.ini
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/unit/environment_checkscript.jsm
@@ -0,0 +1,13 @@
+var EXPORTED_SYMBOLS = ["bound"];
+
+var bound = "";
+
+try { void vu; bound += "vu,"; } catch (e) {}
+try { void vq; bound += "vq,"; } catch (e) {}
+try { void vl; bound += "vl,"; } catch (e) {}
+try { void gt; bound += "gt,"; } catch (e) {}
+try { void ed; bound += "ed,"; } catch (e) {}
+try { void ei; bound += "ei,"; } catch (e) {}
+try { void fo; bound += "fo,"; } catch (e) {}
+try { void fi; bound += "fi,"; } catch (e) {}
+try { void fd; bound += "fd,"; } catch (e) {}
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/unit/environment_script.js
@@ -0,0 +1,14 @@
+let strict = (function() { return this; })() === undefined;
+
+// Allow this to be used as a JSM
+var EXPORTED_SYMBOLS = [];
+
+if (!strict) vu = 1;                                    // Unqualified Variable
+var vq = 2;                                             // Qualified Variable
+let vl = 3;                                             // Lexical
+this.gt = 4;                                            // Global This
+eval("this.ed = 5");                                    // Direct Eval
+(1,eval)("this.ei = 6");                                // Indirect Eval
+(new Function("this.fo = 7"))();                        // Dynamic Function Object
+if (!strict) (function() { this.fi = 8; })();           // Indirect Function This
+function fd_() { this.fd = 9; }; if (!strict) fd_();    // Direct Function Implicit
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/unit/test_ComponentEnvironment.js
@@ -0,0 +1,8 @@
+let tgt = {};
+Components.utils.import("resource://test/environment_script.js", tgt);
+Components.utils.import("resource://test/environment_checkscript.jsm", tgt);
+
+
+// Components should not share namespace
+if (tgt.bound != "")
+    throw new Error("Unexpected shared binding set - " + tgt.bound);
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/unit/test_FrameScriptEnvironment.js
@@ -0,0 +1,43 @@
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+let ppmm = Services.ppmm.getChildAt(0);
+
+add_task(async function test_bindings() {
+    let {strict, bound} = await new Promise(function(resolve) {
+        // Use a listener to get results from child
+        ppmm.addMessageListener("results", function listener(msg) {
+            ppmm.removeMessageListener("results", listener);
+            resolve(msg.data);
+        });
+
+        // Bind vars in first process script
+        ppmm.loadProcessScript("resource://test/environment_script.js", false);
+
+        // Check visibility in second process script
+        ppmm.loadProcessScript(`data:,
+            let strict = (function() { return this; })() === undefined;
+            var bound = "";
+
+            try { void vu; bound += "vu,"; } catch (e) {}
+            try { void vq; bound += "vq,"; } catch (e) {}
+            try { void vl; bound += "vl,"; } catch (e) {}
+            try { void gt; bound += "gt,"; } catch (e) {}
+            try { void ed; bound += "ed,"; } catch (e) {}
+            try { void ei; bound += "ei,"; } catch (e) {}
+            try { void fo; bound += "fo,"; } catch (e) {}
+            try { void fi; bound += "fi,"; } catch (e) {}
+            try { void fd; bound += "fd,"; } catch (e) {}
+
+            sendAsyncMessage("results", { strict, bound });
+            `, false);
+    });
+
+    // FrameScript loader should share |this| access
+    if (strict) {
+        if (bound != "gt,ed,ei,fo,")
+            throw new Error("Unexpected global binding set - " + bound);
+    } else {
+        if (bound != "gt,ed,ei,fo,fi,fd,")
+            throw new Error("Unexpected global binding set - " + bound);
+    }
+});
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/unit/test_SubscriptLoaderEnvironment.js
@@ -0,0 +1,33 @@
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+let tgt = {};
+Services.scriptloader.loadSubScript("resource://test/environment_script.js", tgt);
+
+var bound = "";
+var tgt_bound = "";
+
+// Check global bindings
+try { void vu; bound += "vu,"; } catch (e) {}
+try { void vq; bound += "vq,"; } catch (e) {}
+try { void vl; bound += "vl,"; } catch (e) {}
+try { void gt; bound += "gt,"; } catch (e) {}
+try { void ed; bound += "ed,"; } catch (e) {}
+try { void ei; bound += "ei,"; } catch (e) {}
+try { void fo; bound += "fo,"; } catch (e) {}
+try { void fi; bound += "fi,"; } catch (e) {}
+try { void fd; bound += "fd,"; } catch (e) {}
+
+// Check target bindings
+for (var name of ["vu", "vq", "vl", "gt", "ed", "ei", "fo", "fi", "fd"])
+    if (tgt.hasOwnProperty(name))
+        tgt_bound += name + ",";
+
+
+// Expected subscript loader behavior is as follows:
+//  - Qualified vars and |this| access occur on target object
+//  - Lexical vars occur on ExtensibleLexicalEnvironment of target object
+//  - Bareword assignments and global |this| access occur on caller's global
+if (bound != "vu,ei,fo,fi,")
+    throw new Error("Unexpected global binding set - " + bound);
+if (tgt_bound != "vq,gt,ed,fd,")
+    throw new Error("Unexpected target binding set - " + tgt_bound);
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/unit/test_SubscriptLoaderSandboxEnvironment.js
@@ -0,0 +1,32 @@
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+let tgt = Components.utils.Sandbox(Services.scriptSecurityManager.getSystemPrincipal());
+Services.scriptloader.loadSubScript("resource://test/environment_script.js", tgt);
+
+var bound = "";
+var tgt_bound = "";
+
+// Check global bindings
+try { void vu; bound += "vu,"; } catch (e) {}
+try { void vq; bound += "vq,"; } catch (e) {}
+try { void vl; bound += "vl,"; } catch (e) {}
+try { void gt; bound += "gt,"; } catch (e) {}
+try { void ed; bound += "ed,"; } catch (e) {}
+try { void ei; bound += "ei,"; } catch (e) {}
+try { void fo; bound += "fo,"; } catch (e) {}
+try { void fi; bound += "fi,"; } catch (e) {}
+try { void fd; bound += "fd,"; } catch (e) {}
+
+// Check target bindings
+for (var name of ["vu", "vq", "vl", "gt", "ed", "ei", "fo", "fi", "fd"])
+    if (tgt.hasOwnProperty(name))
+        tgt_bound += name + ",";
+
+
+// Expected subscript loader behavior with a Sandbox is as follows:
+//  - Lexicals occur on ExtensibleLexicalEnvironment of target
+//  - Everything else occurs on Sandbox global
+if (bound != "")
+    throw new Error("Unexpected global binding set - " + bound);
+if (tgt_bound != "vu,vq,gt,ed,ei,fo,fi,fd,")
+    throw new Error("Unexpected target binding set - " + tgt_bound);
--- a/js/xpconnect/tests/unit/xpcshell.ini
+++ b/js/xpconnect/tests/unit/xpcshell.ini
@@ -6,16 +6,18 @@ support-files =
   bogus_exports_type.jsm
   bug451678_subscript.js
   component-blob.js
   component-blob.manifest
   component-file.js
   component-file.manifest
   component_import.js
   component_import.manifest
+  environment_script.js
+  environment_checkscript.jsm
   file_simple_script.js
   importer.jsm
   recursive_importA.jsm
   recursive_importB.jsm
   subScriptWithEarlyError.js
   syntax_error.jsm
 
 [test_allowWaivers.js]
@@ -132,8 +134,12 @@ head = head_watchdog.js
 [test_xrayed_iterator.js]
 [test_xray_named_element_access.js]
 [test_xray_SavedFrame.js]
 [test_xray_SavedFrame-02.js]
 [test_xray_regexp.js]
 [test_resolve_dead_promise.js]
 [test_asyncLoadSubScriptError.js]
 [test_function_names.js]
+[test_FrameScriptEnvironment.js]
+[test_SubscriptLoaderEnvironment.js]
+[test_SubscriptLoaderSandboxEnvironment.js]
+[test_ComponentEnvironment.js]