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

src: throw DOMException on cloning non-serializable objects #47839

Merged
merged 1 commit into from
Oct 8, 2023
Merged
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
59 changes: 36 additions & 23 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -2084,12 +2084,6 @@ urlSearchParams.has.call(buf, 'foo');
// Throws a TypeError with code 'ERR_INVALID_THIS'
```

<a id="ERR_INVALID_TRANSFER_OBJECT"></a>

### `ERR_INVALID_TRANSFER_OBJECT`

An invalid transfer object was passed to `postMessage()`.

<a id="ERR_INVALID_TUPLE"></a>

### `ERR_INVALID_TUPLE`
Expand Down Expand Up @@ -2287,23 +2281,6 @@ The V8 platform used by this instance of Node.js does not support creating
Workers. This is caused by lack of embedder support for Workers. In particular,
this error will not occur with standard builds of Node.js.

<a id="ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST"></a>

### `ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST`

<!-- YAML
added: v15.0.0
-->

An object that needs to be explicitly listed in the `transferList` argument
is in the object passed to a [`postMessage()`][] call, but is not provided
in the `transferList` for that call. Usually, this is a `MessagePort`.

In Node.js versions prior to v15.0.0, the error code being used here was
[`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`][]. However, the set of
transferable object types has been expanded to cover more types than
`MessagePort`.

<a id="ERR_MODULE_NOT_FOUND"></a>

### `ERR_MODULE_NOT_FOUND`
Expand Down Expand Up @@ -3300,6 +3277,20 @@ removed: v15.0.0

An invalid or unknown file encoding was passed.

<a id="ERR_INVALID_TRANSFER_OBJECT"></a>

### `ERR_INVALID_TRANSFER_OBJECT`

<!-- YAML
removed: REPLACEME
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/47839
description: A `DOMException` is thrown instead.
-->

An invalid transfer object was passed to `postMessage()`.

<a id="ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST"></a>

### `ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`
Expand All @@ -3312,6 +3303,28 @@ This error code was replaced by [`ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST`][]
in Node.js v15.0.0, because it is no longer accurate as other types of
transferable objects also exist now.

<a id="ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST"></a>

### `ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST`

<!-- YAML
added: v15.0.0
removed: REPLACEME
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/47839
description: A `DOMException` is thrown instead.
-->

An object that needs to be explicitly listed in the `transferList` argument
is in the object passed to a [`postMessage()`][] call, but is not provided
in the `transferList` for that call. Usually, this is a `MessagePort`.

In Node.js versions prior to v15.0.0, the error code being used here was
[`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`][]. However, the set of
transferable object types has been expanded to cover more types than
`MessagePort`.

<a id="ERR_NAPI_CONS_PROTOTYPE_OBJECT"></a>

### `ERR_NAPI_CONS_PROTOTYPE_OBJECT`
Expand Down
4 changes: 4 additions & 0 deletions src/env_properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@
V(channel_string, "channel") \
V(chunks_sent_since_last_write_string, "chunksSentSinceLastWrite") \
V(clone_unsupported_type_str, "Cannot clone object of unsupported type.") \
V(clone_transfer_needed_str, \
"Object that needs transfer was found in message but not listed in " \
"transferList") \
V(clone_untransferable_str, "Found invalid value in transferList.") \
V(code_string, "code") \
V(commonjs_string, "commonjs") \
V(config_string, "config") \
Expand Down
6 changes: 0 additions & 6 deletions src/node_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,11 @@ void AppendExceptionLine(Environment* env,
V(ERR_INVALID_MODULE, Error) \
V(ERR_INVALID_STATE, Error) \
V(ERR_INVALID_THIS, TypeError) \
V(ERR_INVALID_TRANSFER_OBJECT, TypeError) \
V(ERR_INVALID_URL, TypeError) \
V(ERR_INVALID_URL_SCHEME, TypeError) \
V(ERR_MEMORY_ALLOCATION_FAILED, Error) \
V(ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE, Error) \
V(ERR_MISSING_ARGS, TypeError) \
V(ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST, TypeError) \
V(ERR_MISSING_PASSPHRASE, TypeError) \
V(ERR_MISSING_PLATFORM_FOR_WORKER, Error) \
V(ERR_MODULE_NOT_FOUND, Error) \
Expand Down Expand Up @@ -168,16 +166,12 @@ ERRORS_WITH_CODE(V)
V(ERR_INVALID_MODULE, "No such module") \
V(ERR_INVALID_STATE, "Invalid state") \
V(ERR_INVALID_THIS, "Value of \"this\" is the wrong type") \
V(ERR_INVALID_TRANSFER_OBJECT, "Found invalid object in transferList") \
V(ERR_INVALID_URL_SCHEME, "The URL must be of scheme file:") \
V(ERR_MEMORY_ALLOCATION_FAILED, "Failed to allocate memory") \
V(ERR_OSSL_EVP_INVALID_DIGEST, "Invalid digest used") \
V(ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE, \
"A message object could not be deserialized successfully in the target " \
"vm.Context") \
V(ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST, \
"Object that needs transfer was found in message but not listed " \
"in transferList") \
V(ERR_MISSING_PLATFORM_FOR_WORKER, \
"The V8 platform used by this instance of Node does not support " \
"creating Workers") \
Expand Down
6 changes: 3 additions & 3 deletions src/node_messaging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ class SerializerDelegate : public ValueSerializer::Delegate {
return Just(true);
}
}
THROW_ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST(env_);
ThrowDataCloneError(env_->clone_transfer_needed_str());
return Nothing<bool>();
}

Expand Down Expand Up @@ -475,7 +475,7 @@ Maybe<bool> Message::Serialize(Environment* env,
Local<Value> entry_val = transfer_list_v[i];
if (!entry_val->IsObject()) {
// Only object can be transferred.
THROW_ERR_INVALID_TRANSFER_OBJECT(env);
ThrowDataCloneException(context, env->clone_untransferable_str());
return Nothing<bool>();
}
Local<Object> entry = entry_val.As<Object>();
Expand Down Expand Up @@ -533,7 +533,7 @@ Maybe<bool> Message::Serialize(Environment* env,
host_object = BaseObjectPtr<BaseObject>{Unwrap<BaseObject>(entry)};
} else {
if (!JSTransferable::IsJSTransferable(env, context, entry)) {
THROW_ERR_INVALID_TRANSFER_OBJECT(env);
ThrowDataCloneException(context, env->clone_untransferable_str());
return Nothing<bool>();
}
JSTransferable* js_transferable = JSTransferable::Wrap(env, entry);
Expand Down
16 changes: 12 additions & 4 deletions test/parallel/test-whatwg-webstreams-transfer.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ const theData = 'hello';
});

assert.throws(() => port2.postMessage(readable), {
code: 'ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST',
constructor: DOMException,
name: 'DataCloneError',
code: 25,
});

port2.postMessage(readable, [readable]);
Expand Down Expand Up @@ -155,7 +157,9 @@ const theData = 'hello';
});

assert.throws(() => port2.postMessage(readable), {
code: 'ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST',
constructor: DOMException,
name: 'DataCloneError',
code: 25,
});

port2.postMessage(readable, [readable]);
Expand Down Expand Up @@ -206,7 +210,9 @@ const theData = 'hello';
});

assert.throws(() => port2.postMessage(writable), {
code: 'ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST',
constructor: DOMException,
name: 'DataCloneError',
code: 25,
});

port2.postMessage(writable, [writable]);
Expand Down Expand Up @@ -292,7 +298,9 @@ const theData = 'hello';
});

assert.throws(() => port2.postMessage(transform), {
code: 'ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST',
constructor: DOMException,
name: 'DataCloneError',
code: 25,
});

port2.postMessage(transform, [transform]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ const { once } = require('events');
assert.throws(() => {
port1.postMessage(fh);
}, {
code: 'ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST'
constructor: DOMException,
name: 'DataCloneError',
code: 25,
});

// Check that transferring FileHandle instances works.
Expand Down
4 changes: 3 additions & 1 deletion test/parallel/test-worker-workerdata-messageport.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ const meowScript = () => 'meow';
workerData,
transferList: []
}), {
code: 'ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST',
constructor: DOMException,
name: 'DataCloneError',
code: 25,
message: 'Object that needs transfer was found in message but not ' +
'listed in transferList'
});
Expand Down