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.prototype.transferToImmutable #2400

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/ses/NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ User-visible changes in `ses`:

# v1.9.0 (2024-10-10)

- Adds `ArrayBuffer.p.immutable` and `ArrayBuffer.p.transferToImmutable` as a shim for a future proposal. It makes an ArrayBuffer-like object whose contents cannot be mutated. However, due to limitations of the shim
- Unlike `ArrayBuffer` and `SharedArrayBuffer` this shim's ArrayBuffer-like object cannot be transfered or cloned between JS threads.
- Unlike `ArrayBuffer` and `SharedArrayBuffer`, this shim's ArrayBuffer-like object cannot be used as the backing store of TypeArrays or DataViews.
- The shim depends on the platform providing either `structuredClone` or `Array.prototype.transfer`. Node <= 16 provides neither, causing the shim to fail to initialize, and therefore SES to fail to initialize on such platforms.
- Even after the upcoming `transferToImmutable` proposal is implemented by the platform, the current code will still replace it with the shim implementation, in accord with shim best practices. See https://github.com/endojs/endo/pull/2311#discussion_r1632607527 . It will require a later manual step to delete the shim, after manual analysis of the compat implications.

- On platforms without
[`Array.prototype.transfer`](https://github.com/tc39/proposal-resizablearraybuffer)
but with a global `structuredClone`, the ses-shim's `lockdown` will now
Expand Down
3 changes: 2 additions & 1 deletion packages/ses/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@
"postpack": "git clean -f '*.d.ts*' '*.tsbuildinfo'"
},
"dependencies": {
"@endo/env-options": "workspace:^"
"@endo/env-options": "workspace:^",
"@endo/immutable-arraybuffer": "workspace:^"
},
"devDependencies": {
"@endo/compartment-mapper": "workspace:^",
Expand Down
11 changes: 11 additions & 0 deletions packages/ses/src/get-anonymous-intrinsics.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
matchAllSymbol,
regexpPrototype,
globalThis,
ArrayBuffer,
} from './commons.js';
import { InertCompartment } from './compartment.js';

Expand Down Expand Up @@ -161,5 +162,15 @@ 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) {
// In a native implementation, these will be the same prototype
intrinsics['%ImmutableArrayBufferPrototype%'] = iabProto;
}

return intrinsics;
};
1 change: 1 addition & 0 deletions packages/ses/src/lockdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// @ts-check

import { getEnvironmentOption as getenv } from '@endo/env-options';
import '@endo/immutable-arraybuffer/shim.js';
import {
FERAL_FUNCTION,
FERAL_EVAL,
Expand Down
25 changes: 25 additions & 0 deletions packages/ses/src/permits.js
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,31 @@ export const permitted = {
// 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,
},

// 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
Expand Down
14 changes: 14 additions & 0 deletions packages/ses/test/immutable-array-buffer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import test from 'ava';
import '../index.js';

const { isFrozen, getPrototypeOf } = Object;

lockdown();

test('ses Immutable ArrayBuffer shim installed and hardened', t => {
const ab1 = new ArrayBuffer(0);
const iab = ab1.transferToImmutable();
const iabProto = getPrototypeOf(iab);
t.true(isFrozen(iabProto));
t.true(isFrozen(iabProto.slice));
});
3 changes: 2 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ __metadata:
languageName: unknown
linkType: soft

"@endo/immutable-arraybuffer@workspace:packages/immutable-arraybuffer":
"@endo/immutable-arraybuffer@workspace:^, @endo/immutable-arraybuffer@workspace:packages/immutable-arraybuffer":
version: 0.0.0-use.local
resolution: "@endo/immutable-arraybuffer@workspace:packages/immutable-arraybuffer"
dependencies:
Expand Down Expand Up @@ -8941,6 +8941,7 @@ __metadata:
dependencies:
"@endo/compartment-mapper": "workspace:^"
"@endo/env-options": "workspace:^"
"@endo/immutable-arraybuffer": "workspace:^"
"@endo/module-source": "workspace:^"
"@endo/test262-runner": "workspace:^"
ava: "npm:^6.1.3"
Expand Down
Loading