From 464fb1726d7a87f3e306c9aec1aa55f8e14b44e4 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 6 Dec 2014 22:33:47 +0000 Subject: [PATCH] Keep output dimensions within WebP 14-bit range --- README.md | 6 +++--- index.js | 4 ++-- test/unit/metadata.js | 2 +- test/unit/resize.js | 48 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ee0c6737..ad6cfe7c 100755 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ readableStream.pipe(transformer).pipe(writableStream); ```javascript var image = sharp(inputJpg); image.metadata(function(err, metadata) { - image.resize(metadata.width / 2).webp().toBuffer(function(err, outputBuffer, info) { + image.resize(Math.floor(metadata.width / 2)).webp().toBuffer(function(err, outputBuffer, info) { // outputBuffer contains a WebP image half the width and height of the original JPEG }); }); @@ -259,9 +259,9 @@ An advanced setting that switches the libvips access method to `VIPS_ACCESS_SEQU Scale output to `width` x `height`. By default, the resized image is cropped to the exact size specified. -`width` is the Number of pixels wide the resultant image should be. Use `null` or `undefined` to auto-scale the width to match the height. +`width` is the integral Number of pixels wide the resultant image should be, between 1 and 16383 (0x3FFF). Use `null` or `undefined` to auto-scale the width to match the height. -`height` is the Number of pixels high the resultant image should be. Use `null` or `undefined` to auto-scale the height to match the width. +`height` is the integral Number of pixels high the resultant image should be, between 1 and 16383. Use `null` or `undefined` to auto-scale the height to match the width. #### extract(top, left, width, height) diff --git a/index.js b/index.js index 3f1bb3dc..772ceba1 100755 --- a/index.js +++ b/index.js @@ -361,7 +361,7 @@ Sharp.prototype.resize = function(width, height) { if (!width) { this.options.width = -1; } else { - if (typeof width === 'number' && !Number.isNaN(width)) { + if (typeof width === 'number' && !Number.isNaN(width) && width % 1 === 0 && width > 0 && width <= 0x3FFF) { this.options.width = width; } else { throw new Error('Invalid width ' + width); @@ -370,7 +370,7 @@ Sharp.prototype.resize = function(width, height) { if (!height) { this.options.height = -1; } else { - if (typeof height === 'number' && !Number.isNaN(height)) { + if (typeof height === 'number' && !Number.isNaN(height) && height % 1 === 0 && height > 0 && height <= 0x3FFF) { this.options.height = height; } else { throw new Error('Invalid height ' + height); diff --git a/test/unit/metadata.js b/test/unit/metadata.js index cdd17d51..db741d38 100755 --- a/test/unit/metadata.js +++ b/test/unit/metadata.js @@ -176,7 +176,7 @@ describe('Image metadata', function() { assert.strictEqual(3, metadata.channels); assert.strictEqual(false, metadata.hasProfile); assert.strictEqual(false, metadata.hasAlpha); - image.resize(metadata.width / 2).toBuffer(function(err, data, info) { + image.resize(Math.floor(metadata.width / 2)).toBuffer(function(err, data, info) { if (err) throw err; assert.strictEqual(true, data.length > 0); assert.strictEqual(1362, info.width); diff --git a/test/unit/resize.js b/test/unit/resize.js index 93f4b34c..405316b7 100755 --- a/test/unit/resize.js +++ b/test/unit/resize.js @@ -64,7 +64,7 @@ describe('Resize dimensions', function() { }); }); - it('Invalid width', function(done) { + it('Invalid width - NaN', function(done) { var isValid = true; try { sharp(fixtures.inputJpg).resize('spoons', 240); @@ -75,7 +75,7 @@ describe('Resize dimensions', function() { done(); }); - it('Invalid height', function(done) { + it('Invalid height - NaN', function(done) { var isValid = true; try { sharp(fixtures.inputJpg).resize(320, 'spoons'); @@ -86,6 +86,50 @@ describe('Resize dimensions', function() { done(); }); + it('Invalid width - float', function(done) { + var isValid = true; + try { + sharp(fixtures.inputJpg).resize(1.5, 240); + } catch (err) { + isValid = false; + } + assert.strictEqual(false, isValid); + done(); + }); + + it('Invalid height - float', function(done) { + var isValid = true; + try { + sharp(fixtures.inputJpg).resize(320, 1.5); + } catch (err) { + isValid = false; + } + assert.strictEqual(false, isValid); + done(); + }); + + it('Invalid width - too large', function(done) { + var isValid = true; + try { + sharp(fixtures.inputJpg).resize(0x4000, 240); + } catch (err) { + isValid = false; + } + assert.strictEqual(false, isValid); + done(); + }); + + it('Invalid height - too large', function(done) { + var isValid = true; + try { + sharp(fixtures.inputJpg).resize(320, 0x4000); + } catch (err) { + isValid = false; + } + assert.strictEqual(false, isValid); + done(); + }); + it('TIFF embed known to cause rounding errors', function(done) { sharp(fixtures.inputTiff).resize(240, 320).embed().jpeg().toBuffer(function(err, data, info) { if (err) throw err;