js/xpconnect/tests/chrome/test_cows.xul

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 https://bugzilla.mozilla.org/show_bug.cgi?id=500931
     7 -->
     8 <window title="Mozilla Bug 522764"
     9   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    10   <script type="application/javascript"
    11           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
    13   <!-- test results are displayed in the html:body -->
    14   <body xmlns="http://www.w3.org/1999/xhtml">
    15   <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=522764 "
    16      target="_blank">Mozilla Bug 522764 </a>
    17   </body>
    19   <!-- test code goes here -->
    20   <script type="application/javascript"><![CDATA[
    21 const Ci = Components.interfaces;
    22 const Cu = Components.utils;
    24 var sandbox = new Cu.Sandbox("about:blank");
    26 var test_utils = window.QueryInterface(Ci.nsIInterfaceRequestor).
    27                  getInterface(Ci.nsIDOMWindowUtils);
    29 function getCOW(x) {
    30   if (typeof x != 'object' && typeof x != 'function')
    31     return x;
    32   var rval = {};
    33   if (typeof x == "function")
    34     rval = eval(uneval(x));
    35   for (var i in x) {
    36     if (x.__lookupGetter__(i))
    37       rval.__defineGetter__(i, eval(uneval(x.__lookupGetter__(i))))
    38     else
    39       rval[i] = getCOW(x[i]);
    40   }
    41   return rval;
    42 }
    44 // Give the sandbox a way to create ChromeObjectWrapped objects.
    45 sandbox.getCOW = getCOW;
    47 // Define test API functions in the sandbox.
    48 const TEST_API = ['is', 'isnot', 'ok', 'todo_is', 'todo_isnot', 'todo'];
    49 TEST_API.forEach(function(name) { sandbox[name] = window[name]; });
    51 sandbox.alienObject = {
    52   __exposedProps__: {funProp: 'r'},
    53   funProp: function foo(x) {
    54     return x + 1;
    55   }
    56 };
    58 sandbox.chromeGet = function (obj, prop) { return obj[prop]; };
    60 function COWTests() {
    61     // This function is actually decompiled and run inside a
    62     // sandbox with content privileges.
    64     // TODO: This could use some refactoring; creating helper
    65     // functions like assertIsWritable(myObj, 'someproperty') might
    66     // be useful.
    68     function isProp(obj, propName, value, desc) {
    69       try {
    70           is(obj[propName], value, "getting " + propName + " on " + desc);
    71           ok(propName in obj,
    72              propName + " on " + desc + " should exist");
    73           ok(Object.hasOwnProperty.call(obj, propName),
    74              propName + " on " + desc + " should exist");
    75       } catch (e) {
    76           ok(false, "getting " + propName + " on " + desc + " threw " + e);
    77       }
    78     }
    79     function isPropHidden(obj, propName, desc) {
    80       try {
    81           is(obj[propName], undefined,
    82              "getting " + propName + " on " + desc + " should return undefined");
    83           ok(!(propName in obj),
    84              propName + " on " + desc + " should act as if it doesn't exist");
    85           ok(!Object.hasOwnProperty.call(obj, propName),
    86              propName + " on " + desc + " should act as if it doesn't exist");
    87       } catch (e) {
    88           ok(false, "getting " + propName + " on " + desc + " threw " + e);
    89       }
    90     }
    92     const PROPS_TO_TEST = ['foo', 'bar', 'prototype'];
    94     var empty = {};
    95     var nonempty = {foo: 42, bar: 33};
    96     is(getCOW(empty).foo, undefined,
    97        "shouldn't throw when accessing exposed properties that doesn't exist");
    99     PROPS_TO_TEST.forEach(function(name) {
   100         isPropHidden(getCOW(nonempty), name, "object without exposedProps");
   101     });
   103     // Test function objects without __exposedProps__
   104     var func = function(x) { return 42; };
   105     func.foo = "foo property";
   106     var funcCOW = getCOW(func);
   107     PROPS_TO_TEST.forEach(function(name) {
   108         isPropHidden(funcCOW, name, "function without exposedProps");
   109     });
   110     is([name for (name in funcCOW)].length, 0,
   111        "function without exposedProps shouldn't have any properties");
   112     is(funcCOW(), 42, "COW without exposedProps should still be callable");
   114     // Test function objects with __exposedProps__
   115     var func = function(x) { return 42; };
   116     func.foo = "foo property";
   117     func.__exposedProps__ = { foo: "r" };
   118     var funcCOWr = getCOW(func);
   119     PROPS_TO_TEST.forEach(function(name) {
   120         if (name == "foo") {
   121             isProp(funcCOWr, name, "foo property",
   122                    "function with exposedProps");
   123         }
   124         else {
   125             isPropHidden(funcCOWr, name, "function with exposedProps");
   126         }
   127     });
   128     is([name for (name in funcCOWr)].length, 1,
   129        "function with exposedProps should only enumerate exposed props");
   130     is([name for (name in funcCOWr)][0], "foo",
   131        "function with exposedProps should only enumerate exposed props");
   132     is(funcCOWr(), 42, "COW with exposedProps should be callable");
   134     // Test function objects with __exposedProps__
   135     var func = function(x) { return 42; };
   136     func.foo = "foo property";
   137     func.__exposedProps__ = { foo: "r", bar: "r" };
   138     var funcCOWr2 = getCOW(func);
   139     PROPS_TO_TEST.forEach(function(name) {
   140         if (name == "foo") {
   141             isProp(funcCOWr2, name, "foo property",
   142                    "function with more exposedProps");
   143         }
   144         else {
   145             isPropHidden(funcCOWr2, name, "function with more exposedProps");
   146         }
   147     });
   148     is([name for (name in funcCOWr2)].length, 1,
   149        "function with exposedProps should only enumerate exposed props");
   150     is([name for (name in funcCOWr2)][0], "foo",
   151        "function with exposedProps should only enumerate exposed props");
   153     // Test object with empty exposedProps
   154     var strict = { __exposedProps__: {}, foo: "foo property" };
   155     var strictCOW = getCOW(strict);
   156     PROPS_TO_TEST.forEach(function(name) {
   157         isPropHidden(strictCOW, name, "object with empty exposedProps");
   158     });
   159     is([name for (name in strictCOW)].length, 0,
   160        "object with empty exposedProps shouldn't have any properties");
   162     // Test object with one exposed property
   163     var strict = { __exposedProps__: { foo: "r" }, foo: "foo property" };
   164     var strictCOWr = getCOW(strict);
   165     PROPS_TO_TEST.forEach(function(name) {
   166         if (name == "foo") {
   167             isProp(strictCOWr, name, "foo property",
   168                    "object with exposed 'foo'");
   169         }
   170         else {
   171             isPropHidden(strictCOW, name, "object with exposed 'foo'");
   172         }
   173     });
   174     is([name for (name in strictCOWr)].length, 1,
   175        "object with exposedProps only enumerate exposed props");
   176     is([name for (name in strictCOWr)][0], "foo",
   177        "object with exposedProps only enumerate exposed props");
   179     // Test writable property
   180     var writable = getCOW({ __exposedProps__: {foo: 'w'}});
   181     try {
   182         ok(!("foo" in writable),
   183            "non-existing write-only property shouldn't exist");
   184         writable.foo = 5;
   185         is(chromeGet(writable, "foo"), 5, "writing to a write-only exposed prop works");
   186         todo("foo" in writable,
   187              "existing write-only property should exist");
   188     } catch (e) {
   189         ok(false, "writing to a write-only exposed prop shouldn't throw " + e);
   190     }
   191     try {
   192         writable.foo;
   193         todo(false, "reading from a write-only exposed prop should throw");
   194     } catch (e) {
   195         todo(/Permission denied/.test(e),
   196              "reading from a write-only exposed prop should throw");
   197     }
   198     try {
   199         delete writable.foo;
   200         is(chromeGet(writable, "foo"), undefined,
   201            "deleting a write-only exposed prop works");
   202     } catch (e) {
   203         ok(false, "deleting a write-only exposed prop shouldn't throw " + e);
   204     }
   206     // Test readable property
   207     var readable = { __exposedProps__: {foo: 'r'},
   208                      foo: 5,
   209                      bar: 6 };
   210     try {
   211         isProp(getCOW(readable), "foo", 5,
   212                "reading from a readable exposed prop works");
   213     } catch (e) {
   214         ok(false, "reading from a readable exposed prop shouldn't throw " + e);
   215     }
   216     try {
   217         getCOW(readable).foo = 1;
   218         ok(false, "writing to a read-only exposed prop should fail");
   219     } catch (e) {
   220         ok(/Permission denied/.test(e),
   221            "writing to a read-only exposed prop should fail");
   222     }
   223     try {
   224         delete getCOW(readable).foo;
   225         ok(false, "deleting a read-only exposed prop shouldn't work");
   226     } catch (e) {
   227         ok(/Permission denied/.test(e),
   228            "deleting a read-only exposed prop should throw error");
   229     }
   231     try {
   232         var props = [name for (name in getCOW(readable))];
   233         is(props.length, 1, "COW w/ one exposed prop should enumerate once");
   234         is(props[0], 'foo', "COW w/ one exposed prop should enumerate it");
   235     } catch (e) {
   236         ok(false, "COW w/ a readable prop should not raise exc " +
   237                   "on enumeration: " + e);
   238     }
   240     // Test read/write property
   241     var readwrite = getCOW({ __exposedProps__: {foo: 'rw'}});
   242     try {
   243         ok(!("foo" in readwrite),
   244            "non-existing readwrite property shouldn't exist");
   245         readwrite.foo = 5;
   246         is(readwrite.foo, 5, "writing to a readwrite exposed prop looks like it worked");
   247         is(chromeGet(readwrite, "foo"), 5, "writing to a readwrite exposed prop works");
   248         ok("foo" in readwrite,
   249            "existing readwrite property should exist");
   250     } catch (e) {
   251         ok(false, "writing to a readwrite exposed prop shouldn't throw " + e);
   252     }
   253     try {
   254         delete readwrite.foo;
   255         is(readwrite.foo, undefined, "deleting readwrite prop looks like it worked");
   256         ok(!("foo" in readwrite), "deleting readwrite prop looks like it really worked");
   257         is(chromeGet(readwrite, "foo"), undefined,
   258            "deleting a readwrite exposed prop works");
   259     } catch (e) {
   260         ok(false, "deleting a readwrite exposed prop shouldn't throw " + e);
   261     }
   263     // Readables and functions
   264     try {
   265         var COWFunc = getCOW((function() { return 5; }));
   266         is(COWFunc(), 5, "COWed functions should be callable");
   267     } catch (e) {
   268         todo(false, "COWed functions should not raise " + e);
   269     }
   270     try {
   271         var objWithFunc = {__exposedProps__: {foo: 'r'},
   272                            foo: function foo() { return 5; }};
   273         is(getCOW((objWithFunc)).foo(), 5,
   274            "Readable function exposed props should be callable");
   275     } catch (e) {
   276         ok(false, "Readable function exposed props should be callable" + e);
   277     }
   279     // Readables with getters
   280     var obj = {
   281         get prop() { return { __exposedProps__: {}, test: "FAIL" } },
   282         __exposedProps__: {prop: 'r'}
   283     };
   284     is(getCOW(obj).prop.test, undefined, "getting prop.test shouldn't return anything");
   285     ok(!("test" in getCOW(obj).prop), "getting prop.test shouldn't return anything");
   287     // Alien objects
   288     try {
   289         is(alienObject.funProp(1), 2,
   290            "COWs wrapping objects from different principals should work");
   291     } catch (e) {
   292         ok(false, "COWs wrapping objs from different principals " +
   293                   "shouldn't throw " + e);
   294     }
   296     try {
   297         is(alienObject.funProp(1), 2,
   298            "COWs wrapping objs from different principals should work twice");
   299     } catch (e) {
   300         ok(false, "COWs wrapping objs from different principals " +
   301                   "shouldn't throw on second access but not first: " + e);
   302     }
   303 }
   305 // Decompile the COW test suite, re-evaluate it in the sandbox and execute it.
   306 Cu.evalInSandbox('(' + uneval(COWTests) + ')()', sandbox);
   308 // Test that COWed objects passing from content to chrome get unwrapped.
   309 function returnCOW() {
   310     return getCOW({__exposedProps__: {},
   311                   bar: 6});
   312 }
   314 var unwrapped = Cu.evalInSandbox(
   315     '(' + uneval(returnCOW) + ')()',
   316     sandbox
   317 );
   319 try {
   320     is(unwrapped.bar, 6,
   321        "COWs should be unwrapped when entering chrome space");
   322 } catch (e) {
   323     todo(false, "COWs should be unwrapped when entering chrome space, " +
   324                 "not raise " + e);
   325 }
   326   ]]></script>
   327 </window>

mercurial