cross-realm-filtering.js 7.5 KB
Newer Older
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
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var realms = [Realm.current(), Realm.create()];

// Check stack trace filtering across security contexts.
var thrower_script =
    "(function () { Realm.eval(Realm.current(), 'throw Error()') })";
Realm.shared = {
  thrower_0: Realm.eval(realms[0], thrower_script),
  thrower_1: Realm.eval(realms[1], thrower_script),
};

var script = "                                                                 \
  Error.prepareStackTrace = function(a, b) { return b; };                      \
  try {                                                                        \
    Realm.shared.thrower_0();                                                  \
  } catch (e) {                                                                \
    Realm.shared.error_0 = e.stack;                                            \
  }                                                                            \
  try {                                                                        \
    Realm.shared.thrower_1();                                                  \
  } catch (e) {                                                                \
    Realm.shared.error_1 = e.stack;                                            \
  }                                                                            \
";

function assertNotIn(thrower, error) {
  for (var i = 0; i < error.length; i++) {
    assertFalse(false === error[i].getFunction());
  }
}

Realm.eval(realms[1], script);
jgruber's avatar
jgruber committed
36 37
assertSame(2, Realm.shared.error_0.length);
assertSame(3, Realm.shared.error_1.length);
38

jgruber's avatar
jgruber committed
39
assertTrue(Realm.shared.thrower_1 === Realm.shared.error_1[1].getFunction());
40 41 42 43
assertNotIn(Realm.shared.thrower_0, Realm.shared.error_0);
assertNotIn(Realm.shared.thrower_0, Realm.shared.error_1);

Realm.eval(realms[0], script);
jgruber's avatar
jgruber committed
44 45
assertSame(4, Realm.shared.error_0.length);
assertSame(3, Realm.shared.error_1.length);
46

jgruber's avatar
jgruber committed
47
assertTrue(Realm.shared.thrower_0 === Realm.shared.error_0[1].getFunction());
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
assertNotIn(Realm.shared.thrower_1, Realm.shared.error_0);
assertNotIn(Realm.shared.thrower_1, Realm.shared.error_1);


// Check .caller filtering across security contexts.
var caller_script = "(function (f) { f(); })";
Realm.shared = {
  caller_0 : Realm.eval(realms[0], caller_script),
  caller_1 : Realm.eval(realms[1], caller_script),
}

script = "                                                                     \
  function f_0() { Realm.shared.result_0 = arguments.callee.caller; };         \
  function f_1() { Realm.shared.result_1 = arguments.callee.caller; };         \
  Realm.shared.caller_0(f_0);                                                  \
  Realm.shared.caller_1(f_1);                                                  \
";

Realm.eval(realms[1], script);
assertSame(null, Realm.shared.result_0);
assertSame(Realm.shared.caller_1, Realm.shared.result_1);

Realm.eval(realms[0], script);
assertSame(Realm.shared.caller_0, Realm.shared.result_0);
assertSame(null, Realm.shared.result_1);
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90


// test that do not pollute / leak a function prototype v8/4217
var realmIndex = Realm.create();
var otherObject = Realm.eval(realmIndex, "Object");

var f = Realm.eval(realmIndex, "function f(){}; f");
f.prototype = null;

var o = new f();
var proto = Object.getPrototypeOf(o);
assertFalse(proto === Object.prototype);
assertTrue(proto === otherObject.prototype);

o = Realm.eval(realmIndex, "new f()");
proto = Object.getPrototypeOf(o);
assertFalse(proto === Object.prototype);
assertTrue(proto === otherObject.prototype);
91 92 93 94 95 96 97 98

// Check function constructor.
var ctor_script = "Function";
var ctor_a_script =
    "(function() { return Function.apply(this, ['return 1;']); })";
var ctor_b_script = "Function.bind(this, 'return 1;')";
var ctor_c_script =
    "(function() { return Function.call(this, 'return 1;'); })";
99 100
// Also check Promise constructor.
var promise_ctor_script = "Promise";
101 102 103 104 105 106 107 108 109
Realm.shared = {
  ctor_0 : Realm.eval(realms[0], ctor_script),
  ctor_1 : Realm.eval(realms[1], ctor_script),
  ctor_a_0 : Realm.eval(realms[0], ctor_a_script),
  ctor_a_1 : Realm.eval(realms[1], ctor_a_script),
  ctor_b_0 : Realm.eval(realms[0], ctor_b_script),
  ctor_b_1 : Realm.eval(realms[1], ctor_b_script),
  ctor_c_0 : Realm.eval(realms[0], ctor_c_script),
  ctor_c_1 : Realm.eval(realms[1], ctor_c_script),
110 111
  promise_ctor_0 : Realm.eval(realms[0], promise_ctor_script),
  promise_ctor_1 : Realm.eval(realms[1], promise_ctor_script),
112 113 114
}
var script_0 = "                                                               \
  var ctor_0 = Realm.shared.ctor_0;                                            \
115
  var promise_ctor_0 = Realm.shared.promise_ctor_0;                            \
116 117 118 119 120 121 122 123 124 125
  Realm.shared.direct_0 = ctor_0('return 1');                                  \
  Realm.shared.indirect_0 = (function() { return ctor_0('return 1;'); })();    \
  Realm.shared.apply_0 = ctor_0.apply(this, ['return 1']);                     \
  Realm.shared.bind_0 = ctor_0.bind(this, 'return 1')();                       \
  Realm.shared.call_0 = ctor_0.call(this, 'return 1');                         \
  Realm.shared.proxy_0 = new Proxy(ctor_0, {})('return 1');                    \
  Realm.shared.reflect_0 = Reflect.apply(ctor_0, this, ['return 1']);          \
  Realm.shared.a_0 = Realm.shared.ctor_a_0();                                  \
  Realm.shared.b_0 = Realm.shared.ctor_b_0();                                  \
  Realm.shared.c_0 = Realm.shared.ctor_c_0();                                  \
126
  Realm.shared.p_0 = new promise_ctor_0((res,rej) => res(1));                  \
127 128 129 130 131 132 133 134 135 136 137 138 139
";
script = script_0 + script_0.replace(/_0/g, "_1");
Realm.eval(realms[0], script);
assertSame(1, Realm.shared.direct_0());
assertSame(1, Realm.shared.indirect_0());
assertSame(1, Realm.shared.apply_0());
assertSame(1, Realm.shared.bind_0());
assertSame(1, Realm.shared.call_0());
assertSame(1, Realm.shared.proxy_0());
assertSame(1, Realm.shared.reflect_0());
assertSame(1, Realm.shared.a_0());
assertSame(1, Realm.shared.b_0());
assertSame(1, Realm.shared.c_0());
140
assertInstanceof(Realm.shared.p_0, Realm.shared.promise_ctor_0);
141 142 143 144 145 146 147 148 149 150
assertSame(undefined, Realm.shared.direct_1);
assertSame(undefined, Realm.shared.indirect_1);
assertSame(undefined, Realm.shared.apply_1);
assertSame(undefined, Realm.shared.bind_1);
assertSame(undefined, Realm.shared.call_1);
assertSame(undefined, Realm.shared.proxy_1);
assertSame(undefined, Realm.shared.reflect_1);
assertSame(undefined, Realm.shared.a_1);
assertSame(undefined, Realm.shared.b_1);
assertSame(undefined, Realm.shared.c_1);
151
assertSame(undefined, Realm.shared.p_1);
152 153 154 155 156 157 158 159 160 161 162
Realm.eval(realms[1], script);
assertSame(undefined, Realm.shared.direct_0);
assertSame(undefined, Realm.shared.indirect_0);
assertSame(undefined, Realm.shared.apply_0);
assertSame(undefined, Realm.shared.bind_0);
assertSame(undefined, Realm.shared.call_0);
assertSame(undefined, Realm.shared.proxy_0);
assertSame(undefined, Realm.shared.reflect_0);
assertSame(undefined, Realm.shared.a_0);
assertSame(undefined, Realm.shared.b_0);
assertSame(undefined, Realm.shared.c_0);
163
assertSame(undefined, Realm.shared.p_0);
164 165 166 167 168 169 170 171 172 173
assertSame(1, Realm.shared.direct_1());
assertSame(1, Realm.shared.indirect_1());
assertSame(1, Realm.shared.apply_1());
assertSame(1, Realm.shared.bind_1());
assertSame(1, Realm.shared.call_1());
assertSame(1, Realm.shared.proxy_1());
assertSame(1, Realm.shared.reflect_1());
assertSame(1, Realm.shared.a_1());
assertSame(1, Realm.shared.b_1());
assertSame(1, Realm.shared.c_1());
174
assertInstanceof(Realm.shared.p_1, Realm.shared.promise_ctor_1);