Skip to content

Commit

Permalink
Ensure clone takes deep copy of options #4029
Browse files Browse the repository at this point in the history
  • Loading branch information
lovell committed Mar 17, 2024
1 parent c5f318e commit 7bc74fe
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
3 changes: 3 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Requires libvips v8.15.1
[#4028](https://github.com/lovell/sharp/pull/4028)
[@yolopunk](https://github.com/yolopunk)

* Ensure `clone` takes a deep copy of existing options.
[#4029](https://github.com/lovell/sharp/issues/4029)

### v0.33.2 - 12th January 2024

* Upgrade to libvips v8.15.1 for upstream bug fixes.
Expand Down
7 changes: 5 additions & 2 deletions lib/constructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,13 +425,16 @@ Object.setPrototypeOf(Sharp, stream.Duplex);
function clone () {
// Clone existing options
const clone = this.constructor.call();
clone.options = Object.assign({}, this.options);
const { debuglog, queueListener, ...options } = this.options;
clone.options = structuredClone(options);
clone.options.debuglog = debuglog;
clone.options.queueListener = queueListener;
// Pass 'finish' event to clone for Stream-based input
if (this._isStreamInput()) {
this.on('finish', () => {
// Clone inherits input data
this._flattenBufferIn();
clone.options.bufferIn = this.options.bufferIn;
clone.options.input.buffer = this.options.input.buffer;
clone.emit('finish');
});
}
Expand Down
22 changes: 22 additions & 0 deletions test/unit/clone.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,26 @@ describe('Clone', function () {
assert.strictEqual(0, original.listenerCount('finish'));
assert.strictEqual(0, clone.listenerCount('finish'));
});

it('Ensure deep clone of properties, including arrays', async () => {
const alpha = await sharp({
create: { width: 320, height: 240, channels: 3, background: 'red' }
}).toColourspace('b-w').png().toBuffer();

const original = sharp();
const joiner = original.clone().joinChannel(alpha);
const negater = original.clone().negate();

fs.createReadStream(fixtures.inputJpg320x240).pipe(original);
const joined = await joiner.png({ effort: 1 }).toBuffer();
const negated = await negater.png({ effort: 1 }).toBuffer();

const joinedMetadata = await sharp(joined).metadata();
assert.strictEqual(joinedMetadata.channels, 4);
assert.strictEqual(joinedMetadata.hasAlpha, true);

const negatedMetadata = await sharp(negated).metadata();
assert.strictEqual(negatedMetadata.channels, 3);
assert.strictEqual(negatedMetadata.hasAlpha, false);
});
});

0 comments on commit 7bc74fe

Please sign in to comment.