:: commit 413a5eb012ef70cd48232ba4397fb5a6e2f44f94

Mintsuki <mintsuki@protonmail.com> — 2026-02-07 09:04

parents: 65b7c1d9cd

lib/image: Fix unsigned wrap in centered displacement for oversized images

diff --git a/common/lib/gterm.c b/common/lib/gterm.c
index 3b8fe47c..3c2dd045 100644
--- a/common/lib/gterm.c
+++ b/common/lib/gterm.c
@@ -374,23 +374,23 @@ __attribute__((always_inline)) static inline void genloop(struct fb_info *fb, si
 
     case IMAGE_CENTERED:
         for (size_t y = ystart; y < yend; y++) {
-            size_t image_y = y - background->y_displacement;
-            const size_t off = img_pitch * image_y;
+            int64_t image_y = (int64_t)y - background->y_displacement;
             size_t canvas_off = fb->framebuffer_width * y;
-            if (image_y >= background->y_size) { /* external part */
+            if (image_y < 0 || (uint64_t)image_y >= background->y_size) { /* external part */
                 for (size_t x = xstart; x < xend; x++) {
                     uint32_t i = blend(fb, x, y, background->back_colour);
                     bg_canvas[canvas_off + x] = i;
                 }
             }
             else { /* internal part */
+                const size_t off = img_pitch * (size_t)image_y;
                 for (size_t x = xstart; x < xend; x++) {
                     uint32_t pixel;
-                    if (x < background->x_displacement || x - background->x_displacement >= background->x_size) {
+                    int64_t image_x = (int64_t)x - background->x_displacement;
+                    if (image_x < 0 || (uint64_t)image_x >= background->x_size) {
                         pixel = background->back_colour;
                     } else {
-                        size_t image_x = x - background->x_displacement;
-                        pixel = *(uint32_t*)(img + image_x * colsize + off);
+                        pixel = *(uint32_t*)(img + (size_t)image_x * colsize + off);
                     }
                     uint32_t i = blend(fb, x, y, pixel);
                     bg_canvas[canvas_off + x] = i;
diff --git a/common/lib/image.c b/common/lib/image.c
index 4235b4a3..ab9c33a1 100644
--- a/common/lib/image.c
+++ b/common/lib/image.c
@@ -9,8 +9,8 @@
 void image_make_centered(struct image *image, int frame_x_size, int frame_y_size, uint32_t back_colour) {
     image->type = IMAGE_CENTERED;
 
-    image->x_displacement = frame_x_size / 2 - image->x_size / 2;
-    image->y_displacement = frame_y_size / 2 - image->y_size / 2;
+    image->x_displacement = (int64_t)frame_x_size / 2 - (int64_t)image->x_size / 2;
+    image->y_displacement = (int64_t)frame_y_size / 2 - (int64_t)image->y_size / 2;
     image->back_colour = back_colour;
 }
 
diff --git a/common/lib/image.h b/common/lib/image.h
index 507fa1d3..e5cc2961 100644
--- a/common/lib/image.h
+++ b/common/lib/image.h
@@ -13,8 +13,8 @@ struct image {
     int pitch;
     size_t img_width; // x_size = scaled size, img_width = bitmap size
     size_t img_height;
-    size_t x_displacement;
-    size_t y_displacement;
+    int64_t x_displacement;
+    int64_t y_displacement;
     uint32_t back_colour;
 };
 
tab: 248 wrap: offon