From b370e22c57d1b4993923c8ce0a6dd862da10901f Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 14 Oct 2024 15:28:13 +0200 Subject: [PATCH] refactor, cleanup --- libheif/api/libheif/heif.cc | 2 +- libheif/codecs/uncompressed/unc_codec.cc | 3 +- libheif/context.cc | 30 ++---------------- libheif/context.h | 4 +-- libheif/error.h | 2 -- libheif/image-items/grid.cc | 9 +++--- libheif/image-items/image_item.cc | 39 ++---------------------- libheif/image-items/image_item.h | 5 --- libheif/image-items/mask_image.cc | 5 +-- libheif/image-items/overlay.cc | 5 +-- libheif/image-items/tiled.cc | 2 +- libheif/image-items/unc_image.cc | 2 +- libheif/security_limits.cc | 28 +++++++++++++++++ libheif/security_limits.h | 5 +++ 14 files changed, 55 insertions(+), 86 deletions(-) diff --git a/libheif/api/libheif/heif.cc b/libheif/api/libheif/heif.cc index 4ef92b1a7b..5f9957909e 100644 --- a/libheif/api/libheif/heif.cc +++ b/libheif/api/libheif/heif.cc @@ -68,7 +68,7 @@ #include -const struct heif_error heif_error_success = {heif_error_Ok, heif_suberror_Unspecified, kSuccess}; +const struct heif_error heif_error_success = {heif_error_Ok, heif_suberror_Unspecified, Error::kSuccess}; static struct heif_error error_unsupported_parameter = {heif_error_Usage_error, heif_suberror_Unsupported_parameter, "Unsupported encoder parameter"}; diff --git a/libheif/codecs/uncompressed/unc_codec.cc b/libheif/codecs/uncompressed/unc_codec.cc index 0ce5759f32..8718cbc5fe 100644 --- a/libheif/codecs/uncompressed/unc_codec.cc +++ b/libheif/codecs/uncompressed/unc_codec.cc @@ -38,6 +38,7 @@ #include #include #include +#include "security_limits.h" bool isKnownUncompressedFrameConfigurationBoxProfile(const std::shared_ptr& uncC) @@ -602,7 +603,7 @@ Error UncompressedImageCodec::decode_uncompressed_image(const HeifContext* conte assert(ispe); uint32_t width = ispe->get_width(); uint32_t height = ispe->get_height(); - error = context->check_resolution(width, height); + error = check_for_valid_image_size(context->get_security_limits(), width, height); if (error) { return error; } diff --git a/libheif/context.cc b/libheif/context.cc index 1278da4ab3..778fe8f743 100644 --- a/libheif/context.cc +++ b/libheif/context.cc @@ -88,7 +88,7 @@ struct heif_error heif_encoder::alloc() return error; } - struct heif_error err = {heif_error_Ok, heif_suberror_Unspecified, kSuccess}; + struct heif_error err = {heif_error_Ok, heif_suberror_Unspecified, Error::kSuccess}; return err; } @@ -185,32 +185,6 @@ void HeifContext::reset_to_empty_heif() m_primary_image.reset(); } -Error HeifContext::check_resolution(uint32_t width, uint32_t height) const { - - // TODO: remove this. Has been moved to ImageItem::check_for_valid_image_size() - - // --- check whether the image size is "too large" - uint32_t max_width_height = static_cast(std::numeric_limits::max()); - if ((width > max_width_height || height > max_width_height) || - (height != 0 && width > get_security_limits()->max_image_size_pixels / height)) { - std::stringstream sstr; - sstr << "Image size " << width << "x" << height << " exceeds the maximum image size " - << get_security_limits()->max_image_size_pixels << "\n"; - - return Error(heif_error_Memory_allocation_error, - heif_suberror_Security_limit_exceeded, - sstr.str()); - } - - if (width==0 || height==0) { - return Error(heif_error_Memory_allocation_error, - heif_suberror_Invalid_image_size, - "zero width or height"); - } - - return Error::Ok; -} - std::vector> HeifContext::get_top_level_images(bool return_error_images) { @@ -1201,7 +1175,7 @@ Error HeifContext::encode_image(const std::shared_ptr& pixel_ima out_image = image_item; - insert_new_image(image_item->get_id(), image_item); + insert_image_item(image_item->get_id(), image_item); // --- if there is an alpha channel, add it as an additional image diff --git a/libheif/context.h b/libheif/context.h index 422f5ad352..4ed4c3e92d 100644 --- a/libheif/context.h +++ b/libheif/context.h @@ -83,13 +83,11 @@ class HeifContext : public ErrorBuffer Error read_from_memory(const void* data, size_t size, bool copy); - Error check_resolution(uint32_t width, uint32_t height) const; - std::shared_ptr get_heif_file() const { return m_heif_file; } std::vector> get_top_level_images(bool return_error_images); - void insert_new_image(heif_item_id id, std::shared_ptr img) { + void insert_image_item(heif_item_id id, std::shared_ptr img) { m_all_images.insert(std::make_pair(id, img)); } diff --git a/libheif/error.h b/libheif/error.h index 32fd871338..2a8249c626 100644 --- a/libheif/error.h +++ b/libheif/error.h @@ -35,8 +35,6 @@ #include "libheif/heif.h" #include -static constexpr char kSuccess[] = "Success"; - class ErrorBuffer { diff --git a/libheif/image-items/grid.cc b/libheif/image-items/grid.cc index 1a0b035d2c..44a0260ef8 100644 --- a/libheif/image-items/grid.cc +++ b/libheif/image-items/grid.cc @@ -27,6 +27,7 @@ #include #include #include +#include "security_limits.h" Error ImageGrid::parse(const std::vector& data) @@ -247,7 +248,7 @@ Result> ImageItem_Grid::decode_full_grid_image(c const uint32_t w = grid.get_width(); const uint32_t h = grid.get_height(); - Error err = check_resolution(w, h); + Error err = check_for_valid_image_size(get_context()->get_security_limits(), w, h); if (err) { return err; } @@ -292,7 +293,7 @@ Result> ImageItem_Grid::decode_full_grid_image(c uint32_t src_width = tileImg->get_width(); uint32_t src_height = tileImg->get_height(); - err = check_resolution(src_width, src_height); + err = check_for_valid_image_size(get_context()->get_security_limits(), src_width, src_height); if (err) { return err; } @@ -588,7 +589,7 @@ Result> ImageItem_Grid::add_new_grid_item(HeifCo grid_image->set_grid_spec(grid); grid_image->set_resolution(output_width, output_height); - ctx->insert_new_image(grid_id, grid_image); + ctx->insert_image_item(grid_id, grid_image); const int construction_method = 1; // 0=mdat 1=idat file->append_iloc_data(grid_id, grid_data, construction_method); @@ -682,7 +683,7 @@ Result> ImageItem_Grid::add_and_encode_full_grid // Create Grid Item heif_item_id grid_id = file->add_new_image(fourcc("grid")); griditem = std::make_shared(ctx, grid_id); - ctx->insert_new_image(grid_id, griditem); + ctx->insert_image_item(grid_id, griditem); const int construction_method = 1; // 0=mdat 1=idat file->append_iloc_data(grid_id, grid_data, construction_method); diff --git a/libheif/image-items/image_item.cc b/libheif/image-items/image_item.cc index 843b5f068b..c4ded16f95 100644 --- a/libheif/image-items/image_item.cc +++ b/libheif/image-items/image_item.cc @@ -35,6 +35,8 @@ #include "color-conversion/colorconversion.h" #include "api/libheif/api_structs.h" #include "plugin_registry.h" +#include "security_limits.h" + #include #include #include @@ -65,12 +67,6 @@ std::shared_ptr ImageItem::get_file() const } -Error ImageItem::check_resolution(uint32_t w, uint32_t h) const -{ - return m_heif_context->check_resolution(w, h); -} - - Error ImageItem::init_decoder_from_item(heif_item_id id) { m_id = id; @@ -668,35 +664,6 @@ void ImageItem::CodedImageData::append_with_4bytes_size(const uint8_t* data, siz } -Error ImageItem::check_for_valid_image_size(uint32_t width, uint32_t height) const -{ - uint64_t maximum_image_size_limit = m_heif_context->get_maximum_image_size_limit(); - - // --- check whether the image size is "too large" - - auto max_width_height = static_cast(std::numeric_limits::max()); - if ((width > max_width_height || height > max_width_height) || - (height != 0 && width > maximum_image_size_limit / height)) { - std::stringstream sstr; - sstr << "Image size " << width << "x" << height << " exceeds the maximum image size " - << maximum_image_size_limit << "\n"; - - return {heif_error_Memory_allocation_error, - heif_suberror_Security_limit_exceeded, - sstr.str()}; - } - - if (width == 0 || height == 0) { - return {heif_error_Memory_allocation_error, - heif_suberror_Invalid_image_size, - "zero width or height"}; - } - - return Error::Ok; - -} - - Error ImageItem::transform_requested_tile_position_to_original_tile_position(uint32_t& tile_x, uint32_t& tile_y) const { Result>> propertiesResult = get_properties(); @@ -764,7 +731,7 @@ Result> ImageItem::decode_image(const struct hei if (!decode_tile_only) { auto ispe = m_heif_context->get_heif_file()->get_property(m_id); if (ispe) { - Error err = check_for_valid_image_size(ispe->get_width(), ispe->get_height()); + Error err = check_for_valid_image_size(get_context()->get_security_limits(), ispe->get_width(), ispe->get_height()); if (err) { return err; } diff --git a/libheif/image-items/image_item.h b/libheif/image-items/image_item.h index 39250505db..8149b58c61 100644 --- a/libheif/image-items/image_item.h +++ b/libheif/image-items/image_item.h @@ -46,7 +46,6 @@ class ImageMetadata }; - class ImageItem : public ErrorBuffer { public: @@ -97,8 +96,6 @@ class ImageItem : public ErrorBuffer std::shared_ptr get_file() const; - Error check_resolution(uint32_t w, uint32_t h) const; - void set_resolution(uint32_t w, uint32_t h) { m_width = w; @@ -275,8 +272,6 @@ class ImageItem : public ErrorBuffer virtual Result> get_compressed_image_data() const; - Error check_for_valid_image_size(uint32_t width, uint32_t height) const; - Result>> get_properties() const; // === encoding === diff --git a/libheif/image-items/mask_image.cc b/libheif/image-items/mask_image.cc index da21641ba7..98ddb06501 100644 --- a/libheif/image-items/mask_image.cc +++ b/libheif/image-items/mask_image.cc @@ -20,7 +20,6 @@ * along with libheif. If not, see . */ - #include #include #include @@ -31,6 +30,8 @@ #include "logging.h" #include "mask_image.h" #include "image_item.h" +#include "security_limits.h" + Error Box_mskC::parse(BitstreamRange& range, const heif_security_limits* limits) { @@ -71,7 +72,7 @@ Error MaskImageCodec::decode_mask_image(const HeifContext* context, width = ispe->get_width(); height = ispe->get_height(); - Error error = context->check_resolution(width, height); + Error error = check_for_valid_image_size(context->get_security_limits(), width, height); if (error) { return error; } diff --git a/libheif/image-items/overlay.cc b/libheif/image-items/overlay.cc index 2eb041ee06..df91f83e81 100644 --- a/libheif/image-items/overlay.cc +++ b/libheif/image-items/overlay.cc @@ -22,6 +22,7 @@ #include "context.h" #include "file.h" #include "color-conversion/colorconversion.h" +#include "security_limits.h" template @@ -287,7 +288,7 @@ Result> ImageItem_Overlay::decode_overlay_image( uint32_t w = m_overlay_spec.get_canvas_width(); uint32_t h = m_overlay_spec.get_canvas_height(); - Error err = check_resolution(w, h); + Error err = check_for_valid_image_size(get_context()->get_security_limits(), w, h); if (err) { return err; } @@ -416,7 +417,7 @@ Result> ImageItem_Overlay::add_new_overlay_it heif_item_id iovl_id = file->add_new_image(fourcc("iovl")); std::shared_ptr iovl_image = std::make_shared(ctx, iovl_id); - ctx->insert_new_image(iovl_id, iovl_image); + ctx->insert_image_item(iovl_id, iovl_image); const int construction_method = 1; // 0=mdat 1=idat file->append_iloc_data(iovl_id, iovl_data, construction_method); diff --git a/libheif/image-items/tiled.cc b/libheif/image-items/tiled.cc index f61a99e18b..7bf2b93d72 100644 --- a/libheif/image-items/tiled.cc +++ b/libheif/image-items/tiled.cc @@ -518,7 +518,7 @@ ImageItem_Tiled::add_new_tiled_item(HeifContext* ctx, const heif_tiled_image_par heif_item_id tild_id = ctx->get_heif_file()->add_new_image(fourcc("tili")); auto tild_image = std::make_shared(ctx, tild_id); tild_image->set_resolution(parameters->image_width, parameters->image_height); - ctx->insert_new_image(tild_id, tild_image); + ctx->insert_image_item(tild_id, tild_image); // Create tilC box diff --git a/libheif/image-items/unc_image.cc b/libheif/image-items/unc_image.cc index 1bca4fa0b6..255f1e7530 100644 --- a/libheif/image-items/unc_image.cc +++ b/libheif/image-items/unc_image.cc @@ -321,7 +321,7 @@ Result> ImageItem_uncompressed::add_unci heif_item_id unci_id = ctx->get_heif_file()->add_new_image(fourcc("unci")); auto unci_image = std::make_shared(ctx, unci_id); unci_image->set_resolution(parameters->image_width, parameters->image_height); - ctx->insert_new_image(unci_id, unci_image); + ctx->insert_image_item(unci_id, unci_image); // Generate headers diff --git a/libheif/security_limits.cc b/libheif/security_limits.cc index 011f4ee089..26f2abeeb5 100644 --- a/libheif/security_limits.cc +++ b/libheif/security_limits.cc @@ -40,3 +40,31 @@ struct heif_security_limits global_security_limits { .max_color_profile_size = 100 * 1024 * 1024, // 100 MB .max_memory_block_size = 512 * 1024 * 1024 // 512 MB }; + + +Error check_for_valid_image_size(const heif_security_limits* limits, uint32_t width, uint32_t height) +{ + uint64_t maximum_image_size_limit = limits->max_image_size_pixels; + + // --- check whether the image size is "too large" + + auto max_width_height = static_cast(std::numeric_limits::max()); + if ((width > max_width_height || height > max_width_height) || + (height != 0 && width > maximum_image_size_limit / height)) { + std::stringstream sstr; + sstr << "Image size " << width << "x" << height << " exceeds the maximum image size " + << maximum_image_size_limit << "\n"; + + return {heif_error_Memory_allocation_error, + heif_suberror_Security_limit_exceeded, + sstr.str()}; + } + + if (width == 0 || height == 0) { + return {heif_error_Memory_allocation_error, + heif_suberror_Invalid_image_size, + "zero width or height"}; + } + + return Error::Ok; +} diff --git a/libheif/security_limits.h b/libheif/security_limits.h index 2e735986d8..aece26191e 100644 --- a/libheif/security_limits.h +++ b/libheif/security_limits.h @@ -23,6 +23,8 @@ #include "libheif/heif.h" #include #include +#include "error.h" + extern heif_security_limits global_security_limits; @@ -35,4 +37,7 @@ static const int64_t MAX_LARGE_BOX_SIZE = 0x0FFFFFFFFFFFFFFF; static const int64_t MAX_FILE_POS = 0x007FFFFFFFFFFFFFLL; // maximum file position static const int MAX_FRACTION_VALUE = 0x10000; + +Error check_for_valid_image_size(const heif_security_limits* limits, uint32_t width, uint32_t height); + #endif // LIBHEIF_SECURITY_LIMITS_H