diff --git a/docs/api.md b/docs/api.md index 540f1e24..52ee10f3 100644 --- a/docs/api.md +++ b/docs/api.md @@ -113,7 +113,8 @@ This will reduce memory usage and can improve performance on some systems. Do not process input images where the number of pixels (width * height) exceeds this limit. -`pixels` is the integral Number of pixels, with a value between 1 and the default 268402689 (0x3FFF * 0x3FFF). +`pixels` is either an integral Number of pixels, with a value between 1 and the default 268402689 (0x3FFF * 0x3FFF) or + a boolean. `false` will disable checking while `true` will revert to the default limit. ### Resizing diff --git a/index.js b/index.js index 8becf8d3..6972bd42 100644 --- a/index.js +++ b/index.js @@ -722,10 +722,17 @@ Sharp.prototype.resize = function(width, height) { /* Limit the total number of pixels for input images - Assumes the image dimensions contained in the file header can be trusted + Assumes the image dimensions contained in the file header can be trusted. + Alternatively can use boolean to disable or reset to default (maximum pixels) */ Sharp.prototype.limitInputPixels = function(limit) { - if (typeof limit === 'number' && !Number.isNaN(limit) && limit % 1 === 0 && limit > 0) { + //if we pass in false we represent the integer as 0 to disable + if(limit === false) { + limit = 0; + } else if(limit === true) { + limit = maximum.pixels; + } + if (typeof limit === 'number' && !Number.isNaN(limit) && limit % 1 === 0 && limit >= 0) { this.options.limitInputPixels = limit; } else { throw new Error('Invalid pixel limit (1 to ' + maximum.pixels + ') ' + limit); diff --git a/package.json b/package.json index aa6a96e8..961761cf 100644 --- a/package.json +++ b/package.json @@ -19,13 +19,14 @@ "Bernhard K. Weisshuhn ", "Chris Riley ", "David Carley ", - "John Tobin " + "John Tobin ", + "Kenton Gray " ], "description": "High performance Node.js module to resize JPEG, PNG, WebP and TIFF images using the libvips library", "scripts": { "clean": "rm -rf node_modules/ build/ include/ lib/ coverage/ test/fixtures/output.*", "test": "VIPS_WARNING=0 node ./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- --slow=5000 --timeout=30000 ./test/unit/*.js", - "test-win": "node ./node_modules/mocha/bin/mocha --slow=5000 --timeout=30000 ./test/unit/*.js", + "test-win": "node ./node_modules/mocha/bin/mocha --slow=5000 --timeout=60000 ./test/unit/*.js", "test-leak": "./test/leak/leak.sh", "test-packaging": "./packaging/test.sh", "test-clean": "rm -rf coverage/ test/fixtures/output.* && npm install && npm test" diff --git a/src/pipeline.cc b/src/pipeline.cc index 16b25cde..63aef9d9 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -158,7 +158,8 @@ class PipelineWorker : public AsyncWorker { } // Limit input images to a given number of pixels, where pixels = width * height - if (image.width() * image.height() > baton->limitInputPixels) { + // Ignore if 0 + if (baton->limitInputPixels > 0 && image.width() * image.height() > baton->limitInputPixels) { (baton->err).append("Input image exceeds pixel limit"); return Error(); } diff --git a/test/fixtures/giant-image.png b/test/fixtures/giant-image.png new file mode 100644 index 00000000..92c08a77 Binary files /dev/null and b/test/fixtures/giant-image.png differ diff --git a/test/fixtures/index.js b/test/fixtures/index.js index 28bb96ad..6d80af16 100644 --- a/test/fixtures/index.js +++ b/test/fixtures/index.js @@ -79,6 +79,7 @@ module.exports = { inputPngOverlayLayer2LowAlpha: getPath('alpha-layer-2-ink-low-alpha.png'), inputPngAlphaPremultiplicationSmall: getPath('alpha-premultiply-1024x768-paper.png'), inputPngAlphaPremultiplicationLarge: getPath('alpha-premultiply-2048x1536-paper.png'), + inputPngLarge: getPath('giant-image.png'), inputWebP: getPath('4.webp'), // http://www.gstatic.com/webp/gallery/4.webp inputWebPWithTransparency: getPath('5_webp_a.webp'), // http://www.gstatic.com/webp/gallery3/5_webp_a.webp diff --git a/test/unit/io.js b/test/unit/io.js index 923b4d9e..30df745f 100644 --- a/test/unit/io.js +++ b/test/unit/io.js @@ -876,6 +876,24 @@ describe('Input/output', function() { }); }); + it('Disabling limit works', function(done) { + sharp(fixtures.inputPngLarge) + .limitInputPixels(false) + .toBuffer(function(err) { + assert.strictEqual(true, !err); + done(); + }); + }); + + it('Enabling default limit fails works and fails with a large image', function(done) { + sharp(fixtures.inputPngLarge) + .limitInputPixels(true) + .toBuffer(function(err) { + assert.strictEqual(true, !!err); + done(); + }); + }); + it('Smaller than input fails', function(done) { sharp(fixtures.inputJpg).metadata(function(err, metadata) { if (err) throw err;