diff --git a/packages/ERTP/src/displayInfo.js b/packages/ERTP/src/displayInfo.js index fe73c48de911..0857c00e2975 100644 --- a/packages/ERTP/src/displayInfo.js +++ b/packages/ERTP/src/displayInfo.js @@ -1,5 +1,10 @@ import { assert, details, q } from '@agoric/assert'; -import { pureCopy, passStyleOf, REMOTE_STYLE } from '@agoric/marshal'; +import { + pureCopy, + passStyleOf, + REMOTE_STYLE, + getInterfaceOf, +} from '@agoric/marshal'; // TODO: assertSubset and assertKeysAllowed are copied from Zoe. Move // this code to a location where it can be used by ERTP and Zoe @@ -44,6 +49,18 @@ export const assertDisplayInfo = allegedDisplayInfo => { export const coerceDisplayInfo = allegedDisplayInfo => { if (passStyleOf(allegedDisplayInfo) === REMOTE_STYLE) { + // These condition together try to ensure that `allegedDisplayInfo` + // is a plain empty object. It will accept all plain empty objects + // that it should. It will reject most things we want to reject including + // remotables that are explicitly declared `Remotable`. But a normal + // HandledPromise presence not explicitly declared `Remotable` will + // be mistaken for a plain empty object. Even in this case, the copy + // has a new identity, so the only danger is that we didn't reject + // with a diagnostic, potentially masking a programmer error. + assert(Object.isFrozen(allegedDisplayInfo)); + assert.equal(Reflect.ownKeys(allegedDisplayInfo).length, 0); + assert.equal(Object.getPrototypeOf(allegedDisplayInfo), Object.prototype); + assert.equal(getInterfaceOf(allegedDisplayInfo), undefined); return harden({}); } allegedDisplayInfo = pureCopy(allegedDisplayInfo);