Fix #120857: Blender crashes for huge compositor images

Blender crashes when the user scales up an image into huge scales. This
is due to integer overflow when doing memory allocations. So we fix this
by using larger integers when doing math on memory allocations and
indexing.

Note that while this solves the random crashes, users scaling up images
to huge scales will face things like the OOM killer activating or at
best significant slow downs due to swapping.

It is not clear how to handle such cases, but something like a global
maximum size option that is set to 16k by default might be worth adding.

Pull Request: https://projects.blender.org/blender/blender/pulls/120921
This commit is contained in:
Omar Emara
2024-04-23 09:44:33 +02:00
committed by Omar Emara
parent 191b4fea5b
commit 614e5ecf7d
2 changed files with 7 additions and 6 deletions

View File

@@ -125,8 +125,8 @@ MemoryBuffer *MemoryBuffer::inflate() const
float MemoryBuffer::get_max_value() const
{
float result = buffer_[0];
const uint size = this->buffer_len();
uint i;
const int64_t size = this->buffer_len();
int64_t i;
const float *fp_src = buffer_;
@@ -408,7 +408,7 @@ void MemoryBuffer::fill_from(const MemoryBuffer &src)
void MemoryBuffer::write_pixel(int x, int y, const float color[4])
{
if (x >= rect_.xmin && x < rect_.xmax && y >= rect_.ymin && y < rect_.ymax) {
const int offset = get_coords_offset(x, y);
const intptr_t offset = get_coords_offset(x, y);
memcpy(&buffer_[offset], color, sizeof(float) * num_channels_);
}
}
@@ -416,7 +416,7 @@ void MemoryBuffer::write_pixel(int x, int y, const float color[4])
void MemoryBuffer::add_pixel(int x, int y, const float color[4])
{
if (x >= rect_.xmin && x < rect_.xmax && y >= rect_.ymin && y < rect_.ymax) {
const int offset = get_coords_offset(x, y);
const intptr_t offset = get_coords_offset(x, y);
float *dst = &buffer_[offset];
const float *src = color;
for (int i = 0; i < num_channels_; i++, dst++, src++) {

View File

@@ -15,6 +15,7 @@
#include "BLI_math_vector_types.hh"
#include "BLI_rect.h"
#include <cstdint>
#include <cstring>
struct ColormanageProcessor;
@@ -657,9 +658,9 @@ class MemoryBuffer {
private:
void set_strides();
const int buffer_len() const
const int64_t buffer_len() const
{
return get_memory_width() * get_memory_height();
return int64_t(get_memory_width()) * int64_t(get_memory_height());
}
void clear_elem(float *out) const