Skip to content

Commit

Permalink
bthreads: throw DataCloneError on duplicate transfer objects. see nod…
Browse files Browse the repository at this point in the history
  • Loading branch information
chjj committed Jan 29, 2019
1 parent abff778 commit 7bf32b7
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
18 changes: 16 additions & 2 deletions lib/internal/clone.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@

'use strict';

const {cloneError} = require('./utils');
const utils = require('./utils');

const {
cloneError,
duplicateError,
hasDuplicates
} = utils;

/*
* Constants
Expand Down Expand Up @@ -126,6 +132,9 @@ class Cloner {
}

morph(value, transferList, opt) {
if (hasDuplicates(transferList))
throw duplicateError();

if (!this.hasPort(transferList, opt))
return [value, transferList, false];

Expand Down Expand Up @@ -436,7 +445,12 @@ class FullCloner extends Cloner {
if (!this.isTransferList(transferList))
throw new TypeError('Invalid transferList.');

return this._walk(value, new Set(transferList));
const list = new Set(transferList);

if (list.size !== transferList.length)
throw duplicateError();

return this._walk(value, list);
}
}

Expand Down
22 changes: 22 additions & 0 deletions lib/internal/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,26 @@ function cloneError(obj) {
return err;
}

function duplicateError() {
const err = new Error('Duplicate items present in transferList.');

err.name = 'DataCloneError';

if (Error.captureStackTrace)
Error.captureStackTrace(err, duplicateError);

return err;
}

function hasDuplicates(list) {
if (!Array.isArray(list))
return false;

const set = new Set(list);

return set.size !== list.length;
}

function toBuffer(value) {
if (value instanceof Uint8Array)
return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
Expand Down Expand Up @@ -71,6 +91,8 @@ function setupRefs(ref, ee, event) {

exports.objectString = objectString;
exports.cloneError = cloneError;
exports.duplicateError = duplicateError;
exports.hasDuplicates = hasDuplicates;
exports.toBuffer = toBuffer;
exports.once = once;
exports.setupRefs = setupRefs;
5 changes: 5 additions & 0 deletions lib/process/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@

const util = require('util');
const {EventEmitter} = require('events');
const utils = require('../internal/utils');
const clone = require('../internal/clone');
const Packet = require('./packet');
const {duplicateError, hasDuplicates} = utils;
const {types} = Packet;

/*
Expand Down Expand Up @@ -240,6 +242,9 @@ function activate(transferList, parent) {
if (!Array.isArray(transferList))
throw new TypeError('Invalid transferList.');

if (hasDuplicates(transferList))
throw duplicateError();

for (const item of transferList) {
if (item instanceof MessagePort) {
let channel = item._channel;
Expand Down

0 comments on commit 7bf32b7

Please sign in to comment.