fix: remove extra stackframe
MODIFY
packages/ses/src/commons.js
packages/ses/src/commons.js
@@ -31,7 +31,7 @@ export const defineProperty = (object, prop, descriptor) => {
return defineProperties(object, { [prop]: descriptor });
};
-export const { apply, get: reflectGet, set: reflectSet } = Reflect;
+export const { apply, construct, get: reflectGet, set: reflectSet } = Reflect;
export const { isArray, prototype: arrayPrototype } = Array;
export const { symbolUnscopables } = Symbol;

MODIFY
packages/ses/src/tame-error-constructor.js
packages/ses/src/tame-error-constructor.js
-import { defineProperties, setPrototypeOf } from './commons.js';
+import {
+ apply,
+ construct,
+ defineProperties,
+ setPrototypeOf,
+} from './commons.js';
import { tameV8ErrorConstructor } from './tame-v8-error-constructor.js';
// TODO where should this go?
@@ -25,12 +30,21 @@ export default function tameErrorConstructor(errorTaming = 'safe') {
const OriginalError = Error;
const ErrorPrototype = OriginalError.prototype;
+ const platform =
+ typeof OriginalError.captureStackTrace === 'function' ? 'v8' : 'unknown';
+
const makeErrorConstructor = (_ = {}) => {
const ResultError = function Error(...rest) {
+ let error;
if (new.target === undefined) {
- return OriginalError(...rest);
+ error = apply(OriginalError, this, rest);
+ } else {
+ error = construct(OriginalError, rest, new.target);
+ }
+ if (platform === 'v8') {
+ OriginalError.captureStackTrace(error, ResultError);
}
- return Reflect.construct(OriginalError, rest, new.target);
+ return error;
};
defineProperties(ResultError, {
length: { value: 1 },
@@ -64,8 +78,7 @@ export default function tameErrorConstructor(errorTaming = 'safe') {
}
let initialGetStackString = tamedMethods.getStackString;
- if (typeof OriginalError.captureStackTrace === 'function') {
- // Assume we're on v8
+ if (platform === 'v8') {
initialGetStackString = tameV8ErrorConstructor(
OriginalError,
InitialError,

RENAME
packages/ses/test/callsite-properties.test.js
packages/ses/test/v8-callsite-properties.test.js
@@ -5,6 +5,7 @@ import '../src/main.js';
lockdown({ errorTaming: 'unsafe' });
test('callSite properties', t => {
+ function topFrame() {
let sst;
const orig = Error.prepareStackTrace;
try {
@@ -18,7 +19,9 @@ test('callSite properties', t => {
// TODO: if we're not under v8, 'sst' will be undefined or an empty
// string, and we shouldn't look for these properties. This test checks
// what happens if we *are* under v8.
- const top = sst[0];
+ return sst[0];
+ }
+ const top = topFrame();
// We currently expect unsafe-tamed Error to allow prepareStackTrace to
// see the following properties, most of which violate confidentiality of
@@ -26,7 +29,7 @@ test('callSite properties', t => {
// them. But we hide the properties that would violate integrity, like
// `getThis` and `getFunction`.
t.equal(top.getTypeName(), null);
- t.equal(top.getFunctionName(), 'Error');
+ t.equal(top.getFunctionName(), 'topFrame');
t.equal(top.getMethodName(), null);
t.equal(typeof top.getFileName(), 'string');
t.equal(typeof top.getLineNumber(), 'number');

fix: remove extra stackframe (#391)