nodejs/deps/v8/test/mjsunit/harmony/shadowrealm-callsite-throw.js
Michaël Zasso f226350fcb deps: update V8 to 11.3.244.4
PR-URL: https://github.com/nodejs/node/pull/47251
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
2023-03-31 14:15:23 +00:00

115 lines
3.0 KiB
JavaScript

// Copyright 2022 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.
// Flags: --harmony-shadow-realm
// Test that CallSite#getFunction and CallSite#getThis throw inside ShadowRealms
// and cannot access objects from the outside, as otherwise we could violate the
// callable boundary invariant.
(function testInside() {
const shadowRealm = new ShadowRealm();
// The ShadowRealm won't have assertThrows, so use try-catch and accumulate a
// message string.
const wrapped = shadowRealm.evaluate(`
Error.prepareStackTrace = function(err, frames) {
let a = [];
for (let i = 0; i < frames.length; i++) {
try {
a.push(frames[i].getFunction());
} catch (e) {
a.push("getFunction threw");
}
try {
a.push(frames[i].getThis());
} catch (e) {
a.push("getThis threw");
}
}
return a.join(' ');
};
function inner() {
try {
throw new Error();
} catch (e) {
return e.stack;
}
}
inner;
`);
(function outer() {
// There are 4 frames, youngest to oldest:
//
// inner
// outer
// testInside
// top-level
//
// So getFunction/getThis should throw 4 times since the prepareStackTrace
// hook is executing inside the ShadowRealm.
assertEquals("getFunction threw getThis threw " +
"getFunction threw getThis threw " +
"getFunction threw getThis threw " +
"getFunction threw getThis threw", wrapped());
})();
})();
// Test that CallSite#getFunction and CallSite#getThis throw for ShadowRealm
// objects from the outside, as otherwise we can also violate the callable
// boundary.
(function testOutside() {
Error.prepareStackTrace = function(err, frames) {
let a = [];
for (let i = 0; i < frames.length; i++) {
try {
frames[i].getFunction();
a.push(`functionName: ${frames[i].getFunctionName()}`);
} catch (e) {
a.push(`${frames[i].getFunctionName()} threw`);
}
try {
frames[i].getThis();
a.push("t");
} catch (e) {
a.push("getThis threw");
}
}
return JSON.stringify(a);
};
const shadowRealm = new ShadowRealm();
const wrap = shadowRealm.evaluate(`
function trampolineMaker(callback) {
return function trampoline() { return callback(); };
}
trampolineMaker;
`);
const wrapped = wrap(function callback() {
try {
throw new Error();
} catch (e) {
return e.stack;
}
});
// There are 4 frames, youngest to oldest:
//
// callback (in outer realm)
// trampoline (in ShadowRealm)
// testOutside (in outer realm)
// top-level (in outer realm)
//
// The frame corresponding to trampoline should throw, since the outer realm
// should not get references to ShadowRealm objects.
assertEquals(JSON.stringify(
["functionName: callback", "t",
"trampoline threw", "getThis threw",
"functionName: testOutside", "t",
"functionName: null", "t"]), wrapped());
assertEquals
})();