test_cloneInto.xul 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?xml version="1.0"?>
  2. <?xml-stylesheet type="text/css" href="chrome://global/skin"?>
  3. <?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
  4. <window title="Mozilla Bug 503926"
  5. xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  6. <script type="application/javascript"
  7. src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
  8. <!-- test results are displayed in the html:body -->
  9. <body xmlns="http://www.w3.org/1999/xhtml">
  10. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=964293"
  11. target="_blank">Cu.cloneInto()</a>
  12. </body>
  13. <!-- test code goes here -->
  14. <script type="application/javascript">
  15. <![CDATA[
  16. const Cu = Components.utils;
  17. const Ci = Components.interfaces;
  18. const TypedArrayThings = [
  19. 'Int8Array',
  20. 'Uint8Array',
  21. 'Uint8ClampedArray',
  22. 'Int16Array',
  23. 'Uint16Array',
  24. 'Int32Array',
  25. 'Uint32Array',
  26. 'Float32Array',
  27. 'Float64Array',
  28. ];
  29. function checkThrows(f, msg, rgxp) {
  30. try {
  31. f();
  32. ok(false, "Should have thrown: " + msg);
  33. } catch (e) {
  34. ok(true, "Threw correctly - " + msg + " - " + e);
  35. if (rgxp)
  36. ok(rgxp.test(e), "Should throw correct exception: " + e);
  37. }
  38. }
  39. function getType(a) {
  40. if (a === null || a === undefined)
  41. return 'null';
  42. if (Array.isArray(a))
  43. return 'array';
  44. if (a instanceof File)
  45. return 'file';
  46. if (a instanceof Ci.nsIDOMBlob)
  47. return 'blob';
  48. if (TypedArrayThings.indexOf(a.constructor.name) !== -1)
  49. return a.constructor.name;
  50. if (typeof a == 'object')
  51. return 'object';
  52. if (typeof a == 'function')
  53. return 'function';
  54. return 'primitive';
  55. }
  56. function compare(a, b) {
  57. is (getType(a), getType(b), 'Type matches');
  58. var type = getType(a);
  59. if (type == 'array') {
  60. is (a.length, b.length, 'Array.length matches');
  61. for (var i = 0; i < a.length; ++i) {
  62. compare(a[i], b[i]);
  63. }
  64. return;
  65. }
  66. if (type == 'file' || type == 'blob') {
  67. ok ( a === b, 'They should match');
  68. return;
  69. }
  70. if (type == 'object') {
  71. ok ( a !== b, 'They should not match');
  72. var aProps = [];
  73. for (var p in a) aProps.push(p);
  74. var bProps = [];
  75. for (var p in b) bProps.push(p);
  76. is (aProps.length, bProps.length, 'Props match');
  77. is (aProps.sort().toSource(), bProps.sort().toSource(), 'Props match - using toSource()');
  78. for (var p in a) {
  79. compare(a[p], b[p]);
  80. }
  81. return;
  82. }
  83. if (type == 'function') {
  84. ok ( a !== b, 'They should not match');
  85. return;
  86. }
  87. if (type != 'null') {
  88. is (a.toSource(), b.toSource(), 'Matching using toSource()');
  89. }
  90. }
  91. var sandboxOptions = {
  92. wantXrays: true,
  93. wantExportHelpers: true,
  94. };
  95. var sandbox = new Cu.Sandbox(window, sandboxOptions);
  96. // The second sandbox is for testing the exportHelper version of the cloneInto
  97. var sandbox2 = new Cu.Sandbox("http://example.com", sandboxOptions);
  98. sandbox.sandbox2 = sandbox2;
  99. sandbox2.sandbox = sandbox;
  100. function cloneAndTest(test) {
  101. var output = sandbox.test = Cu.cloneInto(test, sandbox);
  102. compare(test, output);
  103. output = Cu.evalInSandbox('cloneInto(test, sandbox2)', sandbox);
  104. compare(test, output);
  105. }
  106. function cloneAndTestWithFunctions(test) {
  107. var output = sandbox.test = Cu.cloneInto(test, sandbox, { cloneFunctions: true });
  108. compare(test, output);
  109. output = Cu.evalInSandbox('cloneInto(test, sandbox2, { cloneFunctions: true })', sandbox);
  110. // Note - We need to waive here, because functions are filtered out by object Xrays.
  111. compare(test, Cu.waiveXrays(output));
  112. }
  113. var tests = [
  114. 1,
  115. null,
  116. true,
  117. 'hello world',
  118. [1, 2, 3],
  119. { a: 1, b: 2 },
  120. new Date(),
  121. { a: 1, b: {}, c: [1, 2, 3, {} ], e: 'hello world' },
  122. ];
  123. for (var i = 0; i < tests.length; ++i) {
  124. cloneAndTest(tests[i]);
  125. }
  126. checkThrows(function() { Cu.cloneInto({ a: function() {} }, sandbox); },
  127. 'Function should not be cloned by default');
  128. checkThrows(function() { Cu.cloneInto({ a: document }, sandbox); },
  129. 'Reflectors should not be wrapped by default');
  130. var withReflectors = Cu.cloneInto({ doc: document, win: window }, sandbox,
  131. { wrapReflectors: true });
  132. is(Cu.unwaiveXrays(Cu.waiveXrays(withReflectors).doc), document, "Document passes");
  133. is(Cu.unwaiveXrays(Cu.waiveXrays(withReflectors).win), window, "Window passes");
  134. checkThrows(function() { Cu.evalInSandbox('cloneInto({}, sandbox)', sandbox2); },
  135. 'CloneInto should only work on less privileged target scopes.',
  136. /denied|insecure/);
  137. var cloneTarget = new Cu.Sandbox('http://example.com');
  138. var sameOriginSB = new Cu.Sandbox('http://example.com', { wantGlobalProperties: ['XMLHttpRequest'] });
  139. var crossOriginSB = new Cu.Sandbox('http://example.net', { wantGlobalProperties: ['XMLHttpRequest'] });
  140. sandbox2.cloneTarget = cloneTarget;
  141. sandbox2.soXHR = Cu.evalInSandbox('new XMLHttpRequest()', sameOriginSB);
  142. sandbox2.xoXHR = Cu.evalInSandbox('new XMLHttpRequest()', crossOriginSB);
  143. sandbox2.chromeDoc = document;
  144. Cu.evalInSandbox('function tryToClone(x) { return cloneInto({val: x}, cloneTarget, { wrapReflectors: true }).val; }', sandbox2);
  145. is(Cu.evalInSandbox('tryToClone(soXHR)', sandbox2), sandbox2.soXHR, 'Same-origin wrapReflectors works');
  146. checkThrows(function() { Cu.evalInSandbox('tryToClone(chromeDoc)', sandbox2); },
  147. 'wrapReflectors may not wrap cross-origin reflectors', /unsupported value type/);
  148. var test = { a: function() { return 42; } };
  149. cloneAndTestWithFunctions(test);
  150. // Check that inputs are properly passed through cloned functions:
  151. test = { a: function(obj) { return obj; } };
  152. var clonedTest = Cu.cloneInto(test, sandbox, {cloneFunctions: true});
  153. var testInput = {};
  154. is(clonedTest.a(testInput), testInput, "Objects should be identical");
  155. ]]>
  156. </script>
  157. </window>