summaryrefslogtreecommitdiffstats
path: root/dom/bindings/test/test_bug1036214.html
blob: 8fbe373b65df842e644daa106c424e9c5e92331a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1036214
-->
<head>
  <meta charset="utf-8">
  <title>Test for Bug 1036214</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
  <script type="application/javascript">
  /* global TestInterfaceJS */

  /** Test for subsumes-checking |any| and |object| for js-implemented WebIDL. **/
  SimpleTest.waitForExplicitFinish();
  var xoObjects = [];
  function setup() {
    // window[0] is same-process and cross-origin, even with Fission enabled.
    xoObjects.push(window[0]);
    xoObjects.push(window[0].location);
    xoObjects.push(SpecialPowers.unwrap(SpecialPowers.wrap(window[0]).document));
    xoObjects.push(SpecialPowers.unwrap(SpecialPowers));
    xoObjects.push(SpecialPowers.unwrap(SpecialPowers.wrap));
    SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}, go);
  }

  function setup2() {
    if (SpecialPowers.useRemoteSubframes) {
      // window[1] is cross-origin and out of process, with Fission enabled.
      xoObjects.push(window[1]);
      xoObjects.push(window[1].location);
    }
  }

  function checkThrows(f, msg) {
    try {
      f();
      ok(false, "Should have thrown: " + msg);
    } catch (e) {
      ok(true, "Threw correctly: " + msg);
      ok(/denied|insecure/.test(e), "Threw security exception: " + e);
    }
  }

  function go() {
    //
    // Test the basics of the test interface.
    //

    var any = { a: 11 };
    var obj = { b: 22, c: "str" };
    var obj2 = { foo: "baz" };
    var myDict = { anyMember: 42, objectMember: { answer: 42 }, objectOrStringMember: { answer: "anobject" },
                   anySequenceMember: [{}, 1, "thirdinsequence"],
                   objectRecordMember: { key: { answer: "fortytwo" } },
                   innerDictionary: { innerObject: { answer: "rabbithole" } } };
    var t = new TestInterfaceJS(any, obj, myDict);
    is(Object.getPrototypeOf(t), TestInterfaceJS.prototype, "Prototype setup works correctly");
    is(t.anyArg, any, "anyArg is correct");
    is(t.objectArg, obj, "objectArg is correct");
    is(t.getDictionaryArg().anyMember, 42, "dictionaryArg looks correct");
    is(t.getDictionaryArg().objectMember.answer, 42, "dictionaryArg looks correct");
    is(t.getDictionaryArg().objectRecordMember.key.answer, "fortytwo", "dictionaryArg looks correct");
    is(t.getDictionaryArg().objectRecordMember.key.answer, "fortytwo", "dictionaryArg looks correct");
    t.anyAttr = 2;
    is(t.anyAttr, 2, "ping-pong any attribute works");
    t.objAttr = obj2;
    is(t.objAttr, obj2, "ping-pong object attribute works");
    t.setDictionaryAttr(myDict);
    is(t.getDictionaryAttr().anyMember, 42, "ping-pong dictionary works");
    is(t.getDictionaryAttr().objectMember.answer, 42, "ping-pong dictionary works");
    is(t.getDictionaryAttr().objectRecordMember.key.answer, "fortytwo", "ping-pong dictionary works");
    is(t.getDictionaryAttr().objectRecordMember.key.answer, "fortytwo", "ping-pong dictionary works");

    is(any, t.pingPongAny(any), "ping-pong works with any");
    is(obj, t.pingPongObject(obj), "ping-pong works with obj");
    is(obj, t.pingPongObjectOrString(obj), "ping-pong works with obj or string");
    is("foo", t.pingPongObjectOrString("foo"), "ping-pong works with obj or string");
    is(t.pingPongDictionary(myDict).anyMember, 42, "ping pong works with dict");
    is(t.pingPongDictionary(myDict).objectMember.answer, 42, "ping pong works with dict");
    is(t.pingPongDictionary(myDict).objectOrStringMember.answer, "anobject", "ping pong works with dict");
    is(t.pingPongDictionary(myDict).anySequenceMember[2], "thirdinsequence", "ping pong works with dict");
    is(t.pingPongDictionary(myDict).objectRecordMember.key.answer, "fortytwo", "ping pong works with dict");
    is(t.pingPongDictionary(myDict).objectRecordMember.key.answer, "fortytwo", "ping pong works with dict");
    is(t.pingPongDictionary(myDict).innerDictionary.innerObject.answer, "rabbithole", "ping pong works with layered dicts");
    is(t.pingPongDictionaryOrLong({anyMember: 42}), 42, "ping pong (dict or long) works with dict");
    is(t.pingPongDictionaryOrLong(42), 42, "ping pong (dict or long) works with long");
    ok(/canary/.test(t.pingPongRecord({ someVal: 42, someOtherVal: "canary" })), "ping pong works with record");
    is(t.objectSequenceLength([{}, {}, {}]), 3, "ping pong works with object sequence");
    is(t.anySequenceLength([42, "string", {}, undefined]), 4, "ping pong works with any sequence");

    //
    // Test that we throw in the cross-origin cases.
    //

    xoObjects.forEach(function(xoObj) {
      new TestInterfaceJS();
      checkThrows(() => new TestInterfaceJS(xoObj, undefined), "any param for constructor");
      checkThrows(() => new TestInterfaceJS(undefined, xoObj), "obj param for constructor");
      checkThrows(() => new TestInterfaceJS(undefined, undefined, { anyMember: xoObj }), "any dict param for constructor");
      checkThrows(() => new TestInterfaceJS(undefined, undefined, { objectMember: xoObj }), "object dict param for constructor");
      checkThrows(() => new TestInterfaceJS(undefined, undefined, { objectOrStringMember: xoObj }), "union dict param for constructor");
      checkThrows(() => new TestInterfaceJS(undefined, undefined, { anySequenceMember: [0, xoObj, "hi" ] }), "sequence dict param for constructor");
      checkThrows(() => new TestInterfaceJS(undefined, undefined, { innerDictionary: { innerObject: xoObj } }), "inner dict param for constructor");
      checkThrows(() => t.anyAttr = xoObj, "anyAttr");
      checkThrows(() => t.objectAttr = xoObj, "objAttr");
      checkThrows(() => t.setDictionaryAttr({ anyMember: xoObj }), "dictionaryAttr any");
      checkThrows(() => t.setDictionaryAttr({ objectMember: xoObj }), "dictionaryAttr object");
      checkThrows(() => t.pingPongAny(xoObj), "pingpong any");
      checkThrows(() => t.pingPongObject(xoObj), "pingpong obj");
      checkThrows(() => t.pingPongObjectOrString(xoObj), "pingpong union");
      checkThrows(() => t.pingPongDictionary({ anyMember: xoObj }), "dictionary pingpong any");
      checkThrows(() => t.pingPongDictionary({ objectMember: xoObj }), "dictionary pingpong object");
      checkThrows(() => t.pingPongDictionary({ anyMember: xoObj, objectMember: xoObj }), "dictionary pingpong both");
      checkThrows(() => t.pingPongDictionary({ objectOrStringMember: xoObj }), "dictionary pingpong objectorstring");
      checkThrows(() => t.pingPongDictionary({ objectRecordMember: { key: xoObj } }), "dictionary pingpong record of object");
      checkThrows(() => t.pingPongDictionaryOrLong({ objectMember: xoObj }), "unionable dictionary");
      checkThrows(() => t.pingPongDictionaryOrLong({ anyMember: xoObj }), "unionable dictionary");
      checkThrows(() => t.pingPongRecord({ someMember: 42, someOtherMember: {}, crossOriginMember: xoObj }), "record");
      checkThrows(() => t.objectSequenceLength([{}, {}, xoObj, {}]), "object sequence");
      checkThrows(() => t.anySequenceLength([42, "someString", xoObj, {}]), "any sequence");
    });


    SimpleTest.finish();
  }

  </script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1036214">Mozilla Bug 1036214</a>
<p id="display"></p>
<div id="content" style="display: none">

</div>
<pre id="test">
</pre>
<iframe id="ifr" onload="setup();" src="http://test1.mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
<iframe id="ifr2" onload="setup2();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
</body>
</html>