diff --git a/packages/lockdown/post.js b/packages/lockdown/post.js index 5f06531e8a..e240b8c137 100644 --- a/packages/lockdown/post.js +++ b/packages/lockdown/post.js @@ -6,8 +6,8 @@ export default () => { // this assignment is not rejected, even if it does nothing. Error.stackTraceLimit = Infinity; - harden(TextEncoder); - harden(TextDecoder); + harden(globalThis.TextEncoder); // Absent in eshost + harden(globalThis.TextDecoder); // Absent in eshost harden(globalThis.URL); // Absent only on XSnap harden(globalThis.Base64); // Present only on XSnap }; diff --git a/packages/ses/src/error/console.js b/packages/ses/src/error/console.js index e11b697e96..0efd6fb15b 100644 --- a/packages/ses/src/error/console.js +++ b/packages/ses/src/error/console.js @@ -174,6 +174,10 @@ freeze(ErrorInfo); /** @type {MakeCausalConsole} */ const makeCausalConsole = (baseConsole, loggedErrorHandler) => { + if (!baseConsole) { + return undefined; + } + const { getStackString, tagError, takeMessageLogArgs, takeNoteLogArgsArray } = loggedErrorHandler; diff --git a/packages/ses/src/error/internal-types.js b/packages/ses/src/error/internal-types.js index a62dcc329d..caca8cfbfe 100644 --- a/packages/ses/src/error/internal-types.js +++ b/packages/ses/src/error/internal-types.js @@ -83,7 +83,7 @@ * calls methods of the `loggedErrorHandler` to customize how it handles logged * errors. * - * @param {VirtualConsole} baseConsole + * @param {VirtualConsole | undefined} baseConsole * @param {LoggedErrorHandler} loggedErrorHandler - * @returns {VirtualConsole} + * @returns {VirtualConsole | undefined} */ diff --git a/packages/ses/src/error/tame-console.js b/packages/ses/src/error/tame-console.js index 3f3fca1a4b..000f08207f 100644 --- a/packages/ses/src/error/tame-console.js +++ b/packages/ses/src/error/tame-console.js @@ -1,14 +1,47 @@ // @ts-check -import { TypeError, globalThis } from '../commons.js'; +import { + TypeError, + apply, + defineProperty, + freeze, + globalThis, +} from '../commons.js'; import { loggedErrorHandler as defaultHandler } from './assert.js'; import { makeCausalConsole } from './console.js'; import { makeRejectionHandlers } from './unhandled-rejection.js'; import './types.js'; import './internal-types.js'; +const wrapLogger = (logger, thisArg) => + freeze((...args) => apply(logger, thisArg, args)); + // eslint-disable-next-line no-restricted-globals -const originalConsole = console; +const originalConsole = /** @type {VirtualConsole} */ ( + // eslint-disable-next-line no-nested-ternary + typeof console !== 'undefined' + ? console + : typeof print === 'function' + ? // Make a good-enough console for eshost (including only functions that + // log at a specific level with no special argument interpretation). + // https://console.spec.whatwg.org/#logging + (p => freeze({ debug: p, log: p, info: p, warn: p, error: p }))( + // eslint-disable-next-line no-undef + wrapLogger(print), + ) + : undefined +); + +// Upgrade a log-only console (as in `eshost -h SpiderMonkey`). +if (originalConsole && originalConsole.log) { + for (const methodName of ['warn', 'error']) { + if (!originalConsole[methodName]) { + defineProperty(originalConsole, methodName, { + value: wrapLogger(originalConsole.log, originalConsole), + }); + } + } +} /** * Wrap console unless suppressed. @@ -40,10 +73,11 @@ export const tameConsole = ( getStackString: optGetStackString, }; } - const ourConsole = + const ourConsole = /** @type {VirtualConsole} */ ( consoleTaming === 'unsafe' ? originalConsole - : makeCausalConsole(originalConsole, loggedErrorHandler); + : makeCausalConsole(originalConsole, loggedErrorHandler) + ); // Attach platform-specific error traps such that any error that gets thrown // at top-of-turn (the bottom of stack) will get logged by our causal