Fix: integer overflows calculating the number of pixels in imbuf

Use size_t for imbuf size calculation to prevent integer overflow.

Back ported from: 6d6c695619b5199d2306eede273b9c50ebd10a28

Pull Request: https://projects.blender.org/blender/blender/pulls/137443
This commit is contained in:
Campbell Barton
2025-04-14 10:12:00 +02:00
committed by Thomas Dinges
parent ac5b00a453
commit 358d4b8e02
7 changed files with 25 additions and 24 deletions
+2 -3
View File
@@ -2647,10 +2647,9 @@ void BKE_stamp_info_from_imbuf(RenderResult *rr, ImBuf *ibuf)
bool BKE_imbuf_alpha_test(ImBuf *ibuf)
{
int tot;
if (ibuf->float_buffer.data) {
const float *buf = ibuf->float_buffer.data;
for (tot = ibuf->x * ibuf->y; tot--; buf += 4) {
for (size_t tot = size_t(ibuf->x) * size_t(ibuf->y); tot--; buf += 4) {
if (buf[3] < 1.0f) {
return true;
}
@@ -2658,7 +2657,7 @@ bool BKE_imbuf_alpha_test(ImBuf *ibuf)
}
else if (ibuf->byte_buffer.data) {
uchar *buf = ibuf->byte_buffer.data;
for (tot = ibuf->x * ibuf->y; tot--; buf += 4) {
for (size_t tot = size_t(ibuf->x) * size_t(ibuf->y); tot--; buf += 4) {
if (buf[3] != 255) {
return true;
}
@@ -90,7 +90,8 @@ ImBuf *bitmap_to_image(const Bitmap &bm)
const int words_per_scanline = bm.dy;
const Span<potrace_word> words = {bm.map, num_words};
MutableSpan<ColorGeometry4b> colors = {
reinterpret_cast<ColorGeometry4b *>(ibuf->byte_buffer.data), ibuf->x * ibuf->y};
reinterpret_cast<ColorGeometry4b *>(ibuf->byte_buffer.data),
int64_t(size_t(ibuf->x) * size_t(ibuf->y))};
threading::parallel_for(IndexRange(ibuf->y), 4096, [&](const IndexRange range) {
for (const int y : range) {
Span<potrace_word> scanline_words = words.slice(
+1 -1
View File
@@ -723,7 +723,7 @@ size_t IMB_get_size_in_memory(ImBuf *ibuf)
channel_size += sizeof(float);
}
size += channel_size * ibuf->x * ibuf->y * ibuf->channels;
size += channel_size * size_t(ibuf->x) * size_t(ibuf->y) * size_t(ibuf->channels);
if (ibuf->miptot) {
for (a = 0; a < ibuf->miptot; a++) {
+3 -3
View File
@@ -1239,11 +1239,11 @@ void IMB_rectfill_area(
void IMB_rectfill_alpha(ImBuf *ibuf, const float value)
{
int i;
size_t i;
if (ibuf->float_buffer.data && (ibuf->channels == 4)) {
float *fbuf = ibuf->float_buffer.data + 3;
for (i = ibuf->x * ibuf->y; i > 0; i--, fbuf += 4) {
for (i = size_t(ibuf->x) * size_t(ibuf->y); i > 0; i--, fbuf += 4) {
*fbuf = value;
}
}
@@ -1251,7 +1251,7 @@ void IMB_rectfill_alpha(ImBuf *ibuf, const float value)
if (ibuf->byte_buffer.data) {
const uchar cvalue = value * 255;
uchar *cbuf = ibuf->byte_buffer.data + 3;
for (i = ibuf->x * ibuf->y; i > 0; i--, cbuf += 4) {
for (i = size_t(ibuf->x) * size_t(ibuf->y); i > 0; i--, cbuf += 4) {
*cbuf = cvalue;
}
}
+9 -6
View File
@@ -155,8 +155,9 @@ static void *imb_gpu_get_data(const ImBuf *ibuf,
IMB_colormanagement_space_is_scene_linear(ibuf->byte_buffer.colorspace))
{
/* sRGB or scene linear, store as byte texture that the GPU can decode directly. */
data_rect = MEM_mallocN(
(is_grayscale ? sizeof(float[4]) : sizeof(uchar[4])) * ibuf->x * ibuf->y, __func__);
data_rect = MEM_mallocN((is_grayscale ? sizeof(float[4]) : sizeof(uchar[4])) *
size_t(ibuf->x) * size_t(ibuf->y),
__func__);
*r_freedata = freedata = true;
if (data_rect == nullptr) {
@@ -224,7 +225,8 @@ static void *imb_gpu_get_data(const ImBuf *ibuf,
void *src_rect = data_rect;
if (freedata == false) {
data_rect = MEM_mallocN((is_float_rect ? sizeof(float) : sizeof(uchar)) * ibuf->x * ibuf->y,
data_rect = MEM_mallocN((is_float_rect ? sizeof(float) : sizeof(uchar)) * size_t(ibuf->x) *
size_t(ibuf->y),
__func__);
*r_freedata = freedata = true;
}
@@ -233,14 +235,15 @@ static void *imb_gpu_get_data(const ImBuf *ibuf,
return nullptr;
}
int buffer_size = do_rescale ? rescale_size[0] * rescale_size[1] : ibuf->x * ibuf->y;
size_t buffer_size = do_rescale ? size_t(rescale_size[0]) * size_t(rescale_size[1]) :
size_t(ibuf->x) * size_t(ibuf->y);
if (is_float_rect) {
for (uint64_t i = 0; i < buffer_size; i++) {
for (size_t i = 0; i < buffer_size; i++) {
((float *)data_rect)[i] = ((float *)src_rect)[i * 4];
}
}
else {
for (uint64_t i = 0; i < buffer_size; i++) {
for (size_t i = 0; i < buffer_size; i++) {
((uchar *)data_rect)[i] = ((uchar *)src_rect)[i * 4];
}
}
+5 -7
View File
@@ -618,7 +618,7 @@ static int rna_Image_pixels_get_length(const PointerRNA *ptr, int length[RNA_MAX
ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock);
if (ibuf) {
length[0] = ibuf->x * ibuf->y * ibuf->channels;
length[0] = size_t(ibuf->x) * size_t(ibuf->y) * size_t(ibuf->channels);
}
else {
length[0] = 0;
@@ -634,18 +634,17 @@ static void rna_Image_pixels_get(PointerRNA *ptr, float *values)
Image *ima = (Image *)ptr->owner_id;
ImBuf *ibuf;
void *lock;
int i, size;
ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock);
if (ibuf) {
size = ibuf->x * ibuf->y * ibuf->channels;
const size_t size = size_t(ibuf->x) * size_t(ibuf->y) * size_t(ibuf->channels);
if (ibuf->float_buffer.data) {
memcpy(values, ibuf->float_buffer.data, sizeof(float) * size);
}
else {
for (i = 0; i < size; i++) {
for (size_t i = 0; i < size; i++) {
values[i] = ibuf->byte_buffer.data[i] * (1.0f / 255.0f);
}
}
@@ -659,18 +658,17 @@ static void rna_Image_pixels_set(PointerRNA *ptr, const float *values)
Image *ima = (Image *)ptr->owner_id;
ImBuf *ibuf;
void *lock;
int i, size;
ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock);
if (ibuf) {
size = ibuf->x * ibuf->y * ibuf->channels;
const size_t size = size_t(ibuf->x) * size_t(ibuf->y) * size_t(ibuf->channels);
if (ibuf->float_buffer.data) {
memcpy(ibuf->float_buffer.data, values, sizeof(float) * size);
}
else {
for (i = 0; i < size; i++) {
for (size_t i = 0; i < size; i++) {
ibuf->byte_buffer.data[i] = unit_float_to_uchar_clamp(values[i]);
}
}
@@ -817,7 +817,7 @@ static void *init_heights_data(MultiresBakeRender *bkr, ImBuf *ibuf)
BakeImBufuserData *userdata = static_cast<BakeImBufuserData *>(ibuf->userdata);
if (userdata->displacement_buffer == nullptr) {
userdata->displacement_buffer = MEM_cnew_array<float>(ibuf->x * ibuf->y,
userdata->displacement_buffer = MEM_cnew_array<float>(size_t(ibuf->x) * size_t(ibuf->y),
"MultiresBake heights");
}
@@ -1420,14 +1420,14 @@ static void bake_ibuf_normalize_displacement(ImBuf *ibuf,
float displacement_min,
float displacement_max)
{
int i;
const float *current_displacement = displacement;
const char *current_mask = mask;
float max_distance;
max_distance = max_ff(fabsf(displacement_min), fabsf(displacement_max));
for (i = 0; i < ibuf->x * ibuf->y; i++) {
const size_t ibuf_pixel_count = size_t(ibuf->x) * size_t(ibuf->y);
for (size_t i = 0; i < ibuf_pixel_count; i++) {
if (*current_mask == FILTER_MASK_USED) {
float normalized_displacement;