Allow values for limitInputPixels larger than 32-bit #3238

This commit is contained in:
Lovell Fuller 2022-05-28 08:35:17 +01:00
parent 48e3ea5e29
commit a0568ec0c3
5 changed files with 17 additions and 5 deletions

View File

@ -6,6 +6,9 @@ Requires libvips v8.12.2
### v0.30.6 - TBD ### 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). * Ensure brew-installed `vips` can be detected (regression in 0.30.5).
[#3239](https://github.com/lovell/sharp/issues/3239) [#3239](https://github.com/lovell/sharp/issues/3239)

View File

@ -86,10 +86,10 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
inputDescriptor.limitInputPixels = inputOptions.limitInputPixels inputDescriptor.limitInputPixels = inputOptions.limitInputPixels
? Math.pow(0x3FFF, 2) ? Math.pow(0x3FFF, 2)
: 0; : 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; inputDescriptor.limitInputPixels = inputOptions.limitInputPixels;
} else { } else {
throw is.invalidParameterError('limitInputPixels', 'integer >= 0', inputOptions.limitInputPixels); throw is.invalidParameterError('limitInputPixels', 'positive integer', inputOptions.limitInputPixels);
} }
} }
// unlimited // unlimited

View File

@ -48,6 +48,9 @@ namespace sharp {
int32_t AttrAsInt32(Napi::Object obj, unsigned int const attr) { int32_t AttrAsInt32(Napi::Object obj, unsigned int const attr) {
return obj.Get(attr).As<Napi::Number>().Int32Value(); return obj.Get(attr).As<Napi::Number>().Int32Value();
} }
int64_t AttrAsInt64(Napi::Object obj, std::string attr) {
return obj.Get(attr).As<Napi::Number>().Int64Value();
}
double AttrAsDouble(Napi::Object obj, std::string attr) { double AttrAsDouble(Napi::Object obj, std::string attr) {
return obj.Get(attr).As<Napi::Number>().DoubleValue(); return obj.Get(attr).As<Napi::Number>().DoubleValue();
} }
@ -131,7 +134,7 @@ namespace sharp {
} }
} }
// Limit input images to a given number of pixels, where pixels = width * height // Limit input images to a given number of pixels, where pixels = width * height
descriptor->limitInputPixels = AttrAsUint32(input, "limitInputPixels"); descriptor->limitInputPixels = static_cast<uint64_t>(AttrAsInt64(input, "limitInputPixels"));
// Allow switch from random to sequential access // Allow switch from random to sequential access
descriptor->access = AttrAsBool(input, "sequentialRead") ? VIPS_ACCESS_SEQUENTIAL : VIPS_ACCESS_RANDOM; descriptor->access = AttrAsBool(input, "sequentialRead") ? VIPS_ACCESS_SEQUENTIAL : VIPS_ACCESS_RANDOM;
// Remove safety features and allow unlimited SVG/PNG input // 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 // Limit input images to a given number of pixels, where pixels = width * height
if (descriptor->limitInputPixels > 0 && if (descriptor->limitInputPixels > 0 &&
static_cast<uint64_t>(image.width() * image.height()) > static_cast<uint64_t>(descriptor->limitInputPixels)) { static_cast<uint64_t>(image.width() * image.height()) > descriptor->limitInputPixels) {
throw vips::VError("Input image exceeds pixel limit"); throw vips::VError("Input image exceeds pixel limit");
} }
return std::make_tuple(image, imageType); return std::make_tuple(image, imageType);

View File

@ -49,7 +49,7 @@ namespace sharp {
std::string file; std::string file;
char *buffer; char *buffer;
VipsFailOn failOn; VipsFailOn failOn;
int limitInputPixels; uint64_t limitInputPixels;
bool unlimited; bool unlimited;
VipsAccess access; VipsAccess access;
size_t bufferLength; size_t bufferLength;

View File

@ -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', () => { it('Invalid fails - string', () => {
assert.throws(() => { assert.throws(() => {
sharp({ limitInputPixels: 'fail' }); sharp({ limitInputPixels: 'fail' });