Skip to content

Commit

Permalink
Don't invoke accessors or proxies via Reference functions
Browse files Browse the repository at this point in the history
  • Loading branch information
laverdet committed Mar 20, 2021
1 parent 3a2408a commit 2646e6c
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 121 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
## v4.0.0
- `Callback` class addeed.
- When possible, `reference.get()` will return a function proxy instead of a `Reference`.
- When possible, `reference.get()` will return a function delegate instead of a `Reference`.
- `reference.get()` will no longer return inherited properties by default.
- `result` property on `eval` and `evalClosure` has been removed. The result is now just the return
value.
- All `isolated-vm` class prototypes, and most instances are frozen.
- `isolate.cpuTime` and `isolate.wallTime` now return bigints.
- Proxies and accessors are no longer tolerated via `reference.get`, and related functions.
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ A instance of [`Reference`](#class-reference-transferable) is a pointer to a val
##### `new ivm.Reference(value, options)`
* `value` - The value to create a reference to.
* `options` *[object]*
* `inheritUnsafe` *[boolean]* - If enabled then the `get` family of functions will follow the
* `unsafeInherit` *[boolean]* - If enabled then the `get` family of functions will follow the
object's prototype chain. References created with this option should never be given to untrusted
code.

Expand Down Expand Up @@ -388,7 +388,6 @@ all attempts to access the reference will throw an error.
##### `reference.deleteIgnored(property)`
##### `reference.deleteSync(property)`
* `property` *[transferable]* - The property to access on this object.
* **return** `true` or `false`

Delete a property from this reference, as if using `delete reference[property]`

Expand All @@ -401,17 +400,15 @@ Delete a property from this reference, as if using `delete reference[property]`

Will access a reference as if using `reference[property]` and transfer the value out.

If the object is a proxy, or if the property is a getter, this method will throw.

##### `reference.set(property, value, options)` *[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)*
##### `reference.setIgnored(property, value, options)`
##### `reference.setSync(property, value, options)`
* `property` *[transferable]* - The property to set on this object.
* `value` *[transferable]* - The value to set on this object.
* `options` *[object]*
* [`{ ...TransferOptions }`](#transferoptions)
* **return** `true` or `false`

Returns a boolean indicating whether or not this operation succeeded. I'm actually not really sure
when `false` would be returned, I'm just giving you the result back straight from the v8 API.

##### `reference.apply(receiver, arguments, options)` *[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)*
##### `reference.applyIgnored(receiver, arguments, options)`
Expand Down
32 changes: 17 additions & 15 deletions isolated-vm.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ declare module "isolated-vm" {
| Context
| Script
| ExternalCopy<any>
| Callback<any>
| Copy<any>
| Reference<any>
| Dereference<any>
| Module
| ((...args: any[]) => any)
| typeof import("isolated-vm");

/**
Expand Down Expand Up @@ -284,7 +286,7 @@ declare module "isolated-vm" {
*/
export class Reference<T = any> {
private __ivm_reference: T;
constructor(value: T, options?: { inheritUnsafe?: boolean });
constructor(value: T, options?: { unsafeInherit?: boolean });

/**
* This is the typeof the referenced value, and is available at any time
Expand Down Expand Up @@ -331,31 +333,29 @@ declare module "isolated-vm" {
/**
* Delete a property from this reference, as if using `delete reference[property]`
*/
delete(property: keyof T): Promise<boolean>;
delete(property: keyof T): Promise<void>;
deleteIgnored(property: keyof T): void;
deleteSync(property: keyof T): boolean;
deleteSync(property: keyof T): void;

/**
* Will access a reference as if using reference[property] and return a reference to that value.
*
* If the object is a proxy, or if the property is a getter, this method will throw.
*/
get<Options extends TransferOptions, Key extends keyof T>(
property: Key, options?: Options): ResultTypeAsync<Options & AsReference, T[Key]>;
property: Key, options?: Options): ResultTypeAsync<Options & FallbackReference, T[Key]>;
getSync<Options extends TransferOptions, Key extends keyof T>(
property: Key, options?: Options): ResultTypeSync<Options & AsReference, T[Key]>;
property: Key, options?: Options): ResultTypeSync<Options & FallbackReference, T[Key]>;

/**
* Will access a reference as if using reference[property] and return a reference to that value.
*
* @return {boolean} Indicating whether or not this operation succeeded. I'm actually not really
* sure when false would be returned, I'm just giving you the result back straight from the v8
* API.
*/
set<Options extends TransferOptions, Key extends keyof T>(
property: Key, value: ArgumentType<Options, T[Key]>, options?: Options): Promise<boolean>;
property: Key, value: ArgumentType<Options, T[Key]>, options?: Options): Promise<void>;
setIgnored<Options extends TransferOptions, Key extends keyof T>(
property: Key, value: ArgumentType<Options, T[Key]>, options?: Options): void;
setSync<Options extends TransferOptions, Key extends keyof T>(
property: Key, value: ArgumentType<Options, T[Key]>, options?: Options): boolean;
property: Key, value: ArgumentType<Options, T[Key]>, options?: Options): void;

/**
* Will attempt to invoke an object as if it were a function. If the return
Expand All @@ -366,17 +366,17 @@ declare module "isolated-vm" {
receiver?: ArgumentType<Options['arguments'], ApplyArgumentThis<T>>,
arguments?: ArgumentsTypeBidirectional<Options, ApplyArguments<T>>,
options?: Options
): ResultTypeBidirectionalAsync<Options & ApplyAsReference, ApplyResult<T>>;
): ResultTypeBidirectionalAsync<Options & FallbackReference, ApplyResult<T>>;
applyIgnored<Options extends ReferenceApplyOptions>(
receiver?: ArgumentType<Options['arguments'], ApplyArgumentThis<T>>,
arguments?: ArgumentsTypeBidirectional<Options & ApplyAsReference, ApplyArguments<T>>,
arguments?: ArgumentsTypeBidirectional<Options & FallbackReference, ApplyArguments<T>>,
options?: Options
): void;
applySync<Options extends ReferenceApplyOptions>(
receiver?: ArgumentType<Options['arguments'], ApplyArgumentThis<T>>,
arguments?: ArgumentsTypeBidirectional<Options, ApplyArguments<T>>,
options?: Options
): ResultTypeBidirectionalSync<Options & ApplyAsReference, ApplyResult<T>>;
): ResultTypeBidirectionalSync<Options & FallbackReference, ApplyResult<T>>;

/**
* `applySyncPromise` is a special version of `applySync` which may only be invoked on functions
Expand All @@ -392,7 +392,7 @@ declare module "isolated-vm" {
receiver?: ArgumentType<Options['arguments'], ApplyArgumentThis<T>>,
arguments?: ArgumentsTypeBidirectional<Options, ApplyArguments<T>>,
options?: Options
): ResultTypeBidirectionalSync<Options & ApplyAsReference, ApplyResult<T>>;
): ResultTypeBidirectionalSync<Options & FallbackReference, ApplyResult<T>>;
}

/**
Expand Down Expand Up @@ -707,6 +707,7 @@ declare module "isolated-vm" {
type AsCopy = { copy: true };
type AsExternal = { externalCopy: true };
type AsReference = { reference: true };
type FallbackReference = { _reference: true };
type ApplyAsReference = { result: AsReference };
type WithTransfer = AsCopy | AsExternal | AsReference;

Expand All @@ -727,6 +728,7 @@ declare module "isolated-vm" {
Options extends AsReference ? Reference<Result> :
Result extends Transferable ? Result :
Result extends void ? void :
Options extends FallbackReference ? Reference<Result> :
Transferable;
type ResultTypeAsync<Options extends TransferOptions, Result = any> = Promise<ResultTypeBase<Options, Result>>;
type ResultTypeSync<Options extends TransferOptions, Result = any> = CheckPromise<Options, ResultTypeBase<Options, Result>>;
Expand Down
2 changes: 1 addition & 1 deletion src/isolate/strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ class StringTable {
String function{"function"};
String global{"global"};
String ignored{"ignored"};
String inheritUnsafe{"inheritUnsafe"};
String inspector{"inspector"};
String isolateIsDisposed{"Isolate is disposed"};
String isolatedVm{"isolated-vm"};
Expand All @@ -82,6 +81,7 @@ class StringTable {
String transferList{"transferList"};
String transferOut{"transferOut"};
String undefined{"undefined"};
String unsafeInherit{"unsafeInherit"};

String does_zap_garbage{"does_zap_garbage"};
String externally_allocated_size{"externally_allocated_size"};
Expand Down
Loading

0 comments on commit 2646e6c

Please sign in to comment.