From 5522060e9e5b5d0ea796687ff3679bea1c7f28c7 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Mon, 10 Jul 2023 10:24:12 +0100 Subject: [PATCH] Limit HEIF output dimensions to 16384x16384 This is a slightly breaking change to sync with the behaviour of a forthcoming libvips patch release. It also matches the libavif limit. Having an arbitrary limit is safer than no limit. --- docs/changelog.md | 2 ++ src/common.cc | 4 ++++ src/pipeline.cc | 2 ++ test/unit/avif.js | 14 ++++++++++++++ 4 files changed, 22 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 3cc2fa96..c34b6932 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -6,6 +6,8 @@ Requires libvips v8.14.2 ### v0.32.2 - TBD +* Limit HEIF output dimensions to 16384x16384, matches libvips. + * Ensure exceptions are not thrown when terminating. [#3569](https://github.com/lovell/sharp/issues/3569) diff --git a/src/common.cc b/src/common.cc index dec73e88..e1cf4db5 100644 --- a/src/common.cc +++ b/src/common.cc @@ -669,6 +669,10 @@ namespace sharp { if (image.width() > 65535 || height > 65535) { throw vips::VError("Processed image is too large for the GIF format"); } + } else if (imageType == ImageType::HEIF) { + if (image.width() > 16384 || height > 16384) { + throw vips::VError("Processed image is too large for the HEIF format"); + } } } diff --git a/src/pipeline.cc b/src/pipeline.cc index 30cea840..26cf68f3 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -941,6 +941,7 @@ class PipelineWorker : public Napi::AsyncWorker { } else if (baton->formatOut == "heif" || (baton->formatOut == "input" && inputImageType == sharp::ImageType::HEIF)) { // Write HEIF to buffer + sharp::AssertImageTypeDimensions(image, sharp::ImageType::HEIF); image = sharp::RemoveAnimationProperties(image).cast(VIPS_FORMAT_UCHAR); VipsArea *area = reinterpret_cast(image.heifsave_buffer(VImage::option() ->set("strip", !baton->withMetadata) @@ -1130,6 +1131,7 @@ class PipelineWorker : public Napi::AsyncWorker { } else if (baton->formatOut == "heif" || (mightMatchInput && isHeif) || (willMatchInput && inputImageType == sharp::ImageType::HEIF)) { // Write HEIF to file + sharp::AssertImageTypeDimensions(image, sharp::ImageType::HEIF); image = sharp::RemoveAnimationProperties(image).cast(VIPS_FORMAT_UCHAR); image.heifsave(const_cast(baton->fileOut.data()), VImage::option() ->set("strip", !baton->withMetadata) diff --git a/test/unit/avif.js b/test/unit/avif.js index e546c2f1..ca9a2bc2 100644 --- a/test/unit/avif.js +++ b/test/unit/avif.js @@ -130,4 +130,18 @@ describe('AVIF', () => { width: 32 }); }); + + it('Invalid width - too large', async () => + assert.rejects( + () => sharp({ create: { width: 16385, height: 16, channels: 3, background: 'red' } }).avif().toBuffer(), + /Processed image is too large for the HEIF format/ + ) + ); + + it('Invalid height - too large', async () => + assert.rejects( + () => sharp({ create: { width: 16, height: 16385, channels: 3, background: 'red' } }).avif().toBuffer(), + /Processed image is too large for the HEIF format/ + ) + ); });