From d24adf7bae92c5649bda284e52c8d669becc3c99 Mon Sep 17 00:00:00 2001 From: Sayed Kaif Date: Tue, 23 Jun 2026 23:07:04 +0530 Subject: [PATCH] bound extract region to libvips coordinate limit --- docs/src/content/docs/api-resize.md | 8 ++++---- lib/index.d.ts | 8 ++++---- lib/resize.mjs | 12 ++++++------ test/unit/extract.js | 14 ++++++++++++++ 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/docs/src/content/docs/api-resize.md b/docs/src/content/docs/api-resize.md index eac265225..0051bde7e 100644 --- a/docs/src/content/docs/api-resize.md +++ b/docs/src/content/docs/api-resize.md @@ -236,10 +236,10 @@ Extract/crop a region of the image. | Param | Type | Description | | --- | --- | --- | | options | Object | describes the region to extract using integral pixel values | -| options.left | number | zero-indexed offset from left edge | -| options.top | number | zero-indexed offset from top edge | -| options.width | number | width of region to extract | -| options.height | number | height of region to extract | +| options.left | number | zero-indexed offset from left edge, an integer between 0 and 100000000 | +| options.top | number | zero-indexed offset from top edge, an integer between 0 and 100000000 | +| options.width | number | width of region to extract, an integer between 0 and 100000000 | +| options.height | number | height of region to extract, an integer between 0 and 100000000 | **Example** ```js diff --git a/lib/index.d.ts b/lib/index.d.ts index 08f4001de..3defe61d0 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -1598,13 +1598,13 @@ declare namespace sharp { } interface Region { - /** zero-indexed offset from left edge */ + /** zero-indexed offset from left edge, an integer between 0 and 100000000 */ left: number; - /** zero-indexed offset from top edge */ + /** zero-indexed offset from top edge, an integer between 0 and 100000000 */ top: number; - /** dimension of extracted image */ + /** dimension of extracted image, an integer between 0 and 100000000 */ width: number; - /** dimension of extracted image */ + /** dimension of extracted image, an integer between 0 and 100000000 */ height: number; } diff --git a/lib/resize.mjs b/lib/resize.mjs index ef97b8d4f..d1030c4ce 100644 --- a/lib/resize.mjs +++ b/lib/resize.mjs @@ -471,10 +471,10 @@ function extend (extend) { * }); * * @param {Object} options - describes the region to extract using integral pixel values - * @param {number} options.left - zero-indexed offset from left edge - * @param {number} options.top - zero-indexed offset from top edge - * @param {number} options.width - width of region to extract - * @param {number} options.height - height of region to extract + * @param {number} options.left - zero-indexed offset from left edge, an integer between 0 and 100000000 + * @param {number} options.top - zero-indexed offset from top edge, an integer between 0 and 100000000 + * @param {number} options.width - width of region to extract, an integer between 0 and 100000000 + * @param {number} options.height - height of region to extract, an integer between 0 and 100000000 * @returns {Sharp} * @throws {Error} Invalid parameters */ @@ -485,10 +485,10 @@ function extract (options) { } ['left', 'top', 'width', 'height'].forEach(function (name) { const value = options[name]; - if (is.integer(value) && value >= 0) { + if (is.integer(value) && is.inRange(value, 0, 100000000)) { this.options[name + (name === 'left' || name === 'top' ? 'Offset' : '') + suffix] = value; } else { - throw is.invalidParameterError(name, 'integer', value); + throw is.invalidParameterError(name, 'integer between 0 and 100000000', value); } }, this); // Ensure existing rotation occurs before pre-resize extraction diff --git a/test/unit/extract.js b/test/unit/extract.js index 5d771f087..55d986f02 100644 --- a/test/unit/extract.js +++ b/test/unit/extract.js @@ -282,6 +282,20 @@ suite('Partial image extraction', () => { }); }); + test('Oversized width', (t) => { + t.plan(1); + t.assert.throws(() => { + sharp(fixtures.inputJpg).extract({ left: 10, top: 10, width: 100000001, height: 10 }); + }, /Expected integer between 0 and 100000000 for width but received 100000001 of type number/); + }); + + test('Oversized left', (t) => { + t.plan(1); + t.assert.throws(() => { + sharp(fixtures.inputJpg).extract({ left: 2 ** 31, top: 10, width: 10, height: 10 }); + }, /Expected integer between 0 and 100000000 for left but received 2147483648 of type number/); + }); + test('Bad image area', async (t) => { t.plan(1); t.assert.rejects(