From b86e4fbde7f789d981bc7502189d7cdcf9e7dbc4 Mon Sep 17 00:00:00 2001 From: Hanno Schwalm Date: Wed, 22 Jan 2025 06:43:22 +0100 Subject: [PATCH] enlarge canvas fixes We can crash darktable being in darkroom using the enlarge_canvas module while being zoomed in either in process() or in distort_mask() Both are related to incorrect results for border_in_x/y leading to out-of-bounds data access. So we restrict results to be in allowed range. Use dt_aligned_pixel_t instead of float[4] as used elsewhere. --- src/iop/enlargecanvas.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/iop/enlargecanvas.c b/src/iop/enlargecanvas.c index 6949a54c9bf4..89d19ebf0249 100644 --- a/src/iop/enlargecanvas.c +++ b/src/iop/enlargecanvas.c @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2024 darktable developers. + Copyright (C) 2024-25 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -306,14 +306,14 @@ void distort_mask(dt_iop_module_t *self, dt_iop_border_positions_t binfo; - float bcolor[4] = { 0 }; - float fcolor[4] = { 0 }; + dt_aligned_pixel_t bcolor = { 0 }; + dt_aligned_pixel_t fcolor = { 0 }; dt_iop_setup_binfo(piece, roi_in, roi_out, pos_v, pos_h, bcolor, fcolor, 0.f, 0.f, &binfo); - const int border_in_x = binfo.border_in_x; - const int border_in_y = binfo.border_in_y; + const int border_in_x = CLAMP(binfo.border_in_x, 0, roi_out->width - roi_in->width); + const int border_in_y = CLAMP(binfo.border_in_y, 0, roi_out->height - roi_in->height); // fill the image with 0 so that the added border isn't part of the mask dt_iop_image_fill(out, 0.0f, roi_out->width, roi_out->height, 1); @@ -342,8 +342,8 @@ void process(dt_iop_module_t *self, _compute_pos(d, &pos_v, &pos_h); - float fcolor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - float bcolor[4]; + dt_aligned_pixel_t fcolor = { 1.0f, 1.0f, 1.0f, 1.0f }; + dt_aligned_pixel_t bcolor; bcolor[3] = 1.0f; @@ -385,6 +385,9 @@ void process(dt_iop_module_t *self, dt_iop_setup_binfo(piece, roi_in, roi_out, pos_v, pos_h, bcolor, fcolor, 0.f, 0.f, &binfo); + binfo.border_in_x = CLAMP(binfo.border_in_x, 0, roi_out->width - roi_in->width); + binfo.border_in_y = CLAMP(binfo.border_in_y, 0, roi_out->height - roi_in->height); + dt_iop_copy_image_with_border((float*)ovoid, (const float*)ivoid, &binfo); }