You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

@endo/immutable-arraybuffer

Package Overview
Dependencies
Maintainers
5
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@endo/immutable-arraybuffer - npm Package Compare versions

Comparing version

to
1.1.2

src/immutable-arraybuffer-pony.d.ts

4

index.d.ts

@@ -1,4 +0,2 @@

export function transferBufferToImmutable(buffer: ArrayBuffer, newLength?: number): ArrayBuffer;
export function isBufferImmutable(buffer: any): boolean;
export function sliceBufferToImmutable(buffer: ArrayBuffer, start?: number, end?: number): ArrayBuffer;
export * from "./src/immutable-arraybuffer-pony.js";
//# sourceMappingURL=index.d.ts.map

@@ -1,234 +0,1 @@

/* global globalThis */
const { setPrototypeOf, getOwnPropertyDescriptors, defineProperties } = Object;
const { apply } = Reflect;
const { prototype: arrayBufferPrototype } = ArrayBuffer;
// Capture structuredClone before it could be scuttled.
const { structuredClone: originalStructuredCloneMaybe } = globalThis;
const {
slice,
// TODO used to be a-ts-expect-error, but my local IDE's TS server
// seems to use a more recent definition of the `ArrayBuffer` type.
// @ts-ignore At the time of this writing, the `ArrayBuffer` type built
// into TypeScript does not know about the recent standard `transfer` method.
// Indeed, the `transfer` method is absent from Node <= 20.
transfer,
} = arrayBufferPrototype;
/**
* Enforces that `arrayBuffer` is a genuine `ArrayBuffer` exotic object.
*
* @param {ArrayBuffer} arrayBuffer
* @param {number} [start]
* @param {number} [end]
* @returns {ArrayBuffer}
*/
const arrayBufferSlice = (arrayBuffer, start = undefined, end = undefined) =>
apply(slice, arrayBuffer, [start, end]);
/**
* Enforces that `arrayBuffer` is a genuine `ArrayBuffer` exotic object.
* Return a new fresh `ArrayBuffer` exotic object, where the contents of the
* original `arrayBuffer` has been moved into the new one, and the original
* `arrayBuffer` has been detached.
*
* @param {ArrayBuffer} arrayBuffer
* @returns {ArrayBuffer}
*/
let arrayBufferTransfer;
if (transfer) {
arrayBufferTransfer = arrayBuffer => apply(transfer, arrayBuffer, []);
} else if (originalStructuredCloneMaybe) {
arrayBufferTransfer = arrayBuffer => {
// Hopefully, a zero-length slice is cheap, but still enforces that
// `arrayBuffer` is a genuine `ArrayBuffer` exotic object.
arrayBufferSlice(arrayBuffer, 0, 0);
return originalStructuredCloneMaybe(arrayBuffer, {
transfer: [arrayBuffer],
});
};
} else {
// Indeed, Node <= 16 has neither.
throw TypeError(
`Can only emulate immutable ArrayBuffer on a platform with either "structuredClone" or "ArrayBuffer.prototype.transfer"`,
);
}
/**
* This class only exists as an artifact of this ponyfill and shim,
* as a convenience for imperfectly emulating the
* *Immutable ArrayBuffer* proposal, which would not have this class.
* In the proposal,
* `transferToImmutable` makes a new `ArrayBuffer` that inherits directly from
* `ArrayBuffer.prototype` as you'd expect. In the ponyfill and shim,
* `transferToImmutable` makes a normal object that inherits directly from
* `immutableArrayBufferPrototype`, which has been surgically
* altered to inherit directly from `ArrayBuffer.prototype`. The constructor is
* captured for use internal to this module, and is made otherwise inaccessible.
* Therefore, `immutableArrayBufferPrototype` and all its methods
* and accessor functions effectively become hidden intrinsics.
* They are not encapsulated. Rather, they are trivially discoverable if you
* know how, but are not discoverable merely by enumerating naming paths.
*/
class ImmutableArrayBufferInternal {
/** @type {ArrayBuffer} */
#buffer;
constructor(buffer) {
// This constructor is deleted from the prototype below.
this.#buffer = arrayBufferTransfer(buffer);
}
get byteLength() {
return this.#buffer.byteLength;
}
get detached() {
this.#buffer; // shim brand check
return false;
}
get maxByteLength() {
// Not underlying maxByteLength, which is irrelevant
return this.#buffer.byteLength;
}
get resizable() {
this.#buffer; // shim brand check
return false;
}
get immutable() {
this.#buffer; // shim brand check
return true;
}
slice(start = undefined, end = undefined) {
return arrayBufferSlice(this.#buffer, start, end);
}
sliceToImmutable(start = undefined, end = undefined) {
// eslint-disable-next-line no-use-before-define
return sliceBufferToImmutable(this.#buffer, start, end);
}
resize(_newByteLength = undefined) {
this.#buffer; // shim brand check
throw TypeError('Cannot resize an immutable ArrayBuffer');
}
transfer(_newLength = undefined) {
this.#buffer; // shim brand check
throw TypeError('Cannot detach an immutable ArrayBuffer');
}
transferToFixedLength(_newLength = undefined) {
this.#buffer; // shim brand check
throw TypeError('Cannot detach an immutable ArrayBuffer');
}
transferToImmutable(_newLength = undefined) {
this.#buffer; // shim brand check
throw TypeError('Cannot detach an immutable ArrayBuffer');
}
}
const immutableArrayBufferPrototype = ImmutableArrayBufferInternal.prototype;
// @ts-expect-error can only delete optionals
delete immutableArrayBufferPrototype.constructor;
const {
slice: { value: sliceOfImmutable },
immutable: { get: isImmutableGetter },
} = getOwnPropertyDescriptors(immutableArrayBufferPrototype);
setPrototypeOf(immutableArrayBufferPrototype, arrayBufferPrototype);
// See https://github.com/endojs/endo/tree/master/packages/immutable-arraybuffer#purposeful-violation
defineProperties(immutableArrayBufferPrototype, {
[Symbol.toStringTag]: {
value: 'ImmutableArrayBuffer',
writable: false,
enumerable: false,
configurable: true,
},
});
/**
* Transfer the contents to a new Immutable ArrayBuffer
*
* @param {ArrayBuffer} buffer The original buffer.
* @param {number} [newLength] The start index.
* @returns {ArrayBuffer}
*/
export const transferBufferToImmutable = (buffer, newLength = undefined) => {
if (newLength !== undefined) {
if (transfer) {
buffer = apply(transfer, buffer, [newLength]);
} else {
buffer = arrayBufferTransfer(buffer);
const oldLength = buffer.byteLength;
// eslint-disable-next-line @endo/restrict-comparison-operands
if (newLength <= oldLength) {
buffer = arrayBufferSlice(buffer, 0, newLength);
} else {
const oldTA = new Uint8Array(buffer);
const newTA = new Uint8Array(newLength);
newTA.set(oldTA);
buffer = newTA.buffer;
}
}
}
const result = new ImmutableArrayBufferInternal(buffer);
return /** @type {ArrayBuffer} */ (/** @type {unknown} */ (result));
};
export const isBufferImmutable = buffer => {
try {
// @ts-expect-error Getter should be typed as this-sensitive
return apply(isImmutableGetter, buffer, []);
} catch (err) {
if (err instanceof TypeError) {
// Enforce that `buffer` is a genuine ArrayBuffer before returning.
arrayBufferSlice(buffer, 0, 0);
return false;
}
throw err;
}
};
/**
* Enforces that `arrayBuffer` is a genuine `ArrayBuffer` exotic object.
*
* @param {ArrayBuffer} buffer
* @param {number} [start]
* @param {number} [end]
* @returns {ArrayBuffer}
*/
const sliceBuffer = (buffer, start = undefined, end = undefined) => {
try {
// @ts-expect-error We know it is really there
return apply(sliceOfImmutable, buffer, [start, end]);
} catch (err) {
if (err instanceof TypeError) {
return arrayBufferSlice(buffer, start, end);
}
throw err;
}
};
/**
* Creates an immutable slice of the given buffer.
*
* @param {ArrayBuffer} buffer The original buffer.
* @param {number} [start] The start index.
* @param {number} [end] The end index.
* @returns {ArrayBuffer} The sliced immutable ArrayBuffer.
*/
export const sliceBufferToImmutable = (
buffer,
start = undefined,
end = undefined,
) => transferBufferToImmutable(sliceBuffer(buffer, start, end));
export * from './src/immutable-arraybuffer-pony.js';
{
"name": "@endo/immutable-arraybuffer",
"version": "1.1.1",
"version": "1.1.2",
"description": "Immutable ArrayBuffer (the shim!)",

@@ -28,3 +28,2 @@ "keywords": [

"./shim.js": "./shim.js",
"./shim-hermes.js": "./shim-hermes.js",
"./package.json": "./package.json"

@@ -46,3 +45,9 @@ },

"ava": "^6.1.3",
"babel-eslint": "^10.1.0",
"c8": "^7.14.0",
"eslint": "^8.57.1",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-import": "^2.31.0",
"tsd": "^0.31.2",

@@ -67,3 +72,3 @@ "typescript": "~5.8.3"

"extends": [
"plugin:@endo/internal"
"plugin:@endo/ses"
]

@@ -77,3 +82,3 @@ },

},
"gitHead": "03b92fc383da5d8bb4ea993b90149a0db5799d0b"
"gitHead": "9815aea9541f241389d2135c6097a7442bdffa17"
}

@@ -1,58 +0,1 @@

import {
transferBufferToImmutable,
isBufferImmutable,
sliceBufferToImmutable,
} from './index.js';
const { getOwnPropertyDescriptors, defineProperties } = Object;
const { prototype: arrayBufferPrototype } = ArrayBuffer;
const arrayBufferMethods = {
/**
* Transfer the contents to a new Immutable ArrayBuffer
*
* @this {ArrayBuffer} buffer The original buffer.
* @param {number} [newLength] The start index.
* @returns {ArrayBuffer} The sliced immutable ArrayBuffer.
*/
transferToImmutable(newLength = undefined) {
return transferBufferToImmutable(this, newLength);
},
/**
* Creates an immutable slice of the given buffer.
*
* @this {ArrayBuffer} buffer The original buffer.
* @param {number} [start] The start index.
* @param {number} [end] The end index.
* @returns {ArrayBuffer} The sliced immutable ArrayBuffer.
*/
sliceToImmutable(start = undefined, end = undefined) {
return sliceBufferToImmutable(this, start, end);
},
get immutable() {
return isBufferImmutable(this);
},
};
if ('sliceToImmutable' in arrayBufferPrototype) {
// Modern shim practice frowns on conditional installation, at least for
// proposals prior to stage 3. This is so changes to the proposal since
// an old shim was distributed don't need to worry about the proposal
// breaking old code depending on the old shim. Thus, if we detect that
// we're about to overwrite a prior installation, we simply issue this
// warning and continue.
//
// TODO, if the primordials are frozen after the prior implementation, such as
// by `lockdown`, then this precludes overwriting as expected. However, for
// this case, the following warning text will be confusing.
console.warn(
'About to overwrite a prior implementation of "sliceToImmutable"',
);
}
defineProperties(
arrayBufferPrototype,
getOwnPropertyDescriptors(arrayBufferMethods),
);
import './src/immutable-arraybuffer-shim.js';

Sorry, the diff of this file is not supported yet