Skip to content

Commit b8bdaf8

Browse files
jasnelltargos
authored andcommitted
lib: disallow file-backed blob cloning
Disallow cloning of file-backed Blobs. If necessary, we can enable this later but for now we disable it. The reason is because the underlying FdEntry ends up bound to the Environment/Realm under which is was created and transfering across worker threads ends up failing. Fixes: #47334 PR-URL: #47574 Reviewed-By: Debadree Chatterjee <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent 0887fa0 commit b8bdaf8

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

lib/internal/blob.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ const {
5656
ERR_INVALID_ARG_TYPE,
5757
ERR_INVALID_ARG_VALUE,
5858
ERR_INVALID_THIS,
59+
ERR_INVALID_STATE,
5960
ERR_BUFFER_TOO_LARGE,
6061
},
6162
} = require('internal/errors');
@@ -74,6 +75,7 @@ const { queueMicrotask } = require('internal/process/task_queues');
7475
const kHandle = Symbol('kHandle');
7576
const kType = Symbol('kType');
7677
const kLength = Symbol('kLength');
78+
const kNotCloneable = Symbol('kNotCloneable');
7779

7880
const disallowedTypeCharacters = /[^\u{0020}-\u{007E}]/u;
7981

@@ -186,6 +188,11 @@ class Blob {
186188
}
187189

188190
[kClone]() {
191+
if (this[kNotCloneable]) {
192+
// We do not currently allow file-backed Blobs to be cloned or passed across
193+
// worker threads.
194+
throw new ERR_INVALID_STATE.TypeError('File-backed Blobs are not cloneable');
195+
}
189196
const handle = this[kHandle];
190197
const type = this[kType];
191198
const length = this[kLength];
@@ -438,7 +445,9 @@ function createBlobFromFilePath(path, options) {
438445
return lazyDOMException('The blob could not be read', 'NotReadableError');
439446
}
440447
const { 0: blob, 1: length } = maybeBlob;
441-
return createBlob(blob, length, options?.type);
448+
const res = createBlob(blob, length, options?.type);
449+
res[kNotCloneable] = true;
450+
return res;
442451
}
443452

444453
module.exports = {

test/parallel/test-blob-file-backed.js

+12
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const common = require('../common');
44
const {
55
strictEqual,
66
rejects,
7+
throws,
78
} = require('assert');
89
const { TextDecoder } = require('util');
910
const {
@@ -99,3 +100,14 @@ writeFileSync(testfile3, '');
99100
const reader = stream.getReader();
100101
await rejects(() => reader.read(), { name: 'NotReadableError' });
101102
})().then(common.mustCall());
103+
104+
(async () => {
105+
// We currently do not allow File-backed blobs to be cloned or transfered
106+
// across worker threads. This is largely because the underlying FdEntry
107+
// is bound to the Environment/Realm under which is was created.
108+
const blob = await openAsBlob(__filename);
109+
throws(() => structuredClone(blob), {
110+
code: 'ERR_INVALID_STATE',
111+
message: 'Invalid state: File-backed Blobs are not cloneable'
112+
});
113+
})().then(common.mustCall());

0 commit comments

Comments
 (0)