diff options
Diffstat (limited to 'js/xpconnect/tests/mochitest')
126 files changed, 5516 insertions, 0 deletions
diff --git a/js/xpconnect/tests/mochitest/bug1681664_helper.js b/js/xpconnect/tests/mochitest/bug1681664_helper.js new file mode 100644 index 0000000000..14f2289a19 --- /dev/null +++ b/js/xpconnect/tests/mochitest/bug1681664_helper.js @@ -0,0 +1 @@ +while (true) {}; diff --git a/js/xpconnect/tests/mochitest/bug500931_helper.html b/js/xpconnect/tests/mochitest/bug500931_helper.html new file mode 100644 index 0000000000..da268d99d8 --- /dev/null +++ b/js/xpconnect/tests/mochitest/bug500931_helper.html @@ -0,0 +1,8 @@ +<html> + <head> + <title>Inner frame for bug 500931 mochitest</title> + <script>x = 42;</script> + </head> + <body> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/bug571849_helper.html b/js/xpconnect/tests/mochitest/bug571849_helper.html new file mode 100644 index 0000000000..234cd57ccf --- /dev/null +++ b/js/xpconnect/tests/mochitest/bug571849_helper.html @@ -0,0 +1,7 @@ +<html> + <head> + </head> + <body> + TEXT NODE TEXT NODE + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/bug589028_helper.html b/js/xpconnect/tests/mochitest/bug589028_helper.html new file mode 100644 index 0000000000..dc56ecbc3c --- /dev/null +++ b/js/xpconnect/tests/mochitest/bug589028_helper.html @@ -0,0 +1,27 @@ +<html> + <head> + <script> + function getMyOption() { + return new Option(); + } + function getCallersOption(caller) { + return new caller.Option(); + } + function getMyAudio() { + return new Audio(); + } + function getCallersAudio(caller) { + return new caller.Audio(); + } + function getMyImage() { + return new Image(); + } + function getCallersImage(caller) { + return new caller.Image(); + } + </script> + </head> + <body> + the iframe + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/bug92773_helper.html b/js/xpconnect/tests/mochitest/bug92773_helper.html new file mode 100644 index 0000000000..be10dd54ae --- /dev/null +++ b/js/xpconnect/tests/mochitest/bug92773_helper.html @@ -0,0 +1,7 @@ +<html> + <head> + <script> + Object.defineProperty(window, "foo", { get() { alert("FAIL"); } }); + </script> + </head> +</html> diff --git a/js/xpconnect/tests/mochitest/chrome_wrappers_helper.html b/js/xpconnect/tests/mochitest/chrome_wrappers_helper.html new file mode 100644 index 0000000000..a0c1ec87e3 --- /dev/null +++ b/js/xpconnect/tests/mochitest/chrome_wrappers_helper.html @@ -0,0 +1,29 @@ +<html> + <head> + <script> + function check_wrapper(ok, wrapper, expected, note) { + let { getClassName } = SpecialPowers.unwrap( + SpecialPowers.wrap(window).ChromeUtils + ); + ok(getClassName(wrapper, false) === expected, note); + } + function run_test(ok, xpcnw, sjow) { + // both wrappers should point to our window: XOW + check_wrapper(ok, ok, "Proxy", "functions are wrapped properly"); + check_wrapper(ok, xpcnw, "Proxy", "XPCNWs are transformed correctly"); + check_wrapper(ok, sjow, "Proxy", "SJOWs are transformed correctly"); + + check_wrapper(ok, window.location, "Location", + "same-compartment security wrappers are gone"); + + ok(defprop1 === 1, "defprop1 exists"); + window.defprop1 = 2; + ok(defprop1 === 2, "defprop1 is properly writable"); + + // defprop2 = {}; disabled because the test doesn't work + } + </script> + </head> + <body> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/class_static_worker.js b/js/xpconnect/tests/mochitest/class_static_worker.js new file mode 100644 index 0000000000..eb949226ba --- /dev/null +++ b/js/xpconnect/tests/mochitest/class_static_worker.js @@ -0,0 +1,13 @@ +class A { + static { this.x = 12; } +} + + +self.onmessage = function (e) { + console.log(e) + if (e.data == 'get') { + postMessage(A.x); + return; + } + postMessage('Unknown message type.'); +}
\ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/file1_bug629227.html b/js/xpconnect/tests/mochitest/file1_bug629227.html new file mode 100644 index 0000000000..dd12484068 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file1_bug629227.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html> + <head> + <script> + function doIt() { + var doc = window.frames[0].document; + var ok = (doc.form1 == doc.getElementById("test1")); + window.parent.postMessage( + JSON.stringify({ ok: ok, + reason: "Should be able to get named items by name" }), + "*"); + window.parent.postMessage("finish", "*"); + } + + window.onmessage = function(ev) { + if (ev.data == "start") { + doIt(); + } + } + + document.domain = "example.org"; + </script> + </head> + <body> + <iframe id="subframe"></iframe> + <script> + document.getElementById("subframe").src = + "http://test2.example.org" + + location.pathname.replace(/file1_bug629227.html/, "file2_bug629227.html"); + </script> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file2_bug629227.html b/js/xpconnect/tests/mochitest/file2_bug629227.html new file mode 100644 index 0000000000..02a0540865 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file2_bug629227.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html> + <head> + <script> + document.domain = "example.org"; + </script> + </head> + <body> + <form name="form1" id="test1"></form> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug505915.html b/js/xpconnect/tests/mochitest/file_bug505915.html new file mode 100644 index 0000000000..5129126914 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug505915.html @@ -0,0 +1,10 @@ +<!DOCTYPE HTML> +<html> +<!-- +Inner frame for testing bug 505915. +https://bugzilla.mozilla.org/show_bug.cgi?id=505915 +--> +<head> +<body onload="parent.postMessage('', '*');"> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug605167.html b/js/xpconnect/tests/mochitest/file_bug605167.html new file mode 100644 index 0000000000..d5253315b8 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug605167.html @@ -0,0 +1,7 @@ +<html> +<body> +<script> + parent.f = function() { return this; }; +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug650273.html b/js/xpconnect/tests/mochitest/file_bug650273.html new file mode 100644 index 0000000000..5fe33e9695 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug650273.html @@ -0,0 +1,31 @@ +<!-- test by moz_bug_r_a4@yahoo.com --> +<body onload="a()"> +<script> +var targetUrl = "http://example.com/"; +var l; + +function a() { + var o = {}; + o.toString = function() { + l(); + return "a"; + }; + var f = Object.getOwnPropertyDescriptor(Document.prototype, "title").set; + setTimeout(f.bind(document), 0, o); +} + +function l() { + var l = false; + onunload = function() { + l = true; + }; + location = targetUrl; + do { + var r = new XMLHttpRequest(); + r.open("GET", location.href, false); + r.overrideMimeType("text/plain"); + try { r.send(null); } + catch (e) {} + } while (!l); +} +</script> diff --git a/js/xpconnect/tests/mochitest/file_bug658560.html b/js/xpconnect/tests/mochitest/file_bug658560.html new file mode 100644 index 0000000000..411d31ac73 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug658560.html @@ -0,0 +1,4 @@ +<html> + <body> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug706301.html b/js/xpconnect/tests/mochitest/file_bug706301.html new file mode 100644 index 0000000000..805449b4aa --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug706301.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> + <head> + <script type="application/javascript"> + window.addEventListener('message', doContentTest); + + function doContentTest() { + + // This has always worked. + var nodelist1 = document.getElementsByTagName('details'); + Object.getOwnPropertyDescriptor(nodelist1, 'length'); + ok(nodelist1['length'] == 0, "Content should be able to get the length of " + + "its own nodelist after calling getOwnPropertyDescriptor."); + + // This is bug 706301. + var nodelist2 = document.getElementsByTagName('section'); + ok(getLengthInChrome(nodelist2), "Chrome should be able to get the length of " + + "content nodelist after calling getOwnPropertyDescriptor."); + + // All done. + finishTestInChrome(); + } + </script> + </head> + <body> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug720619.html b/js/xpconnect/tests/mochitest/file_bug720619.html new file mode 100644 index 0000000000..d198ba1fa3 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug720619.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> + <head> + <script> + valueOf = function() { return "v"; } + toString = function() { return "s"; } + </script> + </head> + <body></body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug731471.html b/js/xpconnect/tests/mochitest/file_bug731471.html new file mode 100644 index 0000000000..fcfb194cb6 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug731471.html @@ -0,0 +1,5 @@ +<html> +<body> +1 +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug738244.html b/js/xpconnect/tests/mochitest/file_bug738244.html new file mode 100644 index 0000000000..a399d9f0e0 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug738244.html @@ -0,0 +1,10 @@ +<html> +<body> +<form name="form1"> + <input name="input1" /> + <input name="appendChild" /> +</form> +<iframe name="frame1"> +</iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug760131.html b/js/xpconnect/tests/mochitest/file_bug760131.html new file mode 100644 index 0000000000..736732a0a4 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug760131.html @@ -0,0 +1,23 @@ +<html> +<div id="target" ontouchstart="alert();"></div> +<script type="application/javascript"> + +/** Test for Bug 760131 **/ + +function accessTouches(evt) +{ + var thrown = false; + try { + var a = evt.touches; + } catch (e) { + thrown = true; + } + ok(!thrown, "Unwrapping a TouchList shouldn't throw"); +} + +document.getElementById("target").ontouchstart = accessTouches; + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug781476.html b/js/xpconnect/tests/mochitest/file_bug781476.html new file mode 100644 index 0000000000..745f8818e5 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug781476.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<script type="application/javascript"> +function makeEvent() { + var evt = new Event("MouseEvents"); + evt.expando = 42; + is(evt.expando, 42, "Expando properly visible in iframe"); + return evt; +} +</script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug789713.html b/js/xpconnect/tests/mochitest/file_bug789713.html new file mode 100644 index 0000000000..4c30fe8275 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug789713.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=789713 +--> +<head> + <meta charset="utf-8"> +</head> +<body> + +<script type="application/javascript"> + +/** Test for Bug 789713 **/ + +function go() { + var ifr = document.getElementById('ifr'); + var pass = true; + var doc = ifr.contentDocument; + var win = ifr.contentWindow; + + var walker = doc.createTreeWalker(doc.body); + pass = pass && (walker.root === doc.body); + walker.foo = "expando"; + + win.bar = "another-expando"; + + // First, do the document.domain operation. This shouldn't crash. + document.domain = "example.org"; + + // Now make sure we can still access properties on "walker". + try { + walker.root; + pass = pass && walker.foo == "expando"; + } catch (e) { + pass = false; + } + + // And make sure we can't access properties on "win", because the + // document.domain change revoked the access. + try { + win.bar; + pass = false; + } catch (e) { pass = pass && /Permission denied/.exec(e.message); } + window.parent.postMessage(pass, '*'); +} + +</script> +<iframe id="ifr" src="file_empty.html" onload="go()"></iframe> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug795275.html b/js/xpconnect/tests/mochitest/file_bug795275.html new file mode 100644 index 0000000000..c3886b8ba8 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug795275.html @@ -0,0 +1,14 @@ +<html> +<head> +<script type="application/javascript"> + function touchComponents() { + Components; + } + function touchInterfaces() { + Components.interfaces; + } +</script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug799348.html b/js/xpconnect/tests/mochitest/file_bug799348.html new file mode 100644 index 0000000000..5800868db0 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug799348.html @@ -0,0 +1,11 @@ +<!DOCTYPE HTML> +<html> +<head> +<script> + var foo = window.open('file_empty.html', '', 'width=550, height=420, status=no, resizable=yes, scrollbars=yes, toolbar=no, left=945, top=225'); +</script> +</head> +<body> +</body> +</html> + diff --git a/js/xpconnect/tests/mochitest/file_bug802557.html b/js/xpconnect/tests/mochitest/file_bug802557.html new file mode 100644 index 0000000000..39f952bc5b --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug802557.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<html> +<head> +<script> +var gTS = window.location.toString; +var gGHR = Object.getOwnPropertyDescriptor(window.location, 'href').get; +function getTests(fromOuter) { + + function loc() { + return fromOuter ? window.location : location; + } + return { + getLocationImplicit: function() { + return loc() + ""; + }, + getLocationExplicit: function() { + return loc().toString(); + }, + getLocationApply1: function() { + return gTS.call(loc()); + }, + getLocationApply2: function() { + return gTS.apply(loc(), []); + }, + getLocationApply3: function() { + return Function.call.apply(gTS, [loc()]); + }, + getHref: function() { + return loc().href; + }, + getHrefViaApply: function() { + return Function.call.apply(gGHR, [loc()]); + }, + } +}; + +function mungeNames(obj, suffix) { + var rv = {}; + Object.getOwnPropertyNames(obj) + .forEach(name => rv[name + suffix] = obj[name]); + return rv; +} + +function mergeObjects(a, b) { + var rv = {}; + Object.getOwnPropertyNames(a).forEach(name => rv[name] = a[name]); + Object.getOwnPropertyNames(b).forEach(name => rv[name] = b[name]); + return rv; +} + +function getAllTests() { + var innerTests = getTests(false); + var outerTests = getTests(true); + return mergeObjects(mungeNames(innerTests, '_inner'), + mungeNames(outerTests, '_outer')); +} + +</script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug860494.html b/js/xpconnect/tests/mochitest/file_bug860494.html new file mode 100644 index 0000000000..63a7003796 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug860494.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<title></title> +</head> +<body> +<iframe name="top"></iframe> +<iframe name="parent"></iframe> +<iframe name="location"></iframe> +<iframe name="length"></iframe> +<iframe name="window"></iframe> +<iframe name="navigator"></iframe> +<iframe name="alert"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html b/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html new file mode 100644 index 0000000000..127c479ebe --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html @@ -0,0 +1,8 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Cross-Compartment DOM WeakMaps</title> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_documentdomain.html b/js/xpconnect/tests/mochitest/file_documentdomain.html new file mode 100644 index 0000000000..784ed269d0 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_documentdomain.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<html> +<head> +<script type="application/javascript"> + + function setDomain(domain) { + document.domain = domain; + } + + function tryToAccess(otherWin) { + try { + var text = otherWin.document.getElementById('foo').innerHTML; + return /Better Late/.exec(text); + } catch (e) { return false; } + } + + var gRef = null; + function storeReference(otherWin) { + gRef = otherWin.document.getElementById('foo'); + } + + function tryToAccessStored() { + try { + return /Better Late/.exec(gRef.innerHTML); + } catch (e) { return false; } + } + + function invokingFunctionThrowsSecurityException(name) { + try { + window[name](); + return false; + } catch (e) { return /insecure|denied/.test(e); } + } + + +</script> +</head> +<body> +<span id="foo">Better Late than Never</span> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html b/js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html new file mode 100644 index 0000000000..f789a33d76 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html @@ -0,0 +1,10 @@ +<html> + <head> + <script> + // We want to put an expando on the object, but we want this object + // to be wrapped in other compartments. This means that the expando + // must implement precreate, which happens (in general) for nodes. + // So we just do a cyclic reference to the document body. + window.expando = document.documentElement; + </script> + </head> diff --git a/js/xpconnect/tests/mochitest/file_empty.html b/js/xpconnect/tests/mochitest/file_empty.html new file mode 100644 index 0000000000..ebe8e56a68 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_empty.html @@ -0,0 +1,3 @@ +<!DOCTYPE html> +<!-- Note: other tests throughout the tree depend on the layout of this, including the title. Don't make big changes without a try run. --> +<html><head><title>empty test page</title></head><body><span id="text">Nothing to see here</span><iframe name="subframe"></iframe></body></html> diff --git a/js/xpconnect/tests/mochitest/file_evalInSandbox.html b/js/xpconnect/tests/mochitest/file_evalInSandbox.html new file mode 100644 index 0000000000..f53aa1166c --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_evalInSandbox.html @@ -0,0 +1,8 @@ +<html> + <body> + <script> + document.foo = "bar"; + windowfoo = "windowbar"; + </script> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_exnstack.html b/js/xpconnect/tests/mochitest/file_exnstack.html new file mode 100644 index 0000000000..448e3c0a70 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_exnstack.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> +<head> + <script type="application/javascript"> + window.doThrow = function(other) { + if (other) + throwAsOuter(other); + else + throwAsInner(); + } + + function throwAsInner() { + throw Error('look at me go!'); + } + + function throwAsOuter(other) { + other.doThrow(null); + } + </script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_expandosharing.html b/js/xpconnect/tests/mochitest/file_expandosharing.html new file mode 100644 index 0000000000..ceb4131bb8 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_expandosharing.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html> +<head> +<script type="application/javascript"> + function setup() { + // Set up different target objects for expandos, one for each binding type. + window.targetWN = window; + window.targetDOM = new XMLHttpRequest(); + window.targetJS = new Date(); + } + + function placeExpando(name, val, target) { + target[name] = val; + } + + // If val === null, then we shouldn't have access. + function checkExpando(name, val, target, msg) { + if (val !== null) { + ok(name in target, msg); + try { + is(target[name], val, "Got the right expando value"); + } catch(e) { ok(false, "Threw when accessing same-origin expando"); } + } + else { + ok(!(name in target), msg); + } + } + +</script> +</head> +<body onload="setup();"> + <span>Salut, Ma Cherise. ;-)</span> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_matches.html b/js/xpconnect/tests/mochitest/file_matches.html new file mode 100644 index 0000000000..0dc101b533 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_matches.html @@ -0,0 +1 @@ +<html><body></body></html> diff --git a/js/xpconnect/tests/mochitest/file_nodelists.html b/js/xpconnect/tests/mochitest/file_nodelists.html new file mode 100644 index 0000000000..2195c62ccf --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_nodelists.html @@ -0,0 +1,7 @@ +<html> + <body> + <p> + <p> + <p> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_wrappers-2.html b/js/xpconnect/tests/mochitest/file_wrappers-2.html new file mode 100644 index 0000000000..e27b07ed6a --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_wrappers-2.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> + <body> + <script> + var obj = {a: 3, next: 1}; + var to_iterate = Object.create(obj); + var enumerate = { 0: 0, "hi": "there" }; + function func () {}; + var o = {}; + var a = [1]; + </script> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_xrayic.html b/js/xpconnect/tests/mochitest/file_xrayic.html new file mode 100644 index 0000000000..ad06a3118b --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_xrayic.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<script type="application/javascript"> + function setup() { + // Set up targets for sandbox expandos. + window.targetDOM = [document.getElementById("hello"), document.getElementById("there")]; + } +</script> +</head> +<body onload="setup();"> +<span id="hello" class="iamaspan">Hello</span> +<span id="there" class="iamaspan">There</span> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/finalizationRegistry_worker.js b/js/xpconnect/tests/mochitest/finalizationRegistry_worker.js new file mode 100644 index 0000000000..d603cdab38 --- /dev/null +++ b/js/xpconnect/tests/mochitest/finalizationRegistry_worker.js @@ -0,0 +1,96 @@ +let holdings1 = []; +let holdings2 = []; +let holdings3 = []; +let holdings4 = []; +let holdings5 = []; + +onmessage = (event) => { + switch (event.data) { + case 'startTest': + startTest(); + break; + case 'checkResults': + checkResults(); + break; + default: + throw "Unknown message"; + } +}; + +function startTest() { + // Registry with no registered objects. + let registry1 = new FinalizationRegistry(v => { holdings1.push(v); }); + + // Registry with three registered objects. + let registry2 = new FinalizationRegistry(v => { holdings2.push(v); }); + registry2.register({}, 1); + registry2.register({}, 2); + registry2.register({}, 3); + + // Registry with registered object that is then unregistered. + let registry3 = new FinalizationRegistry(v => { holdings3.push(v); }); + let token3 = {} + registry3.register({}, 1, token3); + registry3.unregister(token3); + + // Registry with registered object that doesn't die. + let registry4 = new FinalizationRegistry(v => { holdings4.push(v); }); + let object4 = {}; + registry4.register(object4, 1); + + // Registry observing cyclic JS data structure. + let registry5 = new FinalizationRegistry(v => { holdings5.push(v); }); + registry5.register(makeJSCycle(4), 5); + + const { gc } = getJSTestingFunctions(); + gc(); + + Promise.resolve().then(() => { + checkNoCallbacks(); + }); + + postMessage('started'); +} + +function checkNoCallbacks() { + is(holdings1.length, 0); + is(holdings2.length, 0); + is(holdings3.length, 0); + is(holdings4.length, 0); + is(holdings5.length, 0); +} + +function checkResults() { + is(holdings1.length, 0); + + let result = holdings2.sort((a, b) => a - b); + is(result.length, 3); + is(result[0], 1); + is(result[1], 2); + is(result[2], 3); + + is(holdings3.length, 0); + is(holdings4.length, 0); + + is(holdings5.length, 1); + is(holdings5[0], 5); + + postMessage('passed'); +} + +function is(a, b) { + if (a !== b) { + throw `Expected ${b} but got ${a}`; + } +} + +function makeJSCycle(size) { + let first = {}; + let current = first; + for (let i = 0; i < size; i++) { + current.next = {}; + current = current.next; + } + current.next = first; + return first; +} diff --git a/js/xpconnect/tests/mochitest/hasinstance/mochitest.ini b/js/xpconnect/tests/mochitest/hasinstance/mochitest.ini new file mode 100644 index 0000000000..7266b615bb --- /dev/null +++ b/js/xpconnect/tests/mochitest/hasinstance/mochitest.ini @@ -0,0 +1,7 @@ +[DEFAULT] +prefs = + dom.webidl.crosscontext_hasinstance.enabled=false +support-files = + ../file_empty.html + +[test_bug870423.html] diff --git a/js/xpconnect/tests/mochitest/hasinstance/test_bug870423.html b/js/xpconnect/tests/mochitest/hasinstance/test_bug870423.html new file mode 100644 index 0000000000..9d928cdd63 --- /dev/null +++ b/js/xpconnect/tests/mochitest/hasinstance/test_bug870423.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=870423 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 870423</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for cross-scope instanceof. **/ + SimpleTest.waitForExplicitFinish(); + + function go() { + var sowin = $('soifr').contentWindow; + var xowin = $('xoifr').contentWindow; + var xosswin = $('xossifr').contentWindow; + + check(window, sowin, 'HTMLBodyElement', function(win) { return win.document.body; }); + check(window, sowin, 'HTMLDocument', function(win) { return win.document; }); + check(window, sowin, 'Window', function(win) { return win; }); + check(window, sowin, 'Location', function(win) { return win.location; }); + + ok(!(xowin instanceof Window), "Cross-origin instanceof should fail"); + ok(!(xowin.location instanceof Location), "Cross-origin instanceof should fail"); + + // cross-origin same-site. + ok(!(xosswin instanceof Window), "Cross-origin instanceof should fail"); + ok(!(xosswin.location instanceof Location), "Cross-origin instanceof should fail"); + + SimpleTest.finish(); + } + + function check(win1, win2, constructorName, getInstance) { + ok(!(getInstance(win1) instanceof win2[constructorName]), + "Cross-Scope instanceof fails: " + constructorName + ", " + win1.location + ", " + win2.location); + ok(!(getInstance(win2) instanceof win1[constructorName]), + "Cross-Scope instanceof fails: " + constructorName + ", " + win2.location + ", " + win1.location); + } + + </script> +</head> +<body onload="go();"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=870423">Mozilla Bug 870423</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<iframe id="soifr" src="file_empty.html"></iframe> +<iframe id="xoifr" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +<!-- cross origin, same site --> +<iframe id="xossifr" src="//test1.mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/inner.html b/js/xpconnect/tests/mochitest/inner.html new file mode 100644 index 0000000000..8021a55539 --- /dev/null +++ b/js/xpconnect/tests/mochitest/inner.html @@ -0,0 +1,7 @@ +<html> + <head> + <title>Inner frame for bug 39685 mochitest</title> + </head> + <body onload="x = 4"> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/mochitest.ini b/js/xpconnect/tests/mochitest/mochitest.ini new file mode 100644 index 0000000000..30536b42e0 --- /dev/null +++ b/js/xpconnect/tests/mochitest/mochitest.ini @@ -0,0 +1,178 @@ +[DEFAULT] +support-files = + bug500931_helper.html + bug571849_helper.html + bug589028_helper.html + bug92773_helper.html + chrome_wrappers_helper.html + file1_bug629227.html + file2_bug629227.html + file_bug505915.html + file_bug605167.html + file_bug650273.html + file_bug658560.html + file_bug706301.html + file_bug720619.html + file_bug731471.html + file_bug738244.html + file_bug760131.html + file_bug781476.html + file_bug789713.html + file_bug795275.html + file_bug799348.html + file_bug802557.html + file_bug860494.html + file_crosscompartment_weakmap.html + file_documentdomain.html + file_doublewrappedcompartments.html + file_empty.html + file_evalInSandbox.html + file_exnstack.html + file_expandosharing.html + file_matches.html + file_nodelists.html + file_wrappers-2.html + file_xrayic.html + inner.html + test1_bug629331.html + test2_bug629331.html + finalizationRegistry_worker.js + private_field_worker.js + class_static_worker.js + bug1681664_helper.js + shadow_realm_worker.js + shadow_realm_module.js +prefs = + javascript.options.weakrefs=true + javascript.options.spectre.disable_for_isolated_content=true + javascript.options.experimental.enable_new_set_methods=false + javascript.options.experimental.shadow_realms=true +[test_bug384632.html] +[test_bug390488.html] +[test_bug393269.html] +[test_bug396851.html] +skip-if = + http3 +[test_bug428021.html] +[test_bug446584.html] +[test_bug462428.html] +[test_bug478438.html] +skip-if = + http3 +[test_bug500691.html] +[test_bug505915.html] +skip-if = + http3 +[test_bug560351.html] +[test_bug585745.html] +[test_bug589028.html] +[test_bug601299.html] +[test_bug605167.html] +skip-if = + http3 +[test_bug618017.html] +[test_bug623437.html] +[test_bug628410.html] +[test_bug628794.html] +[test_bug629227.html] +skip-if = + http3 +[test_bug629331.html] +skip-if = + http3 +[test_bug636097.html] +skip-if = + http3 +[test_bug650273.html] +skip-if = + http3 +[test_bug655297-1.html] +[test_bug655297-2.html] +[test_bug661980.html] +[test_bug691059.html] +[test_bug720619.html] +skip-if = + http3 +[test_bug731471.html] +skip-if = toolkit == "android" && debug +[test_bug764389.html] +[test_bug772288.html] +[test_bug781476.html] +[test_bug789713.html] +skip-if = + http3 +[test_bug790732.html] +[test_bug793969.html] +[test_bug800864.html] +skip-if = + http3 +[test_bug802557.html] +skip-if = + http3 +[test_bug803730.html] +[test_bug809547.html] +[test_bug829872.html] +skip-if = + http3 +[test_bug862380.html] +skip-if = + http3 +[test_bug865260.html] +skip-if = + http3 +[test_bug871887.html] +[test_bug912322.html] +[test_bug916945.html] +skip-if = + http3 +[test_bug92773.html] +skip-if = + http3 +[test_bug940783.html] +skip-if = + http3 +[test_bug965082.html] +skip-if = + http3 +[test_bug960820.html] +[test_bug993423.html] +[test_bug1005806.html] +[test_bug1094930.html] +[test_bug1158558.html] +[test_bug1448048.html] +[test_bug1681664.html] +[test_crosscompartment_weakmap.html] +[test_enable_privilege.html] +[test_frameWrapping.html] +# The JS test component we use below is only available in debug builds. +[test_getWebIDLCaller.html] +skip-if = (debug == false) +[test_getweakmapkeys.html] +[test_isRemoteProxy.html] +[test_paris_weakmap_keys.html] +skip-if = (debug == false) +[test_nukeContentWindow.html] +[test_sameOriginPolicy.html] +skip-if = + http3 +[test_sandbox_fetch.html] + support-files = + ../../../../dom/tests/mochitest/fetch/test_fetch_basic.js +[test_weakmaps.html] +[test_finalizationRegistry.html] +[test_finalizationRegistryInWorker.html] +[test_finalizationRegistry_cleanupSome.html] +[test_finalizationRegistry_incumbent.html] +[test_weakRefs.html] +[test_weakRefs_cross_compartment.html] +[test_weakRefs_collected_wrapper.html] +[test_private_field_dom.html] +[test_private_field_worker.html] +[test_class_static_block_worker.html] +skip-if = !nightly_build +[test_shadowRealm.html] +# This test has been updated to work with worker modules +[test_shadowRealm_worker.html] +skip-if = !nightly_build +[test_spectre_mitigations.html] +skip-if = os == "android" # Fission situation on Android is more complicated. diff --git a/js/xpconnect/tests/mochitest/moz.build b/js/xpconnect/tests/mochitest/moz.build new file mode 100644 index 0000000000..772ed94cce --- /dev/null +++ b/js/xpconnect/tests/mochitest/moz.build @@ -0,0 +1,7 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +MOCHITEST_MANIFESTS += ["hasinstance/mochitest.ini", "mochitest.ini"] diff --git a/js/xpconnect/tests/mochitest/private_field_worker.js b/js/xpconnect/tests/mochitest/private_field_worker.js new file mode 100644 index 0000000000..b822c16248 --- /dev/null +++ b/js/xpconnect/tests/mochitest/private_field_worker.js @@ -0,0 +1,21 @@ +class A { + #x; + + g(o) { + return #x in o; + } +} + +let objects = []; + +self.onmessage = function (e) { + if (e.data === 'allocate') { + objects.push(new A); + return; + } + if (e.data == 'count') { + postMessage(objects.length); + return; + } + postMessage('Unknown message type.'); +}
\ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/shadow_realm_module.js b/js/xpconnect/tests/mochitest/shadow_realm_module.js new file mode 100644 index 0000000000..35ba80666b --- /dev/null +++ b/js/xpconnect/tests/mochitest/shadow_realm_module.js @@ -0,0 +1 @@ +export var x = 1; diff --git a/js/xpconnect/tests/mochitest/shadow_realm_worker.js b/js/xpconnect/tests/mochitest/shadow_realm_worker.js new file mode 100644 index 0000000000..c91c9bc30c --- /dev/null +++ b/js/xpconnect/tests/mochitest/shadow_realm_worker.js @@ -0,0 +1,81 @@ + +var sr = new ShadowRealm(); +var resolve; + +var allSettled = new Promise((resolved) => { resolve = resolved }); + +self.onmessage = async function (e) { + try { + // Test evaluate + if (e.data === 'evaluate') { + sr.evaluate("var s = 'PASS set string in realm';") + var res = sr.evaluate('s'); + postMessage(res); + return; + } + + // If Import works in a worker, then it ought to work in a shadow realm + // + // See https://bugzilla.mozilla.org/show_bug.cgi?id=1247687 and + // https://bugzilla.mozilla.org/show_bug.cgi?id=1772162 + if (e.data == 'import') { + var import_worked = false; + var importValue_worked = false; + var importNested_worked = false; + try { + var module = await import("./shadow_realm_module.js"); + if (module.x != 1) { + throw "mismatch"; + } + import_worked = true; + } catch (e) { } + + try { + await sr.importValue("./shadow_realm_module.js", 'x').then((x) => { + if (x == 1) { importValue_worked = true; } + }); + } catch (e) { } + + try { + sr.evaluate(` + var imported = false; + import("./shadow_realm_module.js").then((module) => { + if (module.x == 1) { + imported = true; + } + }); + true; + `); + + importNested_worked = sr.evaluate("imported"); + } catch (e) { + + } + + if (importValue_worked == importNested_worked) { + postMessage(`PASS: import in workers ${ + import_worked ? "worked" : "failed" + }. importValue, and nested import all ${ + importValue_worked ? "worked" : "failed" + } `); + resolve(); + return; + } + + postMessage(`FAIL: importValue ${importValue_worked}, import ${import_worked}, importNested ${importNested_worked}`); + resolve(); + return; + } + + + // Reply back with finish + if (e.data == 'finish') { + await allSettled; + postMessage("finish"); + return; + } + } catch (e) { + postMessage("FAIL: " + e.message); + } + postMessage('Unknown message type.'); +} diff --git a/js/xpconnect/tests/mochitest/test1_bug629331.html b/js/xpconnect/tests/mochitest/test1_bug629331.html new file mode 100644 index 0000000000..18843e08da --- /dev/null +++ b/js/xpconnect/tests/mochitest/test1_bug629331.html @@ -0,0 +1,19 @@ +<body> +<iframe src="about:blank" id="ifr"></iframe> +<script> +/** Test for Bug 629331 **/ +function finish() { + parent.postMessage(JSON.stringify({fun: "finish"}), "*"); +} + +function is(a, b, description) { + parent.postMessage(JSON.stringify({ fun: "is", a: a, b: b, description: description }), "*"); +} + +document.domain = "example.org"; +var i = 0; +is(i, 0, 'i meets starting conditions'); +document.getElementById('ifr').src = 'http://test2.example.org/tests/js/xpconnect/tests/mochitest/test2_bug629331.html'; +</script> + + diff --git a/js/xpconnect/tests/mochitest/test2_bug629331.html b/js/xpconnect/tests/mochitest/test2_bug629331.html new file mode 100644 index 0000000000..1bcf037398 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test2_bug629331.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + </head> + <body> + <script> + document.domain = "example.org"; + + for (var j = 1; j <= 9; j++) { + parent.i = j; + var locali = parent.i; + parent.is(locali, j, 'step ' + j + ' worked'); + } + + parent.finish(); + </script> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug1005806.html b/js/xpconnect/tests/mochitest/test_bug1005806.html new file mode 100644 index 0000000000..41fe6ee1e6 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug1005806.html @@ -0,0 +1,27 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1005806 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1005806</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1005806">Mozilla Bug 1005806</a> +<p id="display"></p> +<div id="content" style="display: none"> + <input id="ipt"></input> +</div> +<pre id="test"> +</pre> +<script type="application/javascript"> + +/** Test for Bug 1005806 **/ +is(typeof document.getElementById('ipt').controllers, 'undefined', "Controllers property should not appear for content"); + +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug1094930.html b/js/xpconnect/tests/mochitest/test_bug1094930.html new file mode 100644 index 0000000000..d303bf2495 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug1094930.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1094930 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1094930</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <iframe id="ifr"></iframe> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1094930">Mozilla Bug 1094930</a> +<p id="display"></p> +<script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + class XFoo extends frames[0].HTMLElement { + connectedCallback() { + ok(true, "connectedCallback was called"); + SimpleTest.finish(); + } + }; + + customElements.define.call(frames[0].customElements, "x-foo", XFoo); + frames[0].document.firstChild.appendChild(new XFoo()); +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug1158558.html b/js/xpconnect/tests/mochitest/test_bug1158558.html new file mode 100644 index 0000000000..f5c50d640e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug1158558.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1158558 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1158558</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1158558">Mozilla Bug 1158558</a> +<p id="display"></p> +<div id="content" style="display: none"> + <input id="ipt"></input> +</div> +<pre id="test"> +</pre> +<script type="application/javascript"> + +/** Test for Bug 1158558 **/ + +// Observers of cycle-collector-begin can be implemented in JS, and +// thus can end up starting an incremental GC while we're in the middle +// of a CC slice. + +SimpleTest.waitForExplicitFinish(); + +var observer = { + observe: function(subject, topic, data) { + SpecialPowers.removeObserver(observer, "cycle-collector-begin"); + SpecialPowers.Cu.getJSTestingFunctions().startgc(1); + + ok(true, "Do something so the test harness doesn't get angry"); + + SimpleTest.finish(); + } +}; + +SpecialPowers.addObserver(observer, "cycle-collector-begin"); + +SpecialPowers.Cu.forceCC(); + +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug1448048.html b/js/xpconnect/tests/mochitest/test_bug1448048.html new file mode 100644 index 0000000000..2d58593a6b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug1448048.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1448048 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1448048</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1448048 **/ + var { AppConstants } = SpecialPowers.ChromeUtils.import( + "resource://gre/modules/AppConstants.jsm" + ); + if (AppConstants.NIGHTLY_BUILD) { + is(typeof Components, "undefined", "Should be no Components shim on Nightly"); + } else { + is(typeof Components, "object", "Should have a components shim on non-Nightly"); + } + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1448048">Mozilla Bug 1448048</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug1681664.html b/js/xpconnect/tests/mochitest/test_bug1681664.html new file mode 100644 index 0000000000..685d4aa669 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug1681664.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html lang="en" dir="ltr"> + <head> + <title>Test page for bug 1681664</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script> + SimpleTest.waitForExplicitFinish() + async function init() { + var Services = SpecialPowers.Services; + var observer = { + observe(subject, topic, data) { + if (topic === "process-hang-report") { + var report = subject.QueryInterface(Ci.nsIHangReport); + report.terminateScript(); + Services.obs.removeObserver(observer, "process-hang-report"); + } + } + } + + Services.obs.addObserver(observer, "process-hang-report"); + try { + await import("test_bug1681664_helper.js"); + result.textContent = "FAIL"; + } catch (ex) { + result.textContent = "PASS"; + } + } + </script> + </head> + <body> + <p id="result"></p> + <script> + (async function() { + await init(); + is(result.textContent, "PASS", "Infinite loop script should not cause browser crash"); + SimpleTest.finish() + })(); + </script> + </body> +</html> + diff --git a/js/xpconnect/tests/mochitest/test_bug384632.html b/js/xpconnect/tests/mochitest/test_bug384632.html new file mode 100644 index 0000000000..251ec9b153 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug384632.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=384632 +--> +<head> + <title>Test for Bug 384632</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=384632">Mozilla Bug 384632</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 384632 **/ +var Cc = SpecialPowers.Cc, Ci = SpecialPowers.Ci; +var propBag = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag); +var obj = {}; +propBag.setProperty("foopy", obj); +ok(SpecialPowers.unwrap(propBag.getProperty("foopy")) === obj, + "nsIVariant works with regular objects"); +propBag.setProperty("foopy1", external); +ok(SpecialPowers.unwrap(propBag.getProperty("foopy1")) === external, + "nsIVariant works with bizarre objects"); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug390488.html b/js/xpconnect/tests/mochitest/test_bug390488.html new file mode 100644 index 0000000000..ca4bc4024b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug390488.html @@ -0,0 +1,64 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=390488 +--> +<head> + <title>Test for Bug 390488</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=390488">Mozilla Bug 390488</a> +<p id="display"> + <div id="testdiv" onclick="checkForStacks();" style="visibility:hidden"> + </div> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 390488 **/ + function getStack1() { + var func = arguments.callee.caller; + var stack = ""; + for (var i = 1; func && i < 8; i++) { + stack += " " + i + ". " + func.name; + func = func.caller; + } + return stack; + } + + function getStack2() { + var stack = new Error().stack; + // Remove the two lines due to calling this + return stack.substring(stack.indexOf("\n", stack.indexOf("\n")+1)+1); + } + + function simulateClick() { + var evt = document.createEvent("MouseEvents"); + evt.initMouseEvent("click", true, true, window, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + $("testdiv").dispatchEvent(evt); + } + + function matches(s, p, name) { + ok(s.match(p) != null, + name + " - got " + s + ", expected a string matching " + p); + } + + function checkForStacks() { + matches(getStack1(), /checkForStacks .* onclick .* simulateClick/, + "Stack from walking caller chain should be correct"); + isnot(getStack2().indexOf("simulateClick@"), -1, + "Stack from |new Error().stack| should include simulateClick"); + } + + simulateClick(); +</script> +</pre> +</body> +</html> + diff --git a/js/xpconnect/tests/mochitest/test_bug393269.html b/js/xpconnect/tests/mochitest/test_bug393269.html new file mode 100644 index 0000000000..d69e9ef2d1 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug393269.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=393269 +--> +<head> + <title>Test for Bug 393269</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=393269">Mozilla Bug 393269</a> +<iframe id="ifr"></iframe> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +(function () { + /** Test for Bug 393269 **/ + var doc = $("ifr").contentDocument; + is("UTF-8", doc.characterSet, "control, getting a property"); + doc.open(); + try { + is("UTF-8", doc.characterSet, + "can get a property after 1 document.open") + } catch (e) { + fail("Shouldn't have thrown: " + e); + return; + } finally { + doc.close(); + } + + doc.open(); + try { + is("UTF-8", doc.characterSet, + "can get a property after 2 document.opens") + } catch (e) { + fail("Shouldn't have thrown: " + e); + } finally { + doc.close(); + } +})(); +</script> +</pre> +</body> +</html> + diff --git a/js/xpconnect/tests/mochitest/test_bug396851.html b/js/xpconnect/tests/mochitest/test_bug396851.html new file mode 100644 index 0000000000..dc6bd25d52 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug396851.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=396851 +--> +<head> + <title>Test for Bug 396851</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <script type="text/javascript"> + function throws(func, pattern, msg) { + try { + func(); + ok(false, msg); + } catch (e) { + ok(pattern.test(e), `${msg}: Expect exception mathing ${pattern}`); + } + } + + function go() { + var iframe = $("ifr"); + var win = iframe.contentWindow; + throws(() => win.document, + /Permission denied/, + "Unprivileged code should not be able to access cross-origin document"); + + if (SpecialPowers.useRemoteSubframes) { + throws(() => win.document, + /Permission denied/, + "Privileged code should not be able to access cross-process document"); + } else { + ok(SpecialPowers.wrap(win).document != null, + "Able to access the cross-origin document"); + } + SimpleTest.finish(); + } + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=396851">Mozilla Bug 396851</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<script type="text/javascript"> + SimpleTest.waitForExplicitFinish(); +</script> +<iframe id="ifr" + src="http://example.org/tests/js/xpconnect/tests/mochitest/inner.html" + onload="go()"> +</iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug428021.html b/js/xpconnect/tests/mochitest/test_bug428021.html new file mode 100644 index 0000000000..932dcf7428 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug428021.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=428021 +--> +<head> + <title>Test for Bug 428021</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=428021">Mozilla Bug 428021</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + /** Test for Bug 428021 **/ + var rangetter, ransetter; + this.__defineGetter__('x', function() { rangetter = true; }); + this.__defineSetter__('x', function(val) { ransetter = true; }); + + var exn; + try { + e = x; + x = false; + } catch (e) { + exn = e; + } + ok(!exn, "Exception caught: " + exn); + ok(rangetter, "Failed to run getter"); + ok(ransetter, "Failed to run setter"); + +</script> +</pre> +</body> +</html> + diff --git a/js/xpconnect/tests/mochitest/test_bug446584.html b/js/xpconnect/tests/mochitest/test_bug446584.html new file mode 100644 index 0000000000..09fef92867 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug446584.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=446584 +--> +<head> + <title>Test for Bug 446584</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=446584">Mozilla Bug 446584</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 446584 **/ + +function test(val) { + try { + document.createNodeIterator(document.body, + NodeFilter.SHOW_ALL, + function() { throw val }).nextNode(); + ok(false, "NodeIterator::nextNode() should have thrown an exception."); + } catch (ex) { + ok(val === ex, "NodeIterator did not properly forward exception " + + val + " of type " + typeof val + ". Thrown value was " + ex + "."); + } +} + +test(0); +test(1); +test(3.14); +test('roses'); +test({}); +test(false); +test(true); +test([1,2,3]); +test(function(){}); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug462428.html b/js/xpconnect/tests/mochitest/test_bug462428.html new file mode 100644 index 0000000000..a3f7b7c39a --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug462428.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=462428 +--> +<head> + <title>Test for Bug 462428</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=462428">Mozilla Bug 462428</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 462428 **/ +var getter = document.__lookupGetter__('documentElement'); +ok(getter !== undefined, "But able to look it up the normal way"); +ok(!document.hasOwnProperty('documentElement'), "property should still be on the prototype"); + +var sawProp = false; +for (var i in document) { + if (i === "documentElement") { + sawProp = true; + } +} + +ok(sawProp, "property should be enumerable"); + +is(getter.call(document), document.documentElement, "the getter actually works"); + +Document.prototype.__defineSetter__('documentElement', function() {}); +is(getter.call(document), document.documentElement, "the getter works after defineSetter"); + +var oldTitle = document.title; +try { + var setter = document.__lookupSetter__('title'); + setter.call(document, "title 1"); + is(document.title, "title 1", "the setter is bound correctly"); +} finally { + document.title = oldTitle +} + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug478438.html b/js/xpconnect/tests/mochitest/test_bug478438.html new file mode 100644 index 0000000000..e64a1e89fb --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug478438.html @@ -0,0 +1,65 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=478438 +--> +<head> + <title>Test for Bug 478438</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + function fail(s, e) { ok(false, s + e) } + function pass(s, e) { ok(true, s) } + (pass.opposite = fail).opposite = pass; + + function test() { + if (test.calledAlready) + return; + test.calledAlready = true; + + var iwin = document.getElementById("f").contentWindow; + + function testOne(fn, onAllow, infinitive) { + try { fn(); onAllow("able " + infinitive, "") } + catch (e) { onAllow.opposite("unable " + infinitive, ": " + e) } + } + + testOne(() => iwin.focus, pass, + "to resolve/get allAccess property iwin.focus"); + + testOne(() => iwin.focus(), pass, + "to call allAccess method iwin.focus"); + + testOne(() => iwin.alert, fail, + "to resolve/get restricted property iwin.alert"); + + testOne(() => iwin.alert(), fail, + "to call restricted method iwin.alert"); + + testOne(() => iwin.location.toString(), fail, + "to call restricted method iwin.location.toString"); + + testOne(function() { iwin.location = "http://example.org" }, pass, + "to set writable property iwin.location"); + + SimpleTest.finish(); + } + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=478438">Mozilla Bug 478438</a> +<p id="display"></p> +<div id="content"> + <iframe id="f" src="http://example.com" onload="test()"></iframe> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 478438 **/ + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug484107.html b/js/xpconnect/tests/mochitest/test_bug484107.html new file mode 100644 index 0000000000..38ca7b207b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug484107.html @@ -0,0 +1,99 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=484107 +--> +<head> + <title>Test for Bug 484107</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=484107">Mozilla Bug 484107</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 484107 **/ + + var text = "first group", + xpcWin = new XPCSafeJSObjectWrapper(window); + function get$1() { return RegExp.$1 }; + + function reset() { + var match = /(.*)/.exec(text); + if (!reset.skipStupidTests) { + reset.skipStupidTests = true; + ok(match, "No match?"); + is(match[1], text, "Bad match?"); + is(text, RegExp.$1, "RegExp.$1 missing?"); + is(text, get$1(), "RegExp.$1 inaccessible?"); + } + } + + function test_XPC_SJOW_Call() { + isnot(text, xpcWin.get$1(), "Able to see RegExp.$1 from wrapped method."); + is("", xpcWin.get$1(), "Saw something other than an empty string for " + + "RegExp.$1 from wrapped method."); + is(text, window.get$1(), "Unable to see RegExp.$1 from non-wrapped method."); + } + + function test_XPC_SJOW_Call_foreign_obj() { + var obj = { + xpcGet: xpcWin.get$1, + rawGet: window.get$1 + }; + isnot(text, obj.xpcGet(), "obj.xpcGet() returned matched text."); + is("", obj.xpcGet(), "obj.xpcGet() returned something other than the empty string."); + is(text, obj.rawGet(), "obj.rawGet() did not return matched text."); + } + + function test_XPC_SJOW_toString() { + var str = new XPCSafeJSObjectWrapper({ + toString: function() { return RegExp.$1 } + }) + ""; + isnot(text, str, "toString() returned the matched text."); + is("", str, "toString() returned something other than the empty string."); + } + + function test_XPC_SJOW_GetOrSetProperty() { + window.__defineGetter__("firstMatch", function() { return RegExp.$1 }); + isnot(text, xpcWin.firstMatch, "Getter xpcWin.firstMatch returned matched text."); + is("", xpcWin.firstMatch, + "Getter xpcWin.firstMatch returned something other than the empty string."); + is(text, window.firstMatch, "Getter window.firstMatch did not return matched text."); + } + + function test_XPC_SJOW_Create() { + function ctor() { + this.match = RegExp.$1; + return this; // XXX Why is this necessary? + } + ctor.prototype.getMatch = function() { return this.match }; + var xpcCtor = new XPCSafeJSObjectWrapper(ctor), + match = (new xpcCtor).getMatch(); + isnot(text, match, "(new xpcCtor).getMatch() was the matched text."); + is("", match, "(new xpcCtor).getMatch() was not the empty string."); + } + + var tests = [ + test_XPC_SJOW_Call, + test_XPC_SJOW_Call_foreign_obj, + test_XPC_SJOW_toString, + test_XPC_SJOW_GetOrSetProperty, + test_XPC_SJOW_Create + ]; + + for (var i = 0; i < tests.length; i++) { + reset(); + tests[i](); + is(text, RegExp.$1, "RegExp.$1 was clobbered."); + } + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug500691.html b/js/xpconnect/tests/mochitest/test_bug500691.html new file mode 100644 index 0000000000..2ed127c099 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug500691.html @@ -0,0 +1,27 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=500691 +--> +<head> + <title>Test for Bug 500691</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=500691">Mozilla Bug 500691</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 500691 **/ +ok(Function === alert.constructor, "alert's constructor is our Function"); +ok(window.Function === alert.constructor, "window.Function is also correct"); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug505915.html b/js/xpconnect/tests/mochitest/test_bug505915.html new file mode 100644 index 0000000000..d5898bc1ed --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug505915.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=505915 +--> +<head> + <title>Test for Bug 505915</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=505915">Mozilla Bug 505915</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 505915 **/ +window.addEventListener("message", function () { + ok(false, "should not receive message"); +}); + +function go() { + var ifr = $('ifr'); + try { + // NB: the contentDocument getter now returns null for cross-origin + // frames, so use SpecialPowers to get a security wrapper to the document. + var xdoc = SpecialPowers.unwrap(SpecialPowers.wrap(ifr).contentDocument) + document.createTreeWalker(xdoc, 0, null); + ok(false, "should have thrown a security exception"); + } catch (e) { + ok(/TypeError: Document.createTreeWalker: Argument 1 does not implement interface Node/.test(e), + "threw a binding exception instead of an invalid child exception"); + } + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> + +<iframe id="ifr" onload="go();" src="http://test1.mochi.test:8888/"></iframe> + +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug560351.html b/js/xpconnect/tests/mochitest/test_bug560351.html new file mode 100644 index 0000000000..263e6850d7 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug560351.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=560351 +--> +<head> + <title>Test for Bug 560351</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=560351">Mozilla Bug 560351</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 560351 **/ +var pass = false; +try { + document.body.__lookupGetter__("lastChild")(); +} catch (e) { + pass = true; +} + +</script> +<script> + +ok(pass, "pass was set to true"); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug585745.html b/js/xpconnect/tests/mochitest/test_bug585745.html new file mode 100644 index 0000000000..758aeed30d --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug585745.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=585745 +--> +<head> + <title>Test for Bug 585745</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=585745">Mozilla Bug 585745</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 585745 **/ + + var a = document.createElementNS("http://www.w3.org/1998/Math/MathML", 'mrow'); + var b = document.createElementNS("http://www.w3.org/1999/xhtml", 'span'); + var htmlProto = Object.getPrototypeOf(b); + var mathMLProto = Object.getPrototypeOf(a); + // XXXbz once bug 560072 is fixed, we should be able to use + // getOwnPropertyDescriptor here. + Object.defineProperty(mathMLProto, "style", { + get: htmlProto.__lookupGetter__("style"), + }); + + var threw = false; + try { + a.style; + } catch(e) { + threw = true; + } + is(threw, true, + "Getting .style off a mathml element should throw in this case"); +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug589028.html b/js/xpconnect/tests/mochitest/test_bug589028.html new file mode 100644 index 0000000000..2cd0d15ebb --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug589028.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=589028 +--> +<head> + <title>Test for Bug 589028</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=589028">Mozilla Bug 589028</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script> + +/** Test for Bug 589028 **/ +SimpleTest.waitForExplicitFinish(); +var p = 0; +function go() { + var ifr = $('ifr'); + var ifrwin = ifr.contentWindow; + var ifrdoc = ifr.contentDocument; + + o1 = new ifrwin.Option(); + is(o1.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe"); + + o2 = ifrwin.getMyOption(); + is(o2.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe"); + + o3 = ifrwin.getCallersOption(this); + is(o3.ownerDocument, document); + + a1 = new ifrwin.Audio(); + is(a1.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe"); + + a2 = ifrwin.getMyAudio(); + is(a2.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe"); + + a3 = ifrwin.getCallersAudio(this); + is(a3.ownerDocument, document); + + i1 = new ifrwin.Image(); + is(i1.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe"); + + i2 = ifrwin.getMyImage(); + is(i2.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe"); + + i3 = ifrwin.getCallersImage(this); + is(i3.ownerDocument, document); + + SimpleTest.finish(); +} + + +</script> +</pre> +<iframe src="bug589028_helper.html" id="ifr" onload="go()"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug601299.html b/js/xpconnect/tests/mochitest/test_bug601299.html new file mode 100644 index 0000000000..cd726d7974 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug601299.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=601299 + +Trigger a fastnative from a frameless context. +--> +<head> + <title>Test for Bug 601299</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="window.setTimeout(RegExp, 0); window.setTimeout(function() { ok(true); SimpleTest.finish(); }, 0);"> +<script> +SimpleTest.waitForExplicitFinish(); +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug605167.html b/js/xpconnect/tests/mochitest/test_bug605167.html new file mode 100644 index 0000000000..ba625aa805 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug605167.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=505915 +--> +<head> + <title>Test for Bug 505915</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=505915">Mozilla Bug 505915</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 505915 **/ +var url = "file_bug605167.html"; +var targetUrl = "http://example.com"; +var f; + +var p = 0; +function go() { + switch (++p) { + case 1: + frames[0].location = url; + break; + case 2: + frames[0].location = targetUrl; + break; + case 3: + try { + f().cross_origin_property; + ok(false, "should have thrown an exception"); + } catch (e) { + ok(/Permission denied/.test(e) || /attempt to run compile-and-go script/.test(e), + "threw the correct exception"); + } + SimpleTest.finish(); + break; + } +} + + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> + +<iframe id="ifr" onload="go();"></iframe> + +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug618017.html b/js/xpconnect/tests/mochitest/test_bug618017.html new file mode 100644 index 0000000000..8bfb428870 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug618017.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=618017 + +Parsing XML must not override the version. +--> +<head> + <title>Test for Bug 618017</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + +<script type='application/javascript'> +let x = 12; +function doLetEval() { + ok(eval('let x = 13; x') === 13, 'let statement is valid syntax in version 1.7'); +} +</script> + +<script type='application/javascript'> +doLetEval(); // Call to a function with a different version. +</script> + +</body> +</html> + diff --git a/js/xpconnect/tests/mochitest/test_bug623437.html b/js/xpconnect/tests/mochitest/test_bug623437.html new file mode 100644 index 0000000000..0cea6f330b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug623437.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=623437 +--> +<head> + <title>Test for Bug 623437</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=623437">Mozilla Bug 623437</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 623437 **/ + var c = document.createElement("canvas").getContext("2d"); + var seenArcToFirst; + var seenArc = false; + var seenArcTo = false; + for (var i in c) { + if (i == "arc") { + seenArc = true; + if (!seenArcTo) + seenArcToFirst = false; + } + if (i == "arcTo") { + seenArcTo = true; + if (!seenArc) + seenArcToFirst = true; + } + } + is(seenArc, true, "Should see arc"); + is(seenArcTo, true, "Should see arcTo"); + is(seenArcToFirst, true, "Should see arcTo before arc"); +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug628410.html b/js/xpconnect/tests/mochitest/test_bug628410.html new file mode 100644 index 0000000000..2aec713793 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug628410.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=628410 +--> +<head> + <title>Test for Bug 628410</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=628410">Mozilla Bug 628410</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> + +<pre id="test"> +<script type="application/javascript"> + +window.toString(); + +if (SpecialPowers.Services.prefs.getBoolPref("extensions.InstallTrigger.enabled") && + SpecialPowers.Services.prefs.getBoolPref("extensions.InstallTriggerImpl.enabled")) { + InstallTrigger + ""; +} + +console + ""; +ok(true, "Things didn't throw"); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug628794.html b/js/xpconnect/tests/mochitest/test_bug628794.html new file mode 100644 index 0000000000..9cbfe0f436 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug628794.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=585745 +--> +<head> + <title>Test for Bug 585745</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=585745">Mozilla Bug 585745</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 585745 **/ + + var a = document.createElementNS("http://www.w3.org/2000/svg", 'svg'); + var b = document.createElementNS("http://www.w3.org/1999/xhtml", 'span'); + var htmlProto = Object.getPrototypeOf(b); + var svgProto = Object.getPrototypeOf(a); + // XXXbz once bug 560072 is fixed, we should be able to use + // getOwnPropertyDescriptor here. + Object.defineProperty(svgProto, "style", { + get: htmlProto.__lookupGetter__("style"), + }); + + var threw = false; + try { + a.style; + } catch(e) { + threw = true; + } + is(threw, true, + "Getting .style off an svg element should throw in this case"); +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug629227.html b/js/xpconnect/tests/mochitest/test_bug629227.html new file mode 100644 index 0000000000..6d01c37ec0 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug629227.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=629227 +--> +<head> + <title>Test for Bug 629227</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=629227">Mozilla Bug 629227</a> +<p id="display"> + <iframe id="testTarget"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 629227 **/ +SimpleTest.waitForExplicitFinish(); + +$("testTarget").src = + "http://test1.example.org" + + location.pathname.replace(/test_bug629227.html/, "file1_bug629227.html"); + +window.onmessage = function(ev) { + if (ev.data == "finish") { + SimpleTest.finish(); + } else { + var data = JSON.parse(ev.data); + if ("ok" in data) { + ok(data.ok, data.reason); + } + } +} + +addLoadEvent(function() { + $("testTarget").contentWindow.postMessage("start", "*"); +}); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug629331.html b/js/xpconnect/tests/mochitest/test_bug629331.html new file mode 100644 index 0000000000..17520b187f --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug629331.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=629331 +--> +<head> + <title>Test for Bug 629331</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=629331">Mozilla Bug 629331</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +function handler(event) { + var obj = JSON.parse(event.data); + if (obj.fun == "finish") { + SimpleTest.finish(); + } else { + is(obj.a, obj.b, obj.description); + } +} + +window.addEventListener('message', handler); + +</script> +<iframe src="http://test1.example.org/tests/js/xpconnect/tests/mochitest/test1_bug629331.html"> +</iframe> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug636097.html b/js/xpconnect/tests/mochitest/test_bug636097.html new file mode 100644 index 0000000000..8ae8e4822e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug636097.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=504877 +test by moz_bug_r_a4@yahoo.com +--> +<head> + <title>Test for Bug 504877</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=504877">Mozilla Bug 504877</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 504877 **/ +SimpleTest.waitForExplicitFinish(); + +var targetUrl = "http://example.com/"; +var l; + +function a() { + var r = "FAIL", s; + try { + s = l.toString(); + } + catch (e) { + if (/denied|insecure/.test(e)) + r = "PASS"; + s = e; + } + + is(r, "PASS", "should have thrown an exception"); + SimpleTest.finish(); +} + +var p = 0; +function b() { + switch (++p) { + case 1: + frames[0].location = "about:blank"; + break; + case 2: + l = frames[0].location; + frames[0].location = targetUrl; + break; + case 3: + a(); + break; + } +} +</script> + +</pre> +<iframe onload="b()"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug650273.html b/js/xpconnect/tests/mochitest/test_bug650273.html new file mode 100644 index 0000000000..18e029982a --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug650273.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=650273 +test by moz_bug_r_a4@yahoo.com +--> +<head> + <title>Test for Bug 650273</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" +href="https://bugzilla.mozilla.org/show_bug.cgi?id=650273">Mozilla Bug 650273</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 504877 **/ +SimpleTest.waitForExplicitFinish(); +var count = 0; +function done() { + if (++count == 2) { + try { + ok($('ifr').location.host === 'example.com', "shouldn't see this"); + } catch (e) { + ok(true, "navigation successfully happened"); + } + SimpleTest.finish(); + } +} + +</script> + +<iframe id="ifr" src="file_bug650273.html" onload="done()"></iframe> + +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug655297-1.html b/js/xpconnect/tests/mochitest/test_bug655297-1.html new file mode 100644 index 0000000000..38ff528c5b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug655297-1.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=655297 +--> +<head> + <title>Test for Bug 655297</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=655297">Mozilla Bug 655297</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> + <form>0</form> <form>1</form> <form>2</form> <form>3</form> <form>4</form> + <form>5</form> <form>6</form> <form>7</form> <form>8</form> <form>9</form> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 655297 **/ + +var map = new WeakMap(); +function f() { + var paras = document.getElementsByTagName("form"); + for (var i = 0; i < paras.length; i++) + map.set(paras[i], "ok"); +} +function g() { + var paras = document.getElementsByTagName("form"); + for (var i = 0; i < paras.length; i++) { + if (map.get(paras[i]) != "ok") { + return false; + } + } + return true; +} + +f(); +SpecialPowers.forceGC(); +ok(g(), "Failed to keep XPCWrappedNative used as WeakMap key alive."); + +</script> + + +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug655297-2.html b/js/xpconnect/tests/mochitest/test_bug655297-2.html new file mode 100644 index 0000000000..67da7964bd --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug655297-2.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=655297 +--> +<head> + <title>Test for Bug 655297</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=655297">Mozilla Bug 655297</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> + <p>0</p> <p>1</p> <p>2</p> <p>3</p> <p>4</p> + <p>5</p> <p>6</p> <p>7</p> <p>8</p> <p>9</p> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 655297 **/ + +var map = new WeakMap(); +function f() { + var paras = document.getElementsByTagName("p"); + for (var i = 0; i < paras.length; i++) + map.set(paras[i], "ok"); +} +function g() { + var paras = document.getElementsByTagName("p"); + for (var i = 0; i < paras.length; i++) { + if (map.get(paras[i]) != "ok") { + return false; + } + } + return true; +} + +f(); +SpecialPowers.forceGC(); +ok(g(), "Failed to keep XPCWrappedNative used as WeakMap key alive."); + +</script> + + +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug661980.html b/js/xpconnect/tests/mochitest/test_bug661980.html new file mode 100644 index 0000000000..afe62559a5 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug661980.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=661980 +--> +<head> + <title>Test for Bug 661980</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=661980">Mozilla Bug 661980</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 661980 **/ + +// While not currently needed, make this as similar as possible to a real +// EventTarget just to make sure that we're tripping on the wrapping and +// nothing else. +var fakeTarget = { + addEventListener: function() {}, + removeEventListener: function() {}, + dispatchEvent: function() {} +} + +var mouseevent = document.createEvent("MouseEvent"); +var didThrow = false; +dump("hello nurse\n"); +try { + mouseevent.initMouseEvent("mouseover", + false, false, + window, + 1, 2, 3, 4, 5, + false, false, false, false, + 0, + fakeTarget); +} +catch (ex) { + didThrow = true; +} +ok(didThrow, "should not be able to implement EventTarget using script"); + +mouseevent.initMouseEvent("mouseout", + false, false, + window, + 1, 2, 3, 4, 5, + false, false, false, false, + 0, + document.body); +is(mouseevent.type, "mouseout", + "should able to implement EventTarget using Element"); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug691059.html b/js/xpconnect/tests/mochitest/test_bug691059.html new file mode 100644 index 0000000000..b00da02b0d --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug691059.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=691059 +--> +<head> + <title>Test for Bug 691059</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=691059">Mozilla Bug 691059</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + + +/** Test for Bug 691059 **/ + +function f() {} + +function testEventTarget(obj) { + obj.onmouseenter = f; + is(obj.onmouseenter, f, + "onmouseenter should be settable"); + obj.onmouseleave = f; + is(obj.onmouseleave, f, + "onmouseenter should be settable"); +} + +function testInterface(obj) { + try { + obj.prototype.onmouseenter = f; + is("onmouseenter" in obj, false, + "setting <Interface>.prototype.onmouseenter has no effect on the " + + "non-existent <Interface>.onmouseenter"); + obj.prototype.onmouseleave = f; + is("onmouseleave" in obj, false, + "setting <Interface>.prototype.onmouseleave has no effect on the " + + "non-existent <Interface>.onmouseleave"); + } catch(ex) { + ok(false, ex); + } +} + +testEventTarget(window); +testEventTarget(document); +testEventTarget(document.documentElement); + +testInterface(Document); +testInterface(HTMLElement); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug720619.html b/js/xpconnect/tests/mochitest/test_bug720619.html new file mode 100644 index 0000000000..804ec96d75 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug720619.html @@ -0,0 +1,55 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=720619 +--> +<head> + <title>Test for Bug 629227</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=720619">Mozilla Bug 720619</a> +<p id="display"> + <iframe id="testTarget"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 720619 **/ +SimpleTest.waitForExplicitFinish(); + +function checkThrows(f, exception) { + try { + f(); + ok(false, "should have thrown: " + f); + } catch (e) { + ok(exception.test(e.toString()), "correctly threw"); + } +} + +function go() { + var loc = $('ifr').contentWindow.location; + checkThrows(function() {loc + '';}, /Permission denied/); + checkThrows(function() {'' + loc;}, /Permission denied/); + checkThrows(function() {String(loc);}, /Permission denied/); + + var win = $('ifr').contentWindow; + checkThrows(function() {win + '';}, /Permission denied/); + checkThrows(function() {'' + win;}, /Permission denied/); + checkThrows(function() {String(win);}, /Permission denied/); + + SimpleTest.finish(); +} + +</script> + +<iframe id="ifr" onload="go()" + src="http://example.org/tests/js/xpconnect/tests/mochitest/file_bug720619.html"> +</iframe> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug731471.html b/js/xpconnect/tests/mochitest/test_bug731471.html new file mode 100644 index 0000000000..e74b07734a --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug731471.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=731471 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 731471</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="setTimeout(boom, 0);"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=731471">Mozilla Bug 731471</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 731471. This is effectively a crashtest, but it uses window.open, which + doesn't work in the crashtest harness. **/ +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); +function boom() +{ + w = window.open("file_bug731471.html"); + setTimeout(function() { + w.document.write("2"); + w.document.close(); + w.document.write("3 - Done"); + w.document.close(); + w.close(); + ok(true, "Didn't assert!"); + SimpleTest.finish(); + }, 400); +} + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug764389.html b/js/xpconnect/tests/mochitest/test_bug764389.html new file mode 100644 index 0000000000..6e90dd448b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug764389.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=764389 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 764389</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=764389">Mozilla Bug 764389</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 764389 **/ + +// This is basically a crash test, but we need to write a mochitest so that it +// runs with http:// urls instead of file:// urls. +SimpleTest.waitForExplicitFinish(); + +function go() { + var ifr = document.getElementById('ifr'); + ifr.contentDocument.open(); + ok(true, "Didn't crash"); + ifr.contentDocument.close(); + SimpleTest.finish(); +} + + + +</script> +<iframe id="ifr" onload="go();" src="file_empty.html"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug772288.html b/js/xpconnect/tests/mochitest/test_bug772288.html new file mode 100644 index 0000000000..5af0f7d2d6 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug772288.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=772288 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 772288</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="doTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=772288">Mozilla Bug 772288</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 772288 **/ +SimpleTest.waitForExplicitFinish(); + +const Cu = SpecialPowers.Cu; + +function doTest() { + msg = "AppConstants should be imported on window"; + try { + Cu.import("resource://gre/modules/AppConstants.jsm", window); + ok(AppConstants, msg); + } catch (ex) { + ok(false, msg + " : " + ex); + } + + msg = "AppConstants should be imported on myObj"; + try { + var myObj = {}; + Cu.import("resource://gre/modules/AppConstants.jsm", myObj); + ok(myObj.AppConstants, msg); + } catch (ex) { + ok(false, msg + " : " + ex); + } + + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug781476.html b/js/xpconnect/tests/mochitest/test_bug781476.html new file mode 100644 index 0000000000..f9ab40d4d9 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug781476.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=781476 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 781476</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=781476">Mozilla Bug 781476</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 781476 **/ +SimpleTest.waitForExplicitFinish(); + +function go() { + var iwin = document.getElementById('ifr').contentWindow; + iwin.is = is; + var evt = iwin.makeEvent(); + is(evt.expando, 42, "Expando properly visible in caller frame"); + SimpleTest.finish(); +} + + +</script> +</pre> +<iframe onload="go();" id="ifr" src="file_bug781476.html"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug789713.html b/js/xpconnect/tests/mochitest/test_bug789713.html new file mode 100644 index 0000000000..251ecf22c2 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug789713.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=789713 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 789713</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=789713">Mozilla Bug 789713</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe id="ifr"></iframe> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 789713 **/ + +// We can't set document.domain on mochi.test, because it's forbidden to set +// document.domain to a TLD. +var ifr = document.getElementById('ifr'); + +SimpleTest.waitForExplicitFinish(); +ifr.src = window.location.toString().replace("mochi.test:8888", "test1.example.org") + .replace("test_bug789713", "file_bug789713") + .split('?')[0]; +window.onmessage = function(message) { + ok(message.data, "Test succeeded and didn't crash"); + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug790732.html b/js/xpconnect/tests/mochitest/test_bug790732.html new file mode 100644 index 0000000000..c702273900 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug790732.html @@ -0,0 +1,55 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=790732 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 790732</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +async function doTest() { + await SpecialPowers.pushPrefEnv({set: [["dom.use_components_shim", true]]}) + + // Basic stuff + ok(Components, "Components shim exists!"); + var Ci = Components.interfaces; + ok(Ci, "interfaces shim exists!"); + is(typeof Components.classes, 'undefined', "Shouldn't have a Cc"); + + // Check each interface that we shim. We start by checking specific + // constants for a couple of interfaces, and then once it's pretty clear that + // it's working as intended we just check that the objects themselves are the + // same. + is(Ci.nsIXMLHttpRequest.HEADERS_RECEIVED, XMLHttpRequest.HEADERS_RECEIVED); + is(Ci.nsIDOMNode.DOCUMENT_NODE, Node.DOCUMENT_NODE); + is(Ci.nsIDOMKeyEvent, KeyEvent); + is(Ci.nsIDOMMouseEvent, MouseEvent); + is(Ci.nsIDOMMouseScrollEvent, MouseScrollEvent); + is(Ci.nsIDOMMutationEvent, MutationEvent); + is(Ci.nsIDOMUIEvent, UIEvent); + is(Ci.nsIDOMHTMLMediaElement, HTMLMediaElement); + is(Ci.nsIDOMRange, Range); + is(Ci.nsIDOMNodeFilter, NodeFilter); + is(Ci.nsIDOMXPathResult, XPathResult); + + SimpleTest.finish(); +} + +doTest(); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=790732">Mozilla Bug 790732</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +<iframe id="ifr"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug793969.html b/js/xpconnect/tests/mochitest/test_bug793969.html new file mode 100644 index 0000000000..1d06d65904 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug793969.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=793969 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 793969</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=793969">Mozilla Bug 793969</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 793969 **/ +function checkThrows(f, desc, skipMessageCheck) { + try { + f(); + ok(false, "Should have thrown for " + desc); + } catch (e) { + ok(true, "threw correctly"); + if (!skipMessageCheck) + ok(/denied/.exec(e) || + /can't redefine non-configurable property/.exec(e), + "Correctly threw a security exception: " + e); + } +} + +// NB: These sets will be no-ops (throw in strict mode) because setting an inherited readonly value prop has those semantics. +checkThrows(function() { "use strict"; location.valueOf = 'hah'; }, 'Shadow with string', /* skipMessageCheck = */ true); +checkThrows(function() { "use strict"; location.valueOf = function() { return {a: 'hah'};} }, 'Shadow with function', /* skipMessageCheck = */ true); +checkThrows(function() { Object.defineProperty(location, 'valueOf', { value: function() { return 'hah'; } }); }, 'defineProperty with value'); +checkThrows(function() { delete location.valueOf; Object.defineProperty(location, 'valueOf', { value: function() { return 'hah'; } }); }, 'delete + defineProperty with value'); +checkThrows(function() { Object.defineProperty(location, 'valueOf', { get: function() { return 'hah'; } }); }, 'defineProperty with getter'); +checkThrows(function() { delete location.valueOf; Object.defineProperty(location, 'valueOf', { get: function() { return 'hah'; } }); }, 'delete + defineProperty with getter'); + +Object.prototype.valueOf = function() { return 'hah'; }; +is(({}).valueOf(), 'hah', "Shadowing on Object.prototype works for vanilla objects"); +is(location.valueOf(), location, "Shadowing on Object.prototype and Location.prototype doesn't for location objects"); + +location[Symbol.toPrimitive] = function() { return 'hah'; } +is(location + "", location.toString(), "Should't be able to shadow with toPrimitive"); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug800864.html b/js/xpconnect/tests/mochitest/test_bug800864.html new file mode 100644 index 0000000000..4acee755f5 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug800864.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=800864 +--> +<head> + <title>Test for Bug 800864</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=800864">Mozilla Bug 800864</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +function checkThrows(f) { + try { + f(); + ok(false, "Didn't throw a security exception like we should"); + } catch(e) { + ok(/denied|insecure/.exec(e), "Should throw security exception. Got: " + e); + } +} + +function go() { + ifr = document.getElementById('ifr'); + win = ifr.contentWindow; + loc = win.location; + ifr.onload = check; + win.location = 'http://test1.example.com'; +} + +function check() { + checkThrows(function() { loc.toString(); }); + checkThrows(function() { loc.valueOf().toString(); }); + checkThrows(function() { loc.href; }); + checkThrows(function() { loc + ''; }); + SimpleTest.finish(); +} + +</script> +</pre> +</body> +<iframe id="ifr" onload="go()" src="file_empty.html"></iframe> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug802557.html b/js/xpconnect/tests/mochitest/test_bug802557.html new file mode 100644 index 0000000000..4479986b8e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug802557.html @@ -0,0 +1,116 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=802557 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 802557</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 802557 **/ + SimpleTest.waitForExplicitFinish(); + + function checkThrows(fun, desc) { + try { + fun(); + ok(false, "Didn't throw when " + desc); + } catch(e) { + ok(true, "Threw when " + desc + " " + e); + ok(/denied|insecure/.exec(e), "Should be security exception"); + } + } + + var loadCount = 0; + function go() { + ++loadCount; + window.ifr = document.getElementById('ifr'); + window.iWin = ifr.contentWindow; + + if (loadCount == 1) { + gLoc = iWin.location; + // Note that accessors pulled off Xrays are currently bound. This is bug 658909. + // [getter, description, locationObj, bound] + gGetters = [[ location.toString, 'toString from LW' ], + [ gLoc.toString, 'toString from XLW' ], + [ Object.__lookupGetter__.call(location, 'href'), 'href getter from LW' ], + [ Object.__lookupGetter__.call(gLoc, 'href'), 'href getter from XLW' ], + [ Object.getOwnPropertyDescriptor(location, 'href').get, 'href getter from location' ], + [ Object.getOwnPropertyDescriptor(gLoc, 'href').get, 'href getter from iWin.location' ], + [ function() { return this + ''; }, 'implicit conversion via [[DefaultValue]]', /* doMessageCheck = */ true ]]; + gGetters.forEach(function(item) { + try { + is(item[0].call(location), location.toString(), 'Same-origin LW: ' + item[1]); + is(item[0].call(gLoc), gLoc.toString(), 'Same-origin XLW: ' + item[1]); + } catch (e) { + ok(false, "Threw while applying " + item[1] + " to same-origin location object: " + e); + } + }); + ifr.src = "http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"; + } + else if (loadCount == 2) { + gGetters.forEach(function(item) { + checkThrows(function() { item[0].call(gLoc); }, + 'call()ing ' + item[1] + ' after navigation cross-origin'); + }); + ifr.src = 'http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug802557.html'; + } + else if (loadCount == 3) { + gTestFunctions = ifr.contentWindow.getAllTests(); + var win = ifr.contentWindow; + for (fun in gTestFunctions) + is(gTestFunctions[fun](), win.location.toString(), "allowed via " + fun); + win.location = 'http://example.org/tests/js/xpconnect/tests/mochitest/file_bug802557.html'; + } + else if (loadCount == 4) { + for (fun in gTestFunctions) { + var f = gTestFunctions[fun]; + checkThrows(f, "calling " + fun); + } + + // Verify that URL.prototype.toString can't be applied to Location + var threw = false; + try { + URL.prototype.toString.call(location); + } catch (e) { + threw = true; + } + ok(threw, + "Should not be able to use URL.prototype.toString on a Location instance"); + + // Verify that URL.prototype.href getter can't be applied to Location + threw = false; + var reachedTest = false; + try { + var get = Object.getOwnPropertyDescriptor(URL.prototype, "href").get; + is(typeof(get), "function", "Should have an href getter on URL.prototype"); + var reachedTest = true; + get.call(location); + } catch (e) { + threw = true; + } + ok(reachedTest, + "Should not be able to find URL.prototype.href getter"); + ok(threw, + "Should not be able to use URL.prototype.href getter on a Location instance"); + SimpleTest.finish(); + } + } + + + +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=802557">Mozilla Bug 802557</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<iframe id="ifr" onload="go();" src="file_empty.html"></iframe> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug803730.html b/js/xpconnect/tests/mochitest/test_bug803730.html new file mode 100644 index 0000000000..88df8d5477 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug803730.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=803730 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 803730</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=803730">Mozilla Bug 803730</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 803730 **/ +var foo = { + isNode: function(obj) { + return !!(obj instanceof Node); + } +}; + +var elem = document.createElement("span"); +var trueCount = 0, + falseCount = 0; +for (var x = 0; x < 100000; x++) { + if (foo.isNode(elem)) + trueCount++; + else + falseCount++; +} +is(falseCount, 0, "elem instanceof Node working correctly."); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug809547.html b/js/xpconnect/tests/mochitest/test_bug809547.html new file mode 100644 index 0000000000..17808867d6 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug809547.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=809547 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 809547</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="go()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=809547">Mozilla Bug 809547</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 809547 **/ +SimpleTest.waitForExplicitFinish(); +var gObj = {}; +function go() { + window.location.expando = gObj; + is(window.location.expando, gObj, "Expando appears"); + SimpleTest.executeSoon(finish); +} + +function finish() { + SpecialPowers.forceGC(); + SpecialPowers.forceCC(); + SpecialPowers.forceGC(); + SpecialPowers.forceCC(); + is(window.location.expando, gObj, "Expando preserved"); + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug829872.html b/js/xpconnect/tests/mochitest/test_bug829872.html new file mode 100644 index 0000000000..07e2a4ca77 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug829872.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=829872 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 829872</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 829872 and Bug 968003 **/ + SimpleTest.waitForExplicitFinish(); + + var gLoadCount = 0; + function loaded() { + if (++gLoadCount == 3) + go(); + } + + async function check(elem, desc) { + is(elem.contentDocument, null, "null cross-origin contentDocument for " + desc); + ok(await SpecialPowers.spawn(elem, [], () => this.content.eval('frameElement === null;')), + "null cross-origin frameElement for " + desc); + if (!(elem instanceof elem.ownerDocument.defaultView.HTMLFrameElement)) + is(elem.getSVGDocument(), null, "null cross-origin getSVGDocument() for " + desc); + } + + async function go() { + ok(true, "Starting test"); + await check($('ifr'), "iframe element"); + await check($('obj'), "object element"); + await check($('framesetholder').contentDocument.getElementById('fr'), "frameset frame"); + SimpleTest.finish(); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=829872">Mozilla Bug 829872</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +<iframe id="ifr" onload="loaded();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +<object id="obj" onload="loaded();" data="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></object> +<iframe id="framesetholder" srcdoc="<html><head></head><frameset cols='100%'><frame id='fr' onload='parent.loaded();' src='http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html' /></frameset></html>"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug862380.html b/js/xpconnect/tests/mochitest/test_bug862380.html new file mode 100644 index 0000000000..d604e3d05f --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug862380.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=862380 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 862380</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 862380 **/ + SimpleTest.waitForExplicitFinish(); + function go() { + checkNotEnumerable($('ifr').contentWindow, true); + checkNotEnumerable($('ifr').contentWindow.location, false); + SimpleTest.finish(); + } + +function checkNotEnumerable(obj, isWindow) { + try { + const expectedWindow = ["0"]; + const expectedLocation = []; + const expected = isWindow ? expectedWindow : expectedLocation; + is(Object.keys(obj).length, expected.length, + "Object.keys gives right array length"); + var actual = []; + for (var i in obj) + actual.push(i); + is(actual.length, expected.length, + "Enumeration sees the right number of props"); + actual.sort(); + expected.sort(); + for (var i = 0; i < actual.length; ++i) + is(actual[i], expected[i], "Arrays should be the same " + i); + } catch (e) { + ok(false, "threw: " + e); + } + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=862380">Mozilla Bug 862380</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug865260.html b/js/xpconnect/tests/mochitest/test_bug865260.html new file mode 100644 index 0000000000..b09b488dcd --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug865260.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=865260 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 865260</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 865260 **/ + SimpleTest.waitForExplicitFinish(); + function go() { + var exn = "nothrow"; + try { $('ifr').contentWindow['Date']; } catch (e) { exn = e; }; + ok(!!/denied/.exec(exn), "Threw instead of crashing"); + SimpleTest.finish(); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=865260">Mozilla Bug 865260</a> +<p id="display"></p> +<div id="content"> +<iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug871887.html b/js/xpconnect/tests/mochitest/test_bug871887.html new file mode 100644 index 0000000000..082b2ae746 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug871887.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=871887 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 871887</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 871887 **/ + SimpleTest.waitForExplicitFinish(); + + // NB: onstart ends up getting invoked twice, for mysterious and potentially- + // IE6-related reasons. + function checkpoint(invocant) { + ok(true, "onstart called"); + is(invocant, $('llama'), "this-binding is correct"); + $('llama').loop = 1; + $('llama').scrollDelay = 1; + $('llama').scrollAmount = 500; + } + + function done(invocant) { + is(invocant, $('llama'), "this-binding is correct"); + ok(true, "onfinish called"); + SimpleTest.finish(); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=871887">Mozilla Bug 871887</a> +<p id="display"></p> +<div id="content"> +<marquee id="llama" onstart="checkpoint(this);" onfinish="done(this);">Watch the Llama</marquee> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug912322.html b/js/xpconnect/tests/mochitest/test_bug912322.html new file mode 100644 index 0000000000..011c4a8f4e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug912322.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=912322 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 912322</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + var { AppConstants } = SpecialPowers.ChromeUtils.import( + "resource://gre/modules/AppConstants.jsm" + ); + // Test window.controllers. + if (AppConstants.RELEASE_OR_BETA) { + is(typeof window.controllers, 'object', "shimmed controllers should be available to content in beta and release"); + } else { + is(typeof window.controllers, 'undefined', "controllers should not be available to content in Nightly"); + } + is(typeof SpecialPowers.wrap(window).controllers, 'object', "controllers should be available over Xray"); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=912322">Mozilla Bug 912322</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug916945.html b/js/xpconnect/tests/mochitest/test_bug916945.html new file mode 100644 index 0000000000..01c342eea1 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug916945.html @@ -0,0 +1,78 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=916945 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 916945</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 916945 **/ + SimpleTest.waitForExplicitFinish(); + + var gLoadCount = 0; + function loaded() { + if (++gLoadCount == 2) + go(); + } + async function go() { + // Both same-origin and cross-origin names should be visible if they're set + // on the iframe element. + ok('winA' in window, "same-origin named access works"); + ok(winA instanceof winA.Window, "same-origin named access works"); + ok('winB' in window, "cross-origin named access works when iframe name matches"); + is(winB.parent, window, "cross-origin named access works when iframe name matches"); + + // Setting the 'name' attribute should propagate to the docshell. + var ifrB = document.getElementById('ifrB'); + await SpecialPowers.spawn(ifrB, [], () => { + Assert.equal(this.content.name, 'winB', + 'initial attribute value propagates to the docshell'); + }); + + ifrB.setAttribute('name', 'foo'); + await SpecialPowers.spawn(ifrB, [], () => { + Assert.equal(this.content.name, 'foo', + 'attribute sets propagate to the docshell'); + }); + ok('foo' in window, "names are dynamic if updated via setAttribute"); + is(foo.parent, window, "names are dynamic if updated via setAttribute"); + + // Setting window.name on the subframe should not propagate to the attribute. + await SpecialPowers.spawn(ifrB, [], () => { + this.content.name = "bar"; + }); + is(ifrB.getAttribute('name'), 'foo', 'docshell updates dont propagate to the attribute'); + + // When the frame element attribute and docshell name don't match, nothing is returned. + ok(!('foo' in window), "frame element name not resolved if it doesn't match the docshell"); + ok(!('bar' in window), "docshell name not resolved if it doesn't match the frame element"); + + // This shouldn't assert. + function listener() { + document.body.appendChild(ifrA); + ifrA.name = ""; + } + ifrA.addEventListener("DOMNodeInserted", listener, {once: true}); + document.body.appendChild(ifrA); + + SimpleTest.finish(); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=916945">Mozilla Bug 916945</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<iframe id="ifrA" name="winA" onload="loaded();" src="file_empty.html"></iframe> +<iframe id="ifrB" name="winB" onload="loaded();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug92773.html b/js/xpconnect/tests/mochitest/test_bug92773.html new file mode 100644 index 0000000000..b1172f377e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug92773.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=92773 +--> +<head> + <title>Test for Bug 92773</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=92773">Mozilla Bug 92773</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> + +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 92773 **/ +function go() { + try { + $('ifr').contentWindow.foo; + ok(false, "able to access cross-origin getter"); + } catch (e) { + ok(/Permission denied/.exec(e), "unable to access cross-origin getter"); + } + + SimpleTest.finish(); +} +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> + +<iframe id='ifr' + src='http://example.com/tests/js/xpconnect/tests/mochitest/bug92773_helper.html' + onload="go()"> +</iframe> + +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug940783.html b/js/xpconnect/tests/mochitest/test_bug940783.html new file mode 100644 index 0000000000..0c87e710c1 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug940783.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=940783 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 940783</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 940783 **/ + SimpleTest.waitForExplicitFinish(); + + function checkHistoryThrows(hist) { + checkThrows(function() { hist.length; }); + checkThrows(function() { hist.state; }); + checkThrows(function() { hist.go(); }); + checkThrows(function() { hist.back(); }); + checkThrows(function() { hist.forward(); }); + checkThrows(function() { hist.pushState({}, "foo"); }); + checkThrows(function() { hist.replaceState({}, "foo"); }); + + } + + window.gLoads = 0; + function load() { + var iwin = $('ifr').contentWindow; + ++gLoads; + if (gLoads == 1) { + window.gHist = iwin.history; + iwin.location = "file_empty.html"; + } else if (gLoads == 2) { + checkHistoryThrows(gHist); + window.gHist = iwin.history; + iwin.location = "http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"; + } else { + checkHistoryThrows(gHist); + $('ifr').setAttribute('onload', null); + SimpleTest.finish(); + } + } + + function checkThrows(fn) { + try { fn(); ok(false, "Should have thrown: " + fn.toSource()); } + catch (e) { ok(!!/denied|insecure/.exec(e), "Threw correctly: " + e); } + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=940783">Mozilla Bug 940783</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe id="ifr" onload="load();" src="file_empty.html"></iframe> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug960820.html b/js/xpconnect/tests/mochitest/test_bug960820.html new file mode 100644 index 0000000000..7667fde624 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug960820.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=960820 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 960820</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for exception stacks crossing **/ + + // Synchronous event dispatch creates a new script entry point. At the time + // of this writing, an event listener defined in a Sandbox will cause the + // SafeJSContext to be pushed to the cx stack, which differs from the JSContext + // associated with this DOM window. So we test both kinds of boundaries. + var sb = new SpecialPowers.Cu.Sandbox(SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal()); + sb.win = window; + SpecialPowers.Cu.evalInSandbox("win.document.addEventListener('click', " + + "function clickHandler() { win.wrappedJSObject.clickCallback(); });", sb); + function clickCallback() { + var stack = (new Error()).stack; + ok(true, "Invoked clickCallback. Stack: " + stack); + ok(/clickCallback/.test(stack), "clickCallback should be in the stack"); + ok(!/clickHandler/.test(stack), "clickHandler should not be in the stack"); + ok(/dispatchClick/.test(stack), "dispatchClick should be in the stack"); + + // Check Components.stack, but first filter through the SpecialPowers junk. + var stack = SpecialPowers.wrap(SpecialPowers.Components).stack; + while (/testing-common/.test(stack)) { + stack = stack.caller; + } + ok(/clickCallback/.test(stack), "clickCallback should be reachable via Components.stack"); + ok(/clickHandler/.test(stack.caller), "clickHandler should be reachable via Components.stack"); + ok(/dispatchClick/.test(stack.caller.caller), "dispatchClick hould be reachable via Components.stack"); + } + function dispatchClick() { + document.dispatchEvent(new MouseEvent('click')); + } + dispatchClick(); + + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=960820">Mozilla Bug 960820</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug965082.html b/js/xpconnect/tests/mochitest/test_bug965082.html new file mode 100644 index 0000000000..b2320b52c7 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug965082.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=965082 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 965082</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 965082 **/ + SimpleTest.waitForExplicitFinish(); + + function checkThrows(f, msg) { + try { f(); ok(false, "Should have thrown: " + msg); } + catch (e) { ok(/denied|insecure|can't set prototype/.test(e), "Should throw security exception: " + e + " (" + msg + ")"); } + } + + function go() { + var protoSetter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set; + checkThrows(function() { protoSetter.call(window[0], new Object()); }, "Setting cross-origin Window prototype"); + checkThrows(function() { protoSetter.call(window[0].location, new Object()); }, "Setting cross-origin Location prototype"); + SimpleTest.finish(); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=965082">Mozilla Bug 965082</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug993423.html b/js/xpconnect/tests/mochitest/test_bug993423.html new file mode 100644 index 0000000000..dbe4cef3cc --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug993423.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=993423 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 993423</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 993423 **/ + SimpleTest.waitForExplicitFinish(); + + var sCallbackInvocations = 0; + function callback(handlerIsInXBLScope) { + ok(!handlerIsInXBLScope, "Event handler should not be in XBL scope"); + if (++sCallbackInvocations == 2) + SimpleTest.finish(); + } + + function go() { + document.querySelector('use').setAttributeNS('http://www.w3.org/1999/xlink', + 'href', location.href + '#a'); + } + + </script> +</head> +<body onload="go()";> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=993423">Mozilla Bug 993423</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +<svg> + <symbol id="a"> + <foreignObject> + <img src="about:logo" onload="var isInXBL = (function() { return this; })() != window; if (isInXBL) callback = window.wrappedJSObject.callback; callback(isInXBL);"> + </foreignObject> + </symbol> + <use /> +</svg> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_class_static_block_worker.html b/js/xpconnect/tests/mochitest/test_class_static_block_worker.html new file mode 100644 index 0000000000..e3ce063fe9 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_class_static_block_worker.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test class static fields</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + // Make sure static classes parse in regular context too: + class B { + static { this.x = 12; } + } + is(B.x, 12, "static block set class value"); + console.log("script"); + function go() { + SimpleTest.waitForExplicitFinish(); + + let worker = new Worker('class_static_worker.js'); + + console.log("message") + worker.onmessage = function(e) { + + is(e.data, 12, "correctly allocated class-static containing-class in worker"); + SimpleTest.finish(); + } + worker.postMessage("get"); + info("Messages posted"); + } + go(); + </script> + </head> + +</html>
\ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html b/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html new file mode 100644 index 0000000000..d7d364fdeb --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Cross-Compartment DOM WeakMaps</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<script type="application/javascript"> + +var my_map = new WeakMap(); + +function setup() { + var item = window.frames[0].document.querySelector("body"); + + my_map.set(item, "success_string"); +} + +function runTest() { + setup(); + SpecialPowers.forceGC(); + SpecialPowers.forceCC(); + SpecialPowers.forceGC(); + SpecialPowers.forceCC(); + var item = window.frames[0].document.querySelector("body"); + is(my_map.get(item), "success_string", "Preserve reflectors used cross-compartment as weak map keys."); +} + +</script> +<iframe src="file_crosscompartment_weakmap.html" onload="runTest()"></iframe> + + +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_enable_privilege.html b/js/xpconnect/tests/mochitest/test_enable_privilege.html new file mode 100644 index 0000000000..03043e9ce6 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_enable_privilege.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html lang="en" dir="ltr"> + <head> + <title>Test page for enablePrivilege</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script> + function init() { + var result = document.getElementById("result"); + try { + /* globals netscape */ + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + result.textContent = "FAIL"; + } catch (ex) { + result.textContent = "PASS"; + } + } + </script> + </head> + <body> + <p id="result"></p> + <script> + init(); + is(result.textContent, "PASS", "enablePrivilege should be unavaillable"); + </script> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_finalizationRegistry.html b/js/xpconnect/tests/mochitest/test_finalizationRegistry.html new file mode 100644 index 0000000000..9d9a798cdf --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_finalizationRegistry.html @@ -0,0 +1,168 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test FinalizationRegistry works in the browser</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + let registry1, holdings1; + let registry2, holdings2; + let registry3, holdings3; + let registry4, holdings4; + let registry5, holdings5; + let registry6, holdings6; + let registry7, holdings7; + let registry8, holdings8; + let registry9, holdings9; + + let object4 = {}; + + function go() { + SimpleTest.waitForExplicitFinish(); + + // Registry with no registered objects. + holdings1 = []; + registry1 = new FinalizationRegistry(v => { holdings1.push(v); }); + + // Registry with three registered objects. + holdings2 = []; + registry2 = new FinalizationRegistry(v => { holdings2.push(v); }); + registry2.register({}, 1); + registry2.register({}, 2); + registry2.register({}, 3); + + // Registry with registered object that is then unregistered. + holdings3 = []; + registry3 = new FinalizationRegistry(v => { holdings3.push(v); }); + let token3 = {} + registry3.register({}, 1, token3); + registry3.unregister(token3); + + // Registry with registered object that doesn't die. + holdings4 = []; + registry4 = new FinalizationRegistry(v => { holdings4.push(v); }); + registry4.register(object4, 1); + + // Registry observing cyclic JS data structure. + holdings5 = []; + registry5 = new FinalizationRegistry(v => { holdings5.push(v); }); + registry5.register(makeJSCycle(4), 5); + + // Registry observing DOM object without preserved wrappers. + holdings6 = []; + registry6 = new FinalizationRegistry(v => { holdings6.push(v); }); + registry6.register(document.createElement("div"), 6); + + // Registry observing DOM object with preserved wrappers. + holdings7 = []; + registry7 = new FinalizationRegistry(v => { holdings7.push(v); }); + let object = document.createElement("div"); + object.someProperty = true; + registry7.register(object, 7); + object = null; + + // Registry observing reachable DOM object without preserved wrappers. + holdings8 = []; + registry8 = new FinalizationRegistry(v => { holdings8.push(v); }); + document.body.appendChild(document.createElement("div")); + registry8.register(document.body.lastChild, 8); + + // Registry observing cyclic DOM/JS data structure. + holdings9 = []; + registry9 = new FinalizationRegistry(v => { holdings9.push(v); }); + registry9.register(makeDOMCycle(4), 9); + + // Need to run full GC/CC/GC cycle to collect cyclic garbage through DOM + // and JS heaps. + SpecialPowers.DOMWindowUtils.garbageCollect(); + SpecialPowers.DOMWindowUtils.cycleCollect(); + SpecialPowers.DOMWindowUtils.garbageCollect(); + + // Microtasks are run before cleanup callbacks. + Promise.resolve().then(() => { + is(holdings1.length, 0); + is(holdings2.length, 0); + is(holdings3.length, 0); + is(holdings4.length, 0); + is(holdings5.length, 0); + is(holdings6.length, 0); + is(holdings7.length, 0); + is(holdings8.length, 0); + is(holdings9.length, 0); + }); + + // setTimeout queues a task which will run after cleanup callbacks. + setTimeout(task2, 0); + } + + function task2() { + is(holdings1.length, 0); + + let result = holdings2.sort((a, b) => a - b); + is(result.length, 3); + is(result[0], 1); + is(result[1], 2); + is(result[2], 3); + + is(holdings3.length, 0); + is(holdings4.length, 0); + + is(holdings5.length, 1); + is(holdings5[0], 5); + + is(holdings6.length, 1); + is(holdings6[0], 6); + + is(holdings7.length, 1); + is(holdings7[0], 7); + + is(holdings8.length, 0); + + is(holdings9.length, 1); + is(holdings9[0], 9); + + document.body.removeChild(document.body.lastChild); + + SpecialPowers.DOMWindowUtils.garbageCollect(); + SpecialPowers.DOMWindowUtils.cycleCollect(); + SpecialPowers.DOMWindowUtils.garbageCollect(); + + setTimeout(task3, 0); + } + + function task3() { + is(holdings8.length, 1); + is(holdings8[0], 8); + + SimpleTest.finish(); + } + + function makeJSCycle(size) { + let first = {}; + let current = first; + for (let i = 0; i < size; i++) { + current.next = {}; + current = current.next; + } + current.next = first; + return first; + } + + function makeDOMCycle(size) { + let first = {}; + let current = first; + for (let i = 0; i < size; i++) { + if (i % 2 === 0) { + current.next = document.createElement("div"); + } else { + current.next = {}; + } + current = current.next; + } + current.next = first; + return first; + } + </script> + </head> + <body onload="go()"></body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_finalizationRegistryInWorker.html b/js/xpconnect/tests/mochitest/test_finalizationRegistryInWorker.html new file mode 100644 index 0000000000..8393781ce1 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_finalizationRegistryInWorker.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test FinalizationRegistry works in workers</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + function go() { + SimpleTest.waitForExplicitFinish(); + + let worker = new Worker('finalizationRegistry_worker.js'); + + worker.onevent = (event) => { + console.log(event.message); + throw event.error; + }; + + worker.onmessage = (event) => { + switch (event.data) { + case 'started': + worker.postMessage('checkResults'); + break; + + case 'passed': + ok(true, "Tests passed"); + SimpleTest.finish(); + break; + + default: + console.log(event.data); + break; + } + }; + + worker.postMessage('startTest'); + } + </script> + </head> + <body onload="go()"></body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_finalizationRegistry_cleanupSome.html b/js/xpconnect/tests/mochitest/test_finalizationRegistry_cleanupSome.html new file mode 100644 index 0000000000..d70cfa7172 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_finalizationRegistry_cleanupSome.html @@ -0,0 +1,13 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test FinalizationRegistry cleanupSome method is not exposed by default</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + let registry = new FinalizationRegistry(x => 1); + is(registry.cleanupSome, undefined, + "The cleanupSome method should not be exposed by default"); + </script> + </head> +</html> diff --git a/js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html b/js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html new file mode 100644 index 0000000000..8b6c71c9cf --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test FinalizationRegistry tracks its incumbent global</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + let resolvePromise, rejectPromise; + + async function runTest(global, callback) { + let fr = new global.FinalizationRegistry(callback); + fr.register({}, undefined); + + SpecialPowers.DOMWindowUtils.garbageCollect(); + + let promise = new Promise((resolve, reject) => { + resolvePromise = resolve; + rejectPromise = reject; + }); + + return promise; + } + + function receiveMessage(event) { + resolvePromise(event.source.sourceName); + } + + async function go() { + // This test uses FinalizationRegistry to trigger a callback and reports + // the incumbent global in the callback using postMessage. In all cases + // the author function that scheduled the callback is runTest(), so the + // incumbent global should be the main window. + + SimpleTest.waitForExplicitFinish(); + + window.sourceName = "main"; + window.addEventListener("message", receiveMessage, false); + + let other = window.frames[0]; + other.sourceName = "other"; + other.addEventListener("message", receiveMessage, false); + + is(await runTest(window, v => window.postMessage(v)), "main"); + is(await runTest(window, window.postMessage.bind(window)), "main"); + is(await runTest(other, v => other.postMessage(v)), "main"); + is(await runTest(other, other.postMessage.bind(other)), "main"); + is(await runTest(window, v => other.postMessage(v)), "main"); + is(await runTest(window, other.postMessage.bind(other)), "main"); + is(await runTest(other, v => window.postMessage(v)), "main"); + is(await runTest(other, window.postMessage.bind(window)), "main"); + + SimpleTest.finish(); + } + </script> + </head> + <body onload="go()"> + <div style="display: none"> + <!-- A subframe so we have another global to work with --> + <iframe></iframe> + </div> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_frameWrapping.html b/js/xpconnect/tests/mochitest/test_frameWrapping.html new file mode 100644 index 0000000000..4c8a6c428c --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_frameWrapping.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +No bug. +--> +<head> + <title>Test for Bug </title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** No bug for this test **/ + +function go() { + var win = frames[0]; + (function() { + var utils = SpecialPowers.getDOMWindowUtils(window); + is(utils.getClassName(win), "Proxy", "correctly wrap frame elements"); + })() + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +<iframe id="ifr" src="inner.html" onload="go()"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_getWebIDLCaller.html b/js/xpconnect/tests/mochitest/test_getWebIDLCaller.html new file mode 100644 index 0000000000..22a4ae1c3b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_getWebIDLCaller.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=968335 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 968335</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Cu.getCallerPrincipal (within JS-implemented WebIDL). **/ + + SimpleTest.waitForExplicitFinish(); + SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, go); + + + function go() { + var t = new TestInterfaceJS(); + is(t.getCallerPrincipal(), location.origin, + "Cu.getCallerPrincipal works right within JS-implemented WebIDL"); + + try { + SpecialPowers.Cu.getWebIDLCallerPrincipal(); + ok(false, "Should have thrown"); + } catch (e) { + ok(/NOT_AVAILABLE/.test(SpecialPowers.wrap(e)), + "API should throw when invoked outside of JS-implemented WebIDL"); + } + + SimpleTest.finish(); + } + + + + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=968335">Mozilla Bug 968335</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_getweakmapkeys.html b/js/xpconnect/tests/mochitest/test_getweakmapkeys.html new file mode 100644 index 0000000000..7942d9b945 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_getweakmapkeys.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=688277 +--> +<head> + <meta charset="utf-8"> + <title>Tests for nondeterministicGetWeakMapKeys</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + /** Test for Bug 688277 **/ + + /* Fail gracefully if junk is passed in. */ + is(SpecialPowers.nondeterministicGetWeakMapKeys(11), undefined, + "nondeterministicGetWeakMapKeys should return undefined for non-objects"); + is(SpecialPowers.nondeterministicGetWeakMapKeys({}), undefined, + "nondeterministicGetWeakMapKeys should return undefined for non-weakmap objects"); + is(SpecialPowers.nondeterministicGetWeakMapKeys(null), undefined, + "nondeterministicGetWeakMapKeys should return undefined for null"); + + /* return an empty array for an empty WeakMap */ + let mempty = new WeakMap(); + is(SpecialPowers.nondeterministicGetWeakMapKeys(mempty).length, 0, + "nondeterministicGetWeakMapKeys should return empty array for empty weakmap"); + + /* Test freeing/nonfreeing. */ + let m = new WeakMap(); + let liveKeys = new Array(); + + let add_elements = function () { + let k1 = {}; + m.set(k1, "live1"); + liveKeys.push(k1); + + let k2 = {}; + m.set(k2, "dead1"); + + let k = {}; + m.set(k, k); /* simple cycle */ + }; + + add_elements(); + + SpecialPowers.exactGC(function () { + let keys = SpecialPowers.nondeterministicGetWeakMapKeys(m); + is(liveKeys.length, 1, "Wrong number of live keys."); + is(keys.length, 1, "Should have one weak map key."); + is(m.get(keys[0]), "live1", "live1 should be live"); + SimpleTest.finish(); + }); + + SimpleTest.waitForExplicitFinish(); + </script> +</head> +<body> +<p id="display"></p> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_isRemoteProxy.html b/js/xpconnect/tests/mochitest/test_isRemoteProxy.html new file mode 100644 index 0000000000..9761fce05b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_isRemoteProxy.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>Tests for Cu.isRemoteProxy</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script> + +async function addFrame(url) { + let frame = document.createElement("iframe"); + frame.src = url; + document.body.appendChild(frame); + + await new Promise(resolve => { + frame.addEventListener("load", resolve, { once: true }); + }); + + return frame; +} + +add_task(async function() { + const { Cu } = SpecialPowers; + + let localFrame = await addFrame("file_empty.html"); + let remoteFrame = await addFrame( + SimpleTest.getTestFileURL("file_empty.html") + .replace("mochi.test:8888", "example.com")); + + ok(frames[0] === localFrame.contentWindow, "frames[0] is localFrame"); + ok(frames[1] === remoteFrame.contentWindow, "frames[1] is remoteFrame"); + + ok(!Cu.isRemoteProxy(window), "window is not a remote proxy"); + ok(!Cu.isRemoteProxy(location), "location is not a remote proxy"); + + ok(!Cu.isRemoteProxy(frames[0]), "frames[0] is not a remote proxy"); + ok( + !Cu.isRemoteProxy(frames[0].location), + "frames[0].location is not a remote proxy" + ); + + const { useRemoteSubframes } = SpecialPowers; + is(Cu.isRemoteProxy(frames[1]), useRemoteSubframes, + "frames[1] is a remote proxy if Fission is enabled"); + is(Cu.isRemoteProxy(frames[1].location), useRemoteSubframes, + "frames[1].location is a remote proxy if Fission is enabled"); +}); + +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_nukeContentWindow.html b/js/xpconnect/tests/mochitest/test_nukeContentWindow.html new file mode 100644 index 0000000000..0db8749b59 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_nukeContentWindow.html @@ -0,0 +1,75 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1322273 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1322273</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322273">Mozilla Bug 1322273</a> + +<iframe id="subframe"></iframe> + +<script type="application/javascript"> +"use strict"; + +function waitForWindowDestroyed(winID, callback) { + let observer = { + observe: function(subject, topic, data) { + let id = subject.QueryInterface(SpecialPowers.Ci.nsISupportsPRUint64).data; + if (id != winID) { + return; + } + SpecialPowers.removeObserver(observer, "outer-window-nuked"); + SpecialPowers.executeSoon(callback); + } + }; + SpecialPowers.addObserver(observer, "outer-window-nuked"); +} + +add_task(async function() { + let frame = $('subframe'); + frame.srcdoc = "foo"; + await new Promise(resolve => frame.addEventListener("load", resolve, {once: true})); + + let win = frame.contentWindow; + let winID = SpecialPowers.wrap(win).docShell.outerWindowID; + + win.eval("obj = {}"); + win.obj.foo = {bar: "baz"}; + + let obj = win.obj; + + let system = SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal() + let sandbox = SpecialPowers.Cu.Sandbox(system); + + sandbox.obj = obj; + + let isWrapperDead = SpecialPowers.Cu.evalInSandbox(`(${ + function isWrapperDead() { + return Cu.isDeadWrapper(obj); + } + })`, + sandbox); + + is(isWrapperDead(), false, "Sandbox wrapper for content window should not be dead"); + is(obj.foo.bar, "baz", "Content wrappers into and out of content window should be alive"); + + // Remove the frame, which should nuke the content window. + info("Remove the content frame"); + frame.remove(); + + // Give the nuke wrappers task a chance to run. + await new Promise(resolve => waitForWindowDestroyed(winID, resolve)); + + is(isWrapperDead(), true, "Sandbox wrapper for content window should be dead"); + is(obj.foo.bar, "baz", "Content wrappers into and out of content window should be alive"); +}); +</script> + +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_paris_weakmap_keys.html b/js/xpconnect/tests/mochitest/test_paris_weakmap_keys.html new file mode 100644 index 0000000000..1b786138d4 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_paris_weakmap_keys.html @@ -0,0 +1,94 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=777385 +--> +<head> + <meta charset="utf-8"> + <title>Tests for WebIDL objects as weak map keys</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 777385 **/ + + SimpleTest.waitForExplicitFinish(); + + // We wait to run this until the load event because it needs to access an element. + function go() { + + let live_map = new WeakMap; + + let get_div_style = function () { + return document.getElementById("mydivname").style; + } + + let make_live_map = function () { + let my_div_style = get_div_style(); + let div_fail = false; + try { + live_map.set(my_div_style, 12345); + } catch (e) { + div_fail = true; + } + ok(!div_fail, "Using elem.style as a weak map key should not produce an exception."); + + is(live_map.get(get_div_style()), 12345, "Live map should have live style with right value before GC."); + + } + + make_live_map(); + + let tf = new TestFunctions; + + let add_non_isupports2 = function () { + let testKey = tf.wrapperCachedNonISupportsObject; + + let testFail = false; + try { + live_map.set(testKey, 23456); + } catch (e) { + testFail = true; + } + + ok(!testFail, "Using a wrapper cached non-nsISupports class as a weak map key should not produce an exception."); + + is(live_map.get(testKey), 23456, "Live map should have wrapper cached non-nsISupports class right value before GC."); + } + + add_non_isupports2(); + + + /* Set up for running precise GC/CC then check the results. */ + + SpecialPowers.exactGC(function () { + SpecialPowers.forceCC(); + SpecialPowers.forceGC(); + SpecialPowers.forceGC(); + + is(SpecialPowers.nondeterministicGetWeakMapKeys(live_map).length, 2, + "Live WebIDL bindings keys should not be removed from a weak map."); + + is(live_map.get(get_div_style()), 12345, "Live weak map should have live style with right value after GC."); + is(live_map.get(tf.wrapperCachedNonISupportsObject), 23456, + "Live weak map should have live wrapper cached non-nsISupports class with right value after GC."); + + SimpleTest.finish(); + }); + + } + + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, + go); + }); + </script> +</head> +<div></div> +<div id="mydivname"></div> +<body> +<p id="display"></p> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_private_field_dom.html b/js/xpconnect/tests/mochitest/test_private_field_dom.html new file mode 100644 index 0000000000..4a50c7ca95 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_private_field_dom.html @@ -0,0 +1,221 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=???? +--> + +<head> + <meta charset="utf-8"> + <title>Test for Bug ????</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <iframe id="ifr"></iframe> +</head> + +<body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1094930">Mozilla Bug 1094930</a> + <p id="display"></p> + <div id="test_contents"> + <!-- Extracted from nsHTMLTagList.h --> + <applet></applet> + <area></area> + <audio></audio> + <base> + </base> + <bgsound></bgsound> + <blockquote></blockquote> + + <body></body> + <br></br> + <button></button> + <canvas></canvas> + <caption></caption> + <col> + </col> + <colgroup></colgroup> + <data></data> + <datalist></datalist> + <del></del> + <details></details> + <dialog></dialog> + <dir></dir> + <div></div> + <dl></dl> + <embed></embed> + <fieldset></fieldset> + <font></font> + <form></form> + <frame></frame> + <frameset></frameset> + <h1></h1> + <h2></h2> + <h3></h3> + <h4></h4> + <h5></h5> + <h6></h6> + + <head></head> + <hr> + </hr> + <html> + + </html> + <iframe></iframe> + <img></img> + <input></input> + <ins></ins> + <keygen></keygen> + <label></label> + <legend></legend> + <li></li> + <link> + </link> + <listing></listing> + <map></map> + <marquee></marquee> + <menu></menu> + <menuitem> + </menuitem> + <meta> + </meta> + <meter></meter> + <multicol></multicol> + <object></object> + <ol></ol> + <optgroup></optgroup> + <option></option> + <output></output> + <p></p> + <param> + </param> + <picture></picture> + <pre></pre> + <progress></progress> + <q></q> + <script></script> + <select></select> + <slot></slot> + <source> + </source> + <span></span> + <style></style> + <summary></summary> + <table></table> + <tbody></tbody> + <td></td> + <textarea></textarea> + <tfoot></tfoot> + <th></th> + <thead></thead> + <template></template> + <time></time> + <title></title> + <tr></tr> + <track> + </track> + <ul></ul> + <video></video> + <xmp></xmp> + </div> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + info("running") + + + // Because private fields may not be enabled, we construct A via the below eval of an IFFE, + // and return early if it syntax errors. + var A = undefined; + try { + A = eval(`(function(){ + class Base { + constructor(o) { + return o; + } + } + + class A extends Base { + #x = 1; + static g(o) { + return o.#x; + } + static s(o, v) { + o.#x = v; + } + } + + return A; + })();`); + } catch (e) { + is(e instanceof SyntaxError, true, "Threw Syntax Error, Private Fields Not Enabled"); + is(/private fields are not currently supported/.test(e.message), true, "correct message"); + } + + if (A instanceof Function) { + function assertThrewInstance(f, error) { + var threw = true; + try { + f(); + threw = false; + } catch (e) { + // info("Caught " + e.name); + is(e instanceof error, true, "Correct Error thrown"); + } + is(threw, true, "Error was thrown"); + } + + function testNode(node) { + info("Testing node " + node.nodeName); + + assertThrewInstance(() => A.g(node), TypeError); + assertThrewInstance(() => A.s(node, 'node'), TypeError); + // info("Stamping Node"); + new A(node); + // info("Asserting read"); + is(A.g(node), 1, "correct value read"); + // info("Setting"); + A.s(node, 'node'); + // info("Verifing setter set the value"); + is(A.g(node), 'node', "updated value read"); + // info("Verifying we cannot double-init"); + assertThrewInstance(() => new A(node), TypeError); + } + + function testNodeRecursive(node) { + testNode(node); + for (c of node.children) { + testNodeRecursive(c) + } + } + + const test_contents = document.getElementById('test_contents'); + testNodeRecursive(test_contents); + + info("Checking Window"); + // Window itself isn't allowed to host private fields, because it's + // a cross-origin object + assertThrewInstance(() => A.g(window), TypeError) + + info("Checking Window Prototype Chain") + // However, it's prototype chain can. + w = Object.getPrototypeOf(window); + while (w) { + testNode(w); + w = Object.getPrototypeOf(w); + } + + info("Test Document") + testNode(document); + + + info("Test CSSRuleList") + testNode(document.styleSheets[0].cssRules) + + info("Test DOMTokenList") + const div = document.createElement('div'); + testNode(div.classList); + } + SimpleTest.finish(); + </script> +</body> + +</html>
\ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/test_private_field_worker.html b/js/xpconnect/tests/mochitest/test_private_field_worker.html new file mode 100644 index 0000000000..68351000c5 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_private_field_worker.html @@ -0,0 +1,27 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test Private Fields</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + function go() { + SimpleTest.waitForExplicitFinish(); + + let worker = new Worker('private_field_worker.js'); + + var allocated = 0; + worker.onmessage = function(e) { + is(e.data, allocated, "correctly allocated private field-containing-class"); + SimpleTest.finish(); + } + + worker.postMessage("allocate"); allocated++; + worker.postMessage("count"); + info("Messages posted"); + } + go(); + </script> + </head> + +</html>
\ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/test_sameOriginPolicy.html b/js/xpconnect/tests/mochitest/test_sameOriginPolicy.html new file mode 100644 index 0000000000..2393e3c24f --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_sameOriginPolicy.html @@ -0,0 +1,109 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=801576 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 801576</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=801576">Mozilla Bug 801576</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for the same-origin policy. **/ +SimpleTest.waitForExplicitFinish(); + +function check(obj, prop, allowed, write) { + var accessed = false; + try { + if (write) { + try { + obj[prop] = 2; + accessed = true; + } catch (e) {} + Object.defineProperty(obj, 'prop', {getter: function() {}, setter: null}); + } + else + obj[prop]; + accessed = true; + } catch (e) {} + is(accessed, allowed, prop + " is correctly (in)accessible for " + (write ? 'write' : 'read')); +} + +var crossOriginReadableWindowProps = ['blur', 'close', 'closed', 'focus', + 'frames', 'location', 'length', + 'opener', 'parent', 'postMessage', + 'self', 'top', 'window', + /* indexed and named accessors */ + '0', 'subframe']; + +function isCrossOriginReadable(obj, prop) { + if (obj == "Window") + return crossOriginReadableWindowProps.includes(prop); + if (obj == "Location") + return prop == 'replace'; + return false; +} + +function isCrossOriginWritable(obj, prop) { + if (obj == "Window") + return prop == 'location'; + if (obj == "Location") + return prop == 'href'; +} + +// NB: we don't want to succeed with writes, so we only check them when it should be denied. +function testAll(sameOrigin) { + var win = document.getElementById('ifr').contentWindow; + + // Build a list of properties to check from the properties available on our + // window. + var props = []; + for (var prop in window) { props.push(prop); } + + // On android, this appears to be on the window but not on the iframe. It's + // not really relevant to this test, so just skip it. + if (props.includes('crypto')) + props.splice(props.indexOf('crypto'), 1); + + // Add the named grand-child, since that won't appear on our window. + props.push('subframe'); + + for (var prop of props) { + check(win, prop, sameOrigin || isCrossOriginReadable('Window', prop), /* write = */ false); + if (!sameOrigin && !isCrossOriginWritable('Window', prop)) + check(win, prop, false, /* write = */ true); + } + for (var prop in window.location) { + check(win.location, prop, sameOrigin || isCrossOriginReadable('Location', prop)); + if (!sameOrigin && !isCrossOriginWritable('Location', prop)) + check(win.location, prop, false, /* write = */ true); + } +} + +var loadCount = 0; +function go() { + ++loadCount; + if (loadCount == 1) { + testAll(true); + document.getElementById('ifr').contentWindow.location = 'http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html'; + } + else { + is(loadCount, 2); + testAll(false); + SimpleTest.finish(); + } +} + +</script> +</pre> +<iframe id="ifr" onload="go();" src="file_empty.html"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_sandbox_fetch.html b/js/xpconnect/tests/mochitest/test_sandbox_fetch.html new file mode 100644 index 0000000000..3b6cffed4e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_sandbox_fetch.html @@ -0,0 +1,54 @@ +<!doctype html> +<html> +<head> + <title>Fetch in JS Sandbox</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"></link> + <script src="test_fetch_basic.js"></script> +</head> +<body> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +function testHttpFetch(url) { + info('fetch: ' + url); + return fetch(new Request(url, { method: 'GET' })) + .then(response => { + is(response.status, 200, 'Response is 200'); + is(response.url, url, 'Response URL matches'); + }); +} + +function runSandboxTest(testFunc, argString) { + is(typeof testFunc, 'function'); + var resolvePromise; + var testPromise = new Promise(r => resolvePromise = r); + var finishFuncName = 'finish_' + testFunc.name; + SpecialPowers.Cu.exportFunction(_ => resolvePromise(), sb, + { defineAs: finishFuncName }); + SpecialPowers.Cu.evalInSandbox('(' + testFunc.toString() + ')' + + '(' + argString + ')' + + '.then(' + finishFuncName + ');', sb); + return testPromise; +} + +var origin = document.location.origin; +var properties = ['fetch', 'Blob', 'URL']; +var sb = new SpecialPowers.Cu.Sandbox(origin, + { wantGlobalProperties: properties }); + +sb.ok = SpecialPowers.Cu.exportFunction(ok, sb); +sb.is = SpecialPowers.Cu.exportFunction(is, sb); +sb.info = SpecialPowers.Cu.exportFunction(info, sb); + +Promise.resolve() + .then(_ => runSandboxTest(testHttpFetch, '"' + origin + window.location.pathname + '"')) + .then(_ => runSandboxTest(testAboutURL)) + .then(_ => runSandboxTest(testDataURL)) + .then(_ => runSandboxTest(testSameOriginBlobURL)) + .then(_ => SimpleTest.finish()); + +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_shadowRealm.html b/js/xpconnect/tests/mochitest/test_shadowRealm.html new file mode 100644 index 0000000000..311ce68107 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_shadowRealm.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for ShadowRealms</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <iframe id="ifr"></iframe> +</head> + +<body> + <p id="display"></p> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + info("running") + + let realm = new ShadowRealm(); + + let install = (fun, internal_name) => { + let installer = realm.evaluate(`var ${internal_name}; (x) => { ${internal_name} = x}`); + installer(fun); + } + + install(info, "log"); + install(is, "is"); + realm.evaluate(`is(true, true, 'inside realm')`); + + is(realm.evaluate("10"), 10, "ten is ten"); + + SimpleTest.finish(); + </script> +</body> + +</html> diff --git a/js/xpconnect/tests/mochitest/test_shadowRealm_worker.html b/js/xpconnect/tests/mochitest/test_shadowRealm_worker.html new file mode 100644 index 0000000000..d26e665f8f --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_shadowRealm_worker.html @@ -0,0 +1,63 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for ShadowRealms</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <iframe id="ifr"></iframe> +</head> + +<body> + <p id="display"></p> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + + var promise = (async ()=> { + var module = await import("./shadow_realm_module.js"); + is(module.x, 1, "import works outside worker"); + + var sr = new ShadowRealm(); + await sr.importValue("./shadow_realm_module.js", 'x').then((x) => is(x,1, "imported x and got 1")); + })(); + + promise.then(() => { + var worker = new Worker("shadow_realm_worker.js"); + + var expected = 0; + var recieved = 0; + + function test(str) { + worker.postMessage(str); + expected++; + } + + worker.onmessage = function(e) { + console.log("Received Message: "+e.data); + recieved++; + + if (e.data == "finish") { + is(expected, recieved, "Got the appropriate Number of messages"); + SimpleTest.finish(); + return; + } + + if (e.data.startsWith("PASS")) { + ok(true, e.data); + return; + } + + ok(false, e.data); + }; + + + test("evaluate"); + test("import"); + + + test("finish"); + }); + </script> +</body> + +</html> diff --git a/js/xpconnect/tests/mochitest/test_spectre_mitigations.html b/js/xpconnect/tests/mochitest/test_spectre_mitigations.html new file mode 100644 index 0000000000..3797b9af0e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_spectre_mitigations.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>Tests for Spectre mitigations</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script> +add_task(async function() { + const { Cu } = SpecialPowers; + const options = Cu.getJSTestingFunctions().getJitCompilerOptions(); + + const testMitigation = function(name) { + let val = options[name]; + ok(val === 0 || val === 1, "must be valid JitOption"); + is(Boolean(val), !SpecialPowers.useRemoteSubframes, "must be enabled if Fission is disabled"); + }; + + testMitigation("spectre.index-masking"); + testMitigation("spectre.object-mitigations"); + testMitigation("spectre.string-mitigations"); + testMitigation("spectre.value-masking"); + testMitigation("spectre.jit-to-cxx-calls"); +}); +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_weakRefs.html b/js/xpconnect/tests/mochitest/test_weakRefs.html new file mode 100644 index 0000000000..331bb9bb69 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_weakRefs.html @@ -0,0 +1,80 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test WeakRef works in the browser</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + let wr1, wr2, wr3, wr4; + + function go() { + SimpleTest.waitForExplicitFinish(); + + // 1. WeakRef with JS target. + wr1 = new WeakRef({}); + + // 2. WeakRef with DOM object target (without preserved wrapper). + wr2 = new WeakRef(document.createElement("div")); + + // 3. WeakRef with DOM object target (with preserved wrapper). + let object = document.createElement("div"); + object.someProperty = true; + wr3 = new WeakRef(object); + object = null + + // 4. WeakRef with reachable DOM object target without preserved wrapper. + document.body.appendChild(document.createElement("div")); + wr4 = new WeakRef(document.body.lastChild); + + // WeakRef should keep the target in the current task. + isnot(wr1.deref(), undefined, "deref() should return its target."); + isnot(wr2.deref(), undefined, "deref() should return its target."); + isnot(wr3.deref(), undefined, "deref() should return its target."); + isnot(wr4.deref(), undefined, "deref() should return its target."); + + // WeakRef should keep the target until the end of current task, which + // includes promise microtasks. + Promise.resolve().then(() => { + isnot(wr1.deref(), undefined, "deref() should return its target."); + isnot(wr2.deref(), undefined, "deref() should return its target."); + isnot(wr3.deref(), undefined, "deref() should return its target."); + isnot(wr4.deref(), undefined, "deref() should return its target."); + }); + + // setTimeout will call its callback in a new task. + setTimeout(task2, 0); + } + + function task2() { + // Trigger a full GC/CC/GC cycle to collect WeakRef targets. + SpecialPowers.DOMWindowUtils.garbageCollect(); + SpecialPowers.DOMWindowUtils.cycleCollect(); + SpecialPowers.DOMWindowUtils.garbageCollect(); + + is(wr1.deref(), undefined, "deref() should return undefined."); + is(wr2.deref(), undefined, "deref() should return undefined."); + is(wr3.deref(), undefined, "deref() should return undefined."); + isnot(wr4.deref(), undefined, "deref() should return its target."); + + // setTimeout will call its callback in a new task. + setTimeout(task3, 0); + } + + function task3() { + document.body.removeChild(document.body.lastChild); + + SpecialPowers.DOMWindowUtils.garbageCollect(); + SpecialPowers.DOMWindowUtils.cycleCollect(); + SpecialPowers.DOMWindowUtils.garbageCollect(); + + is(wr1.deref(), undefined, "deref() should return undefined."); + is(wr2.deref(), undefined, "deref() should return undefined."); + is(wr3.deref(), undefined, "deref() should return undefined."); + is(wr4.deref(), undefined, "deref() should return undefined."); + + SimpleTest.finish(); + } + </script> + </head> + <body onload="go()"></body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html b/js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html new file mode 100644 index 0000000000..c7af313d96 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test WeakRefs with DOM wrappers that get cycle collected</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + let weakrefs = []; + + function go() { + SimpleTest.waitForExplicitFinish(); + + // 1. nsISupports-derived object. + let doc = document.implementation.createHTMLDocument(); + weakrefs.push(new WeakRef(doc)); + + // 2. non-nsISupports-derived object. + let buffer = new AudioBuffer({length: 1, sampleRate: 8000}); + weakrefs.push(new WeakRef(buffer)); + + // 3. nsISupports non-wrapper-cached object. + let image = new ImageData(1, 1); + weakrefs.push(new WeakRef(image)); + + // 4. non-nsISupports non-wrapper-cached object. + let iterator = document.fonts.values(); + weakrefs.push(new WeakRef(iterator)); + + for (let wr of weakrefs) { + isnot(wr.deref(), undefined, "Check that live wrapper is returned"); + } + + // setTimeout will call its callback in a new task. + setTimeout(task2, 0); + } + + function task2() { + // Trigger a GC and CC to collect the DOM objects, but no GC to + // collect the wrappers. + SpecialPowers.DOMWindowUtils.garbageCollect(); + SpecialPowers.DOMWindowUtils.cycleCollect(); + + for (let wr of weakrefs) { + is(wr.deref(), undefined, "Check that stale wrapper is not exposed"); + } + + SimpleTest.finish(); + } + </script> + </head> + <body onload="go()"></body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_weakRefs_cross_compartment.html b/js/xpconnect/tests/mochitest/test_weakRefs_cross_compartment.html new file mode 100644 index 0000000000..87e509b535 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_weakRefs_cross_compartment.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test WeakRef works when target is in different compartment in the browser</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + function go() { + SimpleTest.waitForExplicitFinish(); + + let Cu = SpecialPowers.Cu; + let isSameCompartment = Cu.getJSTestingFunctions().isSameCompartment; + + // Open a new window, which will be from different compartment. + let win = window.open(); + is(isSameCompartment(win, window), false, + "Test for opeing a window from a different compartment."); + + let wr1, wr2, wr3; + { + let obj = {}; + + // WeakRef and target are both from different compartment. + wr1 = new win.WeakRef(new win.Object()); + + // WeakRef is same compartment, but target isn't. + wr2 = new WeakRef(new win.Object()); + + // WeakRef is in different compartment, but target is. + wr3 = new win.WeakRef(obj); + + obj = null; + } + + // WeakRef should keep the target in the current task. + isnot(wr1.deref(), undefined, "wr1.deref() should return its target."); + isnot(wr2.deref(), undefined, "wr2.deref() should return its target."); + isnot(wr3.deref(), undefined, "we3.deref() should return its target."); + + // Weakref should keep the target until the end of current Job, that + // includes microtask(Promise). + Promise.resolve().then(() => { + isnot(wr1.deref(), undefined, + "wr1.deref() should return its target in promise"); + isnot(wr2.deref(), undefined, + "wr2.deref() should return its target in promise"); + isnot(wr3.deref(), undefined, + "wr3.deref() should return its target in promise"); + }); + + // setTimeout will launch a new job and call ClearKeptObjects(). + setTimeout(() => { + // Call gc() forcibly to clear the target of wr. + SpecialPowers.DOMWindowUtils.garbageCollect(); + + is(wr1.deref(), undefined, "wr1.deref() should return undefined in the new job."); + is(wr2.deref(), undefined, "wr2.deref() should return undefined in the new job."); + is(wr3.deref(), undefined, "wr3.deref() should return undefined in the new job."); + + win.close(); + SimpleTest.finish(); + }, 0); + } + + </script> + </head> + <body onload="go()"></body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_weakmaps.html b/js/xpconnect/tests/mochitest/test_weakmaps.html new file mode 100644 index 0000000000..5e00106fed --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_weakmaps.html @@ -0,0 +1,264 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=668855 +--> +<head> + <meta charset="utf-8"> + <title>Test Cross-Compartment DOM WeakMaps</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="application/javascript"> + /** Test for Bug 668855 **/ + + SimpleTest.waitForExplicitFinish(); + +// We wait to run this until the load event because it needs to access an element. +function go() { + + /* Create a weak reference, with a single-element weak map. */ + let make_weak_ref = function (obj) { + let m = new WeakMap; + m.set(obj, {}); + return m; + }; + + /* Check to see if a weak reference is dead. */ + let weak_ref_dead = function (r) { + return SpecialPowers.nondeterministicGetWeakMapKeys(r).length == 0; + } + + /* Deterministically grab an arbitrary DOM element. */ + let get_live_dom = function () { + let elems = document.getElementsByTagName("a"); + return elems[0]; + }; + + + /* Test case from bug 653248, adapted into a standard test. + + This is a dead cycle involving a DOM edge, so the cycle collector can free it. Keys and + values reachable only from XPConnect must be marked gray for this to work, and the cycle collector + must know the proper structure of the heap. + + */ + let make_gray_loop = function () { + let map = new WeakMap; + let div = document.createElement("div"); + let key = {}; + let obj = {m:map, k:key}; + div.addEventListener("foo", function() { + // The code below doesn't matter (it won't run). Just pull a + // reference to obj. + obj.k = 1; + obj.m = "bar"; + }); + //div.entrain = {m:map, k:key}; This is not sufficient to cause a leak in Fx9 + map.set(key, div); + return make_weak_ref(map); + }; + + let weakref = make_gray_loop(); + + + /* Combinations of live and dead gray maps/keys. */ + let basic_weak_ref = null; + let basic_map_weak_ref = null; + let black_map = new WeakMap; + let black_key = {}; + + let basic_unit_tests = function () { + let live_dom = get_live_dom(); + let dead_dom = document.createElement("div"); + let live_map = new WeakMap; + let dead_map = new WeakMap; + let live_key = {}; + let dead_key = {}; + + // put the live/dead maps/keys into the appropriate DOM elements + live_dom.basic_unit_tests = {m:live_map, k:live_key}; + + let obj = {m:dead_map, k:dead_key}; + // dead_dom.hook = {m:dead_map, k:dead_key}; + dead_dom.addEventListener("foo", function() { + // The code below doesn't matter (it won't run). Just pull a + // reference to obj. + obj.m = 1; + obj.k = "2"; + }); + + // Create a dead value, and a weak ref to it. + // The loop keeps dead_dom alive unless the CC is smart enough to kill it. + let dead_val = {loop:dead_dom}; + basic_weak_ref = make_weak_ref(dead_val); + basic_map_weak_ref = make_weak_ref(dead_map); + + // set up the actual entries. most will die. + live_map.set(live_key, {my_key:'live_live'}); + live_map.set(dead_key, dead_val); + live_map.set(black_key, {my_key:'live_black'}); + + dead_map.set(live_key, dead_val); + dead_map.set(dead_key, dead_val); + dead_map.set(black_key, dead_val); + + black_map.set(live_key, {my_key:'black_live'}); + black_map.set(dead_key, dead_val); + black_map.set(black_key, {my_key:'black_black'}); + + }; + + basic_unit_tests(); + + + let check_basic_unit = function () { + let live_dom = get_live_dom(); + let live_map = live_dom.basic_unit_tests.m; + let live_key = live_dom.basic_unit_tests.k; + + // check the dead elements + ok(weak_ref_dead(basic_weak_ref), "Dead value was kept alive."); + ok(weak_ref_dead(basic_map_weak_ref), "Dead map was kept alive."); + + // check the live gray map + is(live_map.get(live_key).my_key, 'live_live', + "Live key should have the same value in live map."); + is(live_map.get(black_key).my_key, 'live_black', + "Black key should have the same value in live map."); + is(SpecialPowers.nondeterministicGetWeakMapKeys(live_map).length, 2, + "Live map should have two entries."); + + // check the live black map + is(black_map.get(live_key).my_key, 'black_live', + "Live key should have the same value in black map."); + is(black_map.get(black_key).my_key, 'black_black', + "Black key should have the same value in black map."); + is(SpecialPowers.nondeterministicGetWeakMapKeys(black_map).length, 2, + "Black map should have two entries."); + + }; + + + /* live gray chained weak map entries, involving the cycle collector. */ + let chainm = new WeakMap; + let num_chains = 5; + + let nested_cc_maps = function () { + let dom = get_live_dom(); + for(let i = 0; i < num_chains; i++) { + let k = {count:i}; + dom.key = k; + dom0 = document.createElement("div"); + chainm.set(k, {d:dom0}); + dom = document.createElement("div"); + dom0.appendChild(dom); + }; + }; + + let check_nested_cc_maps = function () { + let dom = get_live_dom(); + let all_ok = true; + for(let i = 0; i < num_chains; i++) { + let k = dom.key; + all_ok = all_ok && k.count == i; + dom = chainm.get(k).d.firstChild; + }; + ok(all_ok, "Count was invalid on a key in chained weak map entries."); + }; + + nested_cc_maps(); + + + /* black weak map, chained garbage cycle involving DOM */ + let garbage_map = new WeakMap; + + let chained_garbage_maps = function () { + let dom0 = document.createElement("div"); + let dom = dom0; + for(let i = 0; i < num_chains; i++) { + let k = {}; + dom.key = k; + let new_dom = document.createElement("div"); + garbage_map.set(k, {val_child:new_dom}); + dom = document.createElement("div"); + new_dom.appendChild(dom); + }; + // tie the knot + dom.appendChild(dom0); + }; + + chained_garbage_maps(); + + + /* black weak map, chained garbage cycle involving DOM, XPCWN keys */ + let wn_garbage_map = new WeakMap; + + let wn_chained_garbage_maps = function () { + let dom0 = document.createElement("div"); + let dom = dom0; + for(let i = 0; i < num_chains; i++) { + let new_dom = document.createElement("div"); + wn_garbage_map.set(dom, {wn_val_child:new_dom}); + dom = document.createElement("div"); + new_dom.appendChild(dom); + }; + // tie the knot + dom.appendChild(dom0); + }; + + wn_chained_garbage_maps(); + + + /* The cycle collector shouldn't remove a live wrapped native key. */ + + let wn_live_map = new WeakMap; + + let make_live_map = function () { + let live = get_live_dom(); + wn_live_map.set(live, {}); + ok(wn_live_map.has(get_live_dom()), "Live map should have live DOM node before GC."); + } + + make_live_map(); + + // We're out of ideas for unpreservable natives, now that just about + // everything is on webidl, so just don't test those. + + /* set up for running precise GC/CC then checking the results */ + + SpecialPowers.exactGC(function () { + SpecialPowers.forceCC(); + SpecialPowers.forceGC(); + SpecialPowers.forceGC(); + + ok(weak_ref_dead(weakref), "Garbage gray cycle should be collected."); + + check_nested_cc_maps(); + + is(SpecialPowers.nondeterministicGetWeakMapKeys(garbage_map).length, 0, "Chained garbage weak map entries should not leak."); + + check_basic_unit(); + + // fixed by Bug 680937 + is(SpecialPowers.nondeterministicGetWeakMapKeys(wn_garbage_map).length, 0, + "Chained garbage WN weak map entries should not leak."); + + // fixed by Bug 680937 + is(SpecialPowers.nondeterministicGetWeakMapKeys(wn_live_map).length, 1, + "Live weak map wrapped native key should not be removed."); + + ok(wn_live_map.has(get_live_dom()), "Live map should have live dom."); + + SimpleTest.finish(); + }); + +} + </script> +</head> +<div></div> +<div id="mydivname"></div> +<body onload="go()";> +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=668855" target="_blank">Mozilla Bug 668855</a> +<p id="display"></p> +</body> +</html> |