Skip to content

Commit

Permalink
Limit total size of image instead of width and height individually.
Browse files Browse the repository at this point in the history
  • Loading branch information
fancycode committed Jun 28, 2024
1 parent 717999d commit b66b411
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 35 deletions.
3 changes: 1 addition & 2 deletions libheif/codecs/jpeg2000.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,7 @@ class Jpeg2000ImageCodec
// static Error decode_jpeg2000_image(const std::shared_ptr<const HeifFile>& heif_file,
// heif_item_id ID,
// std::shared_ptr<HeifPixelImage>& img,
// uint32_t maximum_image_width_limit,
// uint32_t maximum_image_height_limit,
// uint32_t maximum_image_size_limit,
// const std::vector<uint8_t>& uncompressed_data);

static Error encode_jpeg2000_image(const std::shared_ptr<HeifFile>& heif_file,
Expand Down
7 changes: 3 additions & 4 deletions libheif/codecs/mask_image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ Error Box_mskC::write(StreamWriter& writer) const
Error MaskImageCodec::decode_mask_image(const std::shared_ptr<const HeifFile>& heif_file,
heif_item_id ID,
std::shared_ptr<HeifPixelImage>& img,
uint32_t maximum_image_width_limit,
uint32_t maximum_image_height_limit,
uint64_t maximum_image_size_limit,
const std::vector<uint8_t>& data)
{
std::vector<std::shared_ptr<Box>> item_properties;
Expand All @@ -77,10 +76,10 @@ Error MaskImageCodec::decode_mask_image(const std::shared_ptr<const HeifFile>& h
width = ispe->get_width();
height = ispe->get_height();

if (width >= maximum_image_width_limit || height >= maximum_image_height_limit) {
if (width > maximum_image_size_limit / height) {
std::stringstream sstr;
sstr << "Image size " << width << "x" << height << " exceeds the maximum image size "
<< maximum_image_width_limit << "x" << maximum_image_height_limit << "\n";
<< maximum_image_size_limit << "\n";

return Error(heif_error_Memory_allocation_error,
heif_suberror_Security_limit_exceeded,
Expand Down
4 changes: 1 addition & 3 deletions libheif/codecs/mask_image.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ class MaskImageCodec
static Error decode_mask_image(const std::shared_ptr<const HeifFile>& heif_file,
heif_item_id ID,
std::shared_ptr<HeifPixelImage>& img,
uint32_t maximum_image_width_limit,
uint32_t maximum_image_height_limit,
uint64_t maximum_image_size_limit,
const std::vector<uint8_t>& data);
static Error encode_mask_image(const std::shared_ptr<HeifFile>& heif_file,
const std::shared_ptr<HeifPixelImage>& src_image,
Expand All @@ -84,4 +83,3 @@ class MaskImageCodec
};

#endif //LIBHEIF_MASK_IMAGE_H

9 changes: 4 additions & 5 deletions libheif/codecs/uncompressed_image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ class AbstractDecoder

std::vector<ChannelListEntry> channelList;

void buildChannelList(std::shared_ptr<HeifPixelImage>& img) {
void buildChannelList(std::shared_ptr<HeifPixelImage>& img) {
for (Box_uncC::Component component : m_uncC->get_components()) {
ChannelListEntry entry = buildChannelListEntry(component, img);
channelList.push_back(entry);
Expand Down Expand Up @@ -853,8 +853,7 @@ static AbstractDecoder* makeDecoder(uint32_t width, uint32_t height, const std::
Error UncompressedImageCodec::decode_uncompressed_image(const std::shared_ptr<const HeifFile>& heif_file,
heif_item_id ID,
std::shared_ptr<HeifPixelImage>& img,
uint32_t maximum_image_width_limit,
uint32_t maximum_image_height_limit,
uint32_t maximum_image_size_limit,
const std::vector<uint8_t>& uncompressed_data)
{
if (uncompressed_data.empty()) {
Expand Down Expand Up @@ -883,10 +882,10 @@ Error UncompressedImageCodec::decode_uncompressed_image(const std::shared_ptr<co
width = ispe->get_width();
height = ispe->get_height();

if (width >= maximum_image_width_limit || height >= maximum_image_height_limit) {
if (width > maximum_image_size_limit / height) {
std::stringstream sstr;
sstr << "Image size " << width << "x" << height << " exceeds the maximum image size "
<< maximum_image_width_limit << "x" << maximum_image_height_limit << "\n";
<< maximum_image_size_limit << "\n";
printf("way too big\n");
return Error(heif_error_Memory_allocation_error,
heif_suberror_Security_limit_exceeded,
Expand Down
3 changes: 1 addition & 2 deletions libheif/codecs/uncompressed_image.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ class UncompressedImageCodec
static Error decode_uncompressed_image(const std::shared_ptr<const HeifFile>& heif_file,
heif_item_id ID,
std::shared_ptr<HeifPixelImage>& img,
uint32_t maximum_image_width_limit,
uint32_t maximum_image_height_limit,
uint32_t maximum_image_size_limit,
const std::vector<uint8_t>& uncompressed_data);

static Error encode_uncompressed_image(const std::shared_ptr<HeifFile>& heif_file,
Expand Down
22 changes: 9 additions & 13 deletions libheif/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,7 @@ void ImageOverlay::get_offset(size_t image_index, int32_t* x, int32_t* y) const

HeifContext::HeifContext()
{
m_maximum_image_width_limit = MAX_IMAGE_WIDTH;
m_maximum_image_height_limit = MAX_IMAGE_HEIGHT;
m_maximum_image_size_limit = MAX_IMAGE_SIZE;

reset_to_empty_heif();
}
Expand Down Expand Up @@ -596,11 +595,10 @@ Error HeifContext::interpret_heif_file()

// --- check whether the image size is "too large"

if (width > m_maximum_image_width_limit ||
height > m_maximum_image_height_limit) {
if (width > m_maximum_image_size_limit / height) {
std::stringstream sstr;
sstr << "Image size " << width << "x" << height << " exceeds the maximum image size "
<< m_maximum_image_width_limit << "x" << m_maximum_image_height_limit << "\n";
<< m_maximum_image_size_limit << "\n";

return Error(heif_error_Memory_allocation_error,
heif_suberror_Security_limit_exceeded,
Expand Down Expand Up @@ -1503,8 +1501,7 @@ Error HeifContext::decode_image_planar(heif_item_id ID,
error = UncompressedImageCodec::decode_uncompressed_image(m_heif_file,
ID,
img,
m_maximum_image_width_limit,
m_maximum_image_height_limit,
m_maximum_image_size_limit,
data);
if (error) {
return error;
Expand All @@ -1521,8 +1518,7 @@ Error HeifContext::decode_image_planar(heif_item_id ID,
error = MaskImageCodec::decode_mask_image(m_heif_file,
ID,
img,
m_maximum_image_width_limit,
m_maximum_image_height_limit,
m_maximum_image_size_limit,
data);
if (error) {
return error;
Expand Down Expand Up @@ -1774,10 +1770,10 @@ Error HeifContext::decode_full_grid_image(heif_item_id ID,

// --- generate image of full output size

if (w >= m_maximum_image_width_limit || h >= m_maximum_image_height_limit) {
if (w > m_maximum_image_size_limit / h) {
std::stringstream sstr;
sstr << "Image size " << w << "x" << h << " exceeds the maximum image size "
<< m_maximum_image_width_limit << "x" << m_maximum_image_height_limit << "\n";
<< m_maximum_image_size_limit << "\n";

return Error(heif_error_Memory_allocation_error,
heif_suberror_Security_limit_exceeded,
Expand Down Expand Up @@ -2124,10 +2120,10 @@ Error HeifContext::decode_overlay_image(heif_item_id ID,
uint32_t w = overlay.get_canvas_width();
uint32_t h = overlay.get_canvas_height();

if (w >= m_maximum_image_width_limit || h >= m_maximum_image_height_limit) {
if (w > m_maximum_image_size_limit / h) {
std::stringstream sstr;
sstr << "Image size " << w << "x" << h << " exceeds the maximum image size "
<< m_maximum_image_width_limit << "x" << m_maximum_image_height_limit << "\n";
<< m_maximum_image_size_limit << "\n";

return Error(heif_error_Memory_allocation_error,
heif_suberror_Security_limit_exceeded,
Expand Down
9 changes: 5 additions & 4 deletions libheif/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ class HeifContext : public ErrorBuffer

void set_max_decoding_threads(int max_threads) { m_max_decoding_threads = max_threads; }

// Sets the maximum size of both width and height of an image. The total limit
// of the image size (width * height) will be "maximum_size * maximum_size".
void set_maximum_image_size_limit(int maximum_size)
{
m_maximum_image_width_limit = maximum_size;
m_maximum_image_height_limit = maximum_size;
m_maximum_image_size_limit = int64_t(maximum_size) * maximum_size;
}

Error read(const std::shared_ptr<StreamReader>& reader);
Expand Down Expand Up @@ -522,8 +523,8 @@ class HeifContext : public ErrorBuffer

int m_max_decoding_threads = 4;

uint32_t m_maximum_image_width_limit;
uint32_t m_maximum_image_height_limit;
// Maximum image size in pixels (width * height).
uint64_t m_maximum_image_size_limit;

std::vector<std::shared_ptr<RegionItem>> m_region_items;

Expand Down
3 changes: 1 addition & 2 deletions libheif/security_limits.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ static const int MAX_COLOR_PROFILE_SIZE = 100 * 1024 * 1024; // 100 MB

// Artificial limit to avoid allocating too much memory.
// 32768^2 = 1.5 GB as YUV-4:2:0 or 4 GB as RGB32
static const int MAX_IMAGE_WIDTH = 32768;
static const int MAX_IMAGE_HEIGHT = 32768;
static const int64_t MAX_IMAGE_SIZE = 32768 * 32768;

// Maximum nesting level of boxes in input files.
// We put a limit on this to avoid unlimited stack usage by malicious input files.
Expand Down

0 comments on commit b66b411

Please sign in to comment.