From a0568ec0c312e7fa290874ddfa6797b93ffe0a67 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 28 May 2022 08:35:17 +0100 Subject: [PATCH] Allow values for limitInputPixels larger than 32-bit #3238 --- docs/changelog.md | 3 +++ lib/input.js | 4 ++-- src/common.cc | 7 +++++-- src/common.h | 2 +- test/unit/io.js | 6 ++++++ 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index aa23cb510..d9fe6c9ff 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -6,6 +6,9 @@ Requires libvips v8.12.2 ### v0.30.6 - TBD +* Allow values for `limitInputPixels` larger than 32-bit. + [#3238](https://github.com/lovell/sharp/issues/3238) + * Ensure brew-installed `vips` can be detected (regression in 0.30.5). [#3239](https://github.com/lovell/sharp/issues/3239) diff --git a/lib/input.js b/lib/input.js index 04aa42f39..494d43d35 100644 --- a/lib/input.js +++ b/lib/input.js @@ -86,10 +86,10 @@ function _createInputDescriptor (input, inputOptions, containerOptions) { inputDescriptor.limitInputPixels = inputOptions.limitInputPixels ? Math.pow(0x3FFF, 2) : 0; - } else if (is.integer(inputOptions.limitInputPixels) && inputOptions.limitInputPixels >= 0) { + } else if (is.integer(inputOptions.limitInputPixels) && is.inRange(inputOptions.limitInputPixels, 0, Number.MAX_SAFE_INTEGER)) { inputDescriptor.limitInputPixels = inputOptions.limitInputPixels; } else { - throw is.invalidParameterError('limitInputPixels', 'integer >= 0', inputOptions.limitInputPixels); + throw is.invalidParameterError('limitInputPixels', 'positive integer', inputOptions.limitInputPixels); } } // unlimited diff --git a/src/common.cc b/src/common.cc index 3eae11984..751e41d73 100644 --- a/src/common.cc +++ b/src/common.cc @@ -48,6 +48,9 @@ namespace sharp { int32_t AttrAsInt32(Napi::Object obj, unsigned int const attr) { return obj.Get(attr).As().Int32Value(); } + int64_t AttrAsInt64(Napi::Object obj, std::string attr) { + return obj.Get(attr).As().Int64Value(); + } double AttrAsDouble(Napi::Object obj, std::string attr) { return obj.Get(attr).As().DoubleValue(); } @@ -131,7 +134,7 @@ namespace sharp { } } // Limit input images to a given number of pixels, where pixels = width * height - descriptor->limitInputPixels = AttrAsUint32(input, "limitInputPixels"); + descriptor->limitInputPixels = static_cast(AttrAsInt64(input, "limitInputPixels")); // Allow switch from random to sequential access descriptor->access = AttrAsBool(input, "sequentialRead") ? VIPS_ACCESS_SEQUENTIAL : VIPS_ACCESS_RANDOM; // Remove safety features and allow unlimited SVG/PNG input @@ -439,7 +442,7 @@ namespace sharp { } // Limit input images to a given number of pixels, where pixels = width * height if (descriptor->limitInputPixels > 0 && - static_cast(image.width() * image.height()) > static_cast(descriptor->limitInputPixels)) { + static_cast(image.width() * image.height()) > descriptor->limitInputPixels) { throw vips::VError("Input image exceeds pixel limit"); } return std::make_tuple(image, imageType); diff --git a/src/common.h b/src/common.h index 9065065fa..2a43597d6 100644 --- a/src/common.h +++ b/src/common.h @@ -49,7 +49,7 @@ namespace sharp { std::string file; char *buffer; VipsFailOn failOn; - int limitInputPixels; + uint64_t limitInputPixels; bool unlimited; VipsAccess access; size_t bufferLength; diff --git a/test/unit/io.js b/test/unit/io.js index dc6004aaf..dd8199be5 100644 --- a/test/unit/io.js +++ b/test/unit/io.js @@ -706,6 +706,12 @@ describe('Input/output', function () { }); }); + it('Invalid fails - integer overflow', () => { + assert.throws(() => { + sharp({ limitInputPixels: Number.MAX_SAFE_INTEGER + 1 }); + }); + }); + it('Invalid fails - string', () => { assert.throws(() => { sharp({ limitInputPixels: 'fail' });