Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ses): ArrayBuffer.p.transferToImmutable #2311

Closed
wants to merge 12 commits into from
Prev Previous commit
Next Next commit
fixup! treat shim prototype as hidden intrinsic
  • Loading branch information
erights committed Jul 13, 2024
commit 7fcb8b19c3d451825e1c263668b70918378c7ec6
10 changes: 10 additions & 0 deletions packages/ses/src/get-anonymous-intrinsics.js
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ import {
matchAllSymbol,
regexpPrototype,
globalThis,
ArrayBuffer,
} from './commons.js';
import { InertCompartment } from './compartment.js';

@@ -157,5 +158,14 @@ export const getAnonymousIntrinsics = () => {
);
}

const ab = new ArrayBuffer(0);
// @ts-expect-error TODO How do I add transferToImmutable to ArrayBuffer type?
// eslint-disable-next-line @endo/no-polymorphic-call
const iab = ab.transferToImmutable();
const iabProto = getPrototypeOf(iab);
if (iabProto !== ArrayBuffer.prototype) {
intrinsics['%ImmutableArrayBufferPrototype%'] = iabProto;
}

return intrinsics;
};
3 changes: 2 additions & 1 deletion packages/ses/src/immutable-array-buffer-shim.js
Original file line number Diff line number Diff line change
@@ -27,7 +27,8 @@ class ImmutableArrayBufferInternal {
#buffer;

constructor(buffer) {
// This also enforces that `buffer` is a genuine `ArrayBuffer`
// This also enforces that `buffer` is a genuine `ArrayBuffer`.
// This constructor is deleted from the prototype below.
this.#buffer = arrayBufferSlice(buffer, 0);
}

21 changes: 21 additions & 0 deletions packages/ses/src/permits.js
Original file line number Diff line number Diff line change
@@ -1273,6 +1273,27 @@ export const permitted = {
immutable: getter,
},

// If this exists, it is purely an artifact of how we currently shim
// `transferToImmutable`. As natively implemented, there would be no
// such extra prototype.
'%ImmutableArrayBufferPrototype%': {
'[[Proto]]': '%ArrayBufferPrototype%',
byteLength: getter,
slice: fn,
// See https://github.com/tc39/proposal-resizablearraybuffer
transfer: fn,
resize: fn,
resizable: getter,
maxByteLength: getter,
// https://github.com/tc39/proposal-arraybuffer-transfer
transferToFixedLength: fn,
detached: getter,
// https://github.com/endojs/endo/pull/2309#issuecomment-2155513240
// to be proposed
transferToImmutable: fn,
immutable: getter,
},

// SharedArrayBuffer Objects
SharedArrayBuffer: false, // UNSAFE and purposely suppressed.
'%SharedArrayBufferPrototype%': false, // UNSAFE and purposely suppressed.
6 changes: 2 additions & 4 deletions packages/ses/test/immutable-array-buffer.test.js
Original file line number Diff line number Diff line change
@@ -5,10 +5,8 @@ const { isFrozen, getPrototypeOf } = Object;

lockdown();

// TODO Need to treat the hidden prototype as a hidden instrinsic so it
// gets hardened when the rest do.
test.failing('Immutable ArrayBuffer installed and hardened', t => {
const ab1 = new ArrayBuffer(2);
test('Immutable ArrayBuffer installed and hardened', t => {
const ab1 = new ArrayBuffer(0);
const iab = ab1.transferToImmutable();
const iabProto = getPrototypeOf(iab);
t.true(isFrozen(iabProto));