test_private_field_cows.xhtml (5593B)
1 <?xml version="1.0"?> 2 <?xml-stylesheet href="chrome://global/skin" type="text/css"?> 3 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" 4 type="text/css"?> 5 6 <window title="Mozilla Bug ????" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 7 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 8 9 <!-- test results are displayed in the html:body --> 10 11 <body xmlns="http://www.w3.org/1999/xhtml"> 12 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=>?????" target="_blank">Mozilla Bug ???? </a> 13 </body> 14 15 <!-- test code goes here --> 16 <script type="application/javascript"><![CDATA[ 17 /* eslint-disable no-eval */ 18 19 add_task(async () => { 20 var sandbox = new Cu.Sandbox("about:blank"); 21 22 await SpecialPowers.pushPrefEnv({ 23 "set": [["security.allow_eval_with_system_principal", 24 true]] 25 }); 26 27 function getCOW(x) { 28 if (typeof x != 'object' && typeof x != 'function') 29 return x; 30 x = Cu.waiveXrays(x); 31 var rval = {}; 32 if (typeof x == "function") 33 rval = eval(`(${x.toString()})`); 34 for (var i in x) { 35 if (x.__lookupGetter__(i)) 36 rval.__defineGetter__(i, eval(`(${x.__lookupGetter__(i).toString()})`)) 37 else 38 rval[i] = getCOW(x[i]); 39 } 40 return rval; 41 } 42 43 // Give the sandbox a way to create ChromeObjectWrapped objects. 44 sandbox.getCOW = getCOW; 45 46 // Define test API functions in the sandbox. 47 const TEST_API = ['is', 'ok', 'info']; 48 TEST_API.forEach(function (name) { sandbox[name] = window[name]; }); 49 50 51 function COWTests() { 52 53 var empty = {}; 54 var cow = getCOW(empty); 55 56 // Because private fields may not be enabled, we construct A via the below eval of an IFFE, 57 // and return early if it syntax errors. 58 var A; 59 try { 60 A = eval(`(function(){ 61 class Base { 62 constructor(o) { 63 return o; 64 } 65 }; 66 67 class A extends Base { 68 #x = 12; 69 static gx(o) { 70 return o.#x; 71 } 72 73 static sx(o, v) { 74 o.#x = v; 75 } 76 }; 77 return A; 78 })();`); 79 } catch (e) { 80 is(e instanceof SyntaxError, true, "Syntax error: Private fields not enabled"); 81 is(/private fields are not currently supported/.test(e.message), true, "correct message"); 82 return; 83 } 84 85 new A(empty); 86 is(A.gx(empty), 12, "Correct value read"); 87 A.sx(empty, 'wrapped'); 88 89 function assertThrewInstance(f, error) { 90 var threw = true; 91 try { 92 f(); 93 threw = false; 94 } catch (e) { 95 is(e instanceof error, true, "Correct Error"); 96 } 97 is(threw, true, "Threw!"); 98 } 99 100 // Note: These throw warnings: 101 // 102 // WARNING: Silently denied access to property ##x: Access to privileged JS object not permitted (@chrome://mochitests/content/chrome/js/xpconnect/tests/chrome/test_private_field_cows.xhtml:108:27): file /js/xpconnect/wrappers/XrayWrapper.cpp, line 226 103 // 104 // It's not clear to me if we ougth to wire this up to -not-? I suspect this is a result of invoking 105 // the has 106 assertThrewInstance(() => A.gx(cow), TypeError); 107 assertThrewInstance(() => A.sx(cow, 'unwrapped'), TypeError); 108 assertThrewInstance(() => new A(cow), Error); 109 assertThrewInstance(() => A.gx(cow), TypeError); 110 } 111 112 // Stringify the COW test suite and directly evaluate it in the sandbox. 113 Cu.evalInSandbox('(' + COWTests.toString() + ')()', sandbox); 114 115 // Test that COWed objects passing from content to chrome get unwrapped. 116 function returnCOW() { 117 return getCOW({ 118 bar: 6 119 }); 120 } 121 122 // eslint-disable-next-line no-unused-vars 123 var unwrapped = Cu.evalInSandbox( 124 '(' + returnCOW.toString() + ')()', 125 sandbox 126 ); 127 128 ok(true, "passed"); 129 }); 130 ]]></script> 131 </window>