mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Expose unlimited option for SVG and PNG input #2984
This commit is contained in:
parent
549219f32a
commit
407bfcb42a
@ -18,6 +18,9 @@ Requires libvips v8.12.0
|
||||
[#2976](https://github.com/lovell/sharp/pull/2976)
|
||||
[@driannaude](https://github.com/driannaude)
|
||||
|
||||
* Expose `unlimited` option for SVG and PNG input, switches off safety features.
|
||||
[#2984](https://github.com/lovell/sharp/issues/2984)
|
||||
|
||||
## v0.29 - *circle*
|
||||
|
||||
Requires libvips v8.11.3
|
||||
|
@ -103,6 +103,7 @@ const debuglog = util.debuglog('sharp');
|
||||
* @param {number|boolean} [options.limitInputPixels=268402689] - Do not process input images where the number of pixels
|
||||
* (width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted.
|
||||
* An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF).
|
||||
* @param {boolean} [options.unlimited=false] - Set this to `true` to remove safety features that help prevent memory exhaustion (SVG, PNG).
|
||||
* @param {boolean} [options.sequentialRead=false] - Set this to `true` to use sequential rather than random access where possible.
|
||||
* This can reduce memory usage and might improve performance on some systems.
|
||||
* @param {number} [options.density=72] - number representing the DPI for vector images in the range 1 to 100000.
|
||||
|
15
lib/input.js
15
lib/input.js
@ -9,9 +9,9 @@ const sharp = require('./sharp');
|
||||
* @private
|
||||
*/
|
||||
function _inputOptionsFromObject (obj) {
|
||||
const { raw, density, limitInputPixels, sequentialRead, failOnError, animated, page, pages, subifd } = obj;
|
||||
return [raw, density, limitInputPixels, sequentialRead, failOnError, animated, page, pages, subifd].some(is.defined)
|
||||
? { raw, density, limitInputPixels, sequentialRead, failOnError, animated, page, pages, subifd }
|
||||
const { raw, density, limitInputPixels, unlimited, sequentialRead, failOnError, animated, page, pages, subifd } = obj;
|
||||
return [raw, density, limitInputPixels, unlimited, sequentialRead, failOnError, animated, page, pages, subifd].some(is.defined)
|
||||
? { raw, density, limitInputPixels, unlimited, sequentialRead, failOnError, animated, page, pages, subifd }
|
||||
: undefined;
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
||||
const inputDescriptor = {
|
||||
failOnError: true,
|
||||
limitInputPixels: Math.pow(0x3FFF, 2),
|
||||
unlimited: false,
|
||||
sequentialRead: false
|
||||
};
|
||||
if (is.string(input)) {
|
||||
@ -83,6 +84,14 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
||||
throw is.invalidParameterError('limitInputPixels', 'integer >= 0', inputOptions.limitInputPixels);
|
||||
}
|
||||
}
|
||||
// unlimited
|
||||
if (is.defined(inputOptions.unlimited)) {
|
||||
if (is.bool(inputOptions.unlimited)) {
|
||||
inputDescriptor.unlimited = inputOptions.unlimited;
|
||||
} else {
|
||||
throw is.invalidParameterError('unlimited', 'boolean', inputOptions.unlimited);
|
||||
}
|
||||
}
|
||||
// sequentialRead
|
||||
if (is.defined(inputOptions.sequentialRead)) {
|
||||
if (is.bool(inputOptions.sequentialRead)) {
|
||||
|
@ -132,6 +132,8 @@ namespace sharp {
|
||||
descriptor->limitInputPixels = AttrAsUint32(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
|
||||
descriptor->unlimited = AttrAsBool(input, "unlimited");
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@ -328,7 +330,7 @@ namespace sharp {
|
||||
vips::VOption *option = VImage::option()
|
||||
->set("access", descriptor->access)
|
||||
->set("fail", descriptor->failOnError);
|
||||
if (imageType == ImageType::SVG) {
|
||||
if (descriptor->unlimited && (imageType == ImageType::SVG || imageType == ImageType::PNG)) {
|
||||
option->set("unlimited", TRUE);
|
||||
}
|
||||
if (imageType == ImageType::SVG || imageType == ImageType::PDF) {
|
||||
@ -403,7 +405,7 @@ namespace sharp {
|
||||
vips::VOption *option = VImage::option()
|
||||
->set("access", descriptor->access)
|
||||
->set("fail", descriptor->failOnError);
|
||||
if (imageType == ImageType::SVG) {
|
||||
if (descriptor->unlimited && (imageType == ImageType::SVG || imageType == ImageType::PNG)) {
|
||||
option->set("unlimited", TRUE);
|
||||
}
|
||||
if (imageType == ImageType::SVG || imageType == ImageType::PDF) {
|
||||
|
@ -50,6 +50,7 @@ namespace sharp {
|
||||
char *buffer;
|
||||
bool failOnError;
|
||||
int limitInputPixels;
|
||||
bool unlimited;
|
||||
VipsAccess access;
|
||||
size_t bufferLength;
|
||||
bool isBuffer;
|
||||
@ -75,6 +76,7 @@ namespace sharp {
|
||||
buffer(nullptr),
|
||||
failOnError(TRUE),
|
||||
limitInputPixels(0x3FFF * 0x3FFF),
|
||||
unlimited(FALSE),
|
||||
access(VIPS_ACCESS_RANDOM),
|
||||
bufferLength(0),
|
||||
isBuffer(FALSE),
|
||||
|
@ -648,6 +648,19 @@ describe('Input/output', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Switch off safety limits for PNG/SVG input', () => {
|
||||
it('Valid', () => {
|
||||
assert.doesNotThrow(() => {
|
||||
sharp({ unlimited: true });
|
||||
});
|
||||
});
|
||||
it('Invalid', () => {
|
||||
assert.throws(() => {
|
||||
sharp({ unlimited: -1 });
|
||||
}, /Expected boolean for unlimited but received -1 of type number/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Limit pixel count of input image', () => {
|
||||
it('Invalid fails - negative', () => {
|
||||
assert.throws(() => {
|
||||
@ -671,7 +684,9 @@ describe('Input/output', function () {
|
||||
sharp(fixtures.inputJpg)
|
||||
.metadata()
|
||||
.then(({ width, height }) =>
|
||||
sharp(fixtures.inputJpg, { limitInputPixels: width * height }).toBuffer()
|
||||
sharp(fixtures.inputJpg, { limitInputPixels: width * height })
|
||||
.resize(2)
|
||||
.toBuffer()
|
||||
)
|
||||
);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user