From f67a647a12d6b361342e5fe4df5029fce4009d5c Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 29 Sep 2024 09:33:28 -0700 Subject: [PATCH 1/2] font/sprite: bounds checking for pixel writes on Pixman --- src/font/sprite/canvas.zig | 16 ++++++++++++---- src/font/sprite/underline.zig | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/font/sprite/canvas.zig b/src/font/sprite/canvas.zig index 10699615b..67e213b21 100644 --- a/src/font/sprite/canvas.zig +++ b/src/font/sprite/canvas.zig @@ -409,6 +409,11 @@ const PixmanImpl = struct { /// Draw and fill a single pixel pub fn pixel(self: *Canvas, x: u32, y: u32, color: Color) void { + if (comptime std.debug.runtime_safety) { + assert(x < self.image.getWidth()); + assert(y < self.image.getHeight()); + } + const boxes = &[_]pixman.Box32{ .{ .x1 = @intCast(x), @@ -433,10 +438,13 @@ const PixmanImpl = struct { }, }; - assert(boxes[0].x1 >= 0); - assert(boxes[0].y1 >= 0); - assert(boxes[0].x2 <= @as(i32, @intCast(self.image.getWidth()))); - assert(boxes[0].y2 <= @as(i32, @intCast(self.image.getHeight()))); + if (comptime std.debug.runtime_safety) { + assert(boxes[0].x1 >= 0); + assert(boxes[0].y1 >= 0); + assert(boxes[0].x2 <= @as(i32, @intCast(self.image.getWidth()))); + assert(boxes[0].y2 <= @as(i32, @intCast(self.image.getHeight()))); + } + self.image.fillBoxes(.src, color.pixmanColor(), boxes) catch {}; } diff --git a/src/font/sprite/underline.zig b/src/font/sprite/underline.zig index 08e74c781..0f00dffe3 100644 --- a/src/font/sprite/underline.zig +++ b/src/font/sprite/underline.zig @@ -27,7 +27,7 @@ pub fn renderGlyph( line_pos: u32, line_thickness: u32, ) !font.Glyph { - // Draw the appropriate sprite + // Draw the appropriate sprite var canvas: font.sprite.Canvas, const offset_y: i32 = switch (sprite) { .underline => try drawSingle(alloc, width, line_thickness), .underline_double => try drawDouble(alloc, width, line_thickness), From bbacee66d0aecdb049598bbc1d950af5755cc175 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 29 Sep 2024 09:39:17 -0700 Subject: [PATCH 2/2] font/sprite: fix out of bounds right on curly underline Fixes #2321 --- src/font/sprite/underline.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/font/sprite/underline.zig b/src/font/sprite/underline.zig index 0f00dffe3..03ce2872b 100644 --- a/src/font/sprite/underline.zig +++ b/src/font/sprite/underline.zig @@ -181,13 +181,13 @@ fn drawCurly(alloc: Allocator, width: u32, thickness: u32) !CanvasAndOffset { const alpha: u8 = @intFromFloat(255 * @abs(y - @floor(y))); // upper and lower bounds - canvas.pixel(x, @min(y_upper, height), @enumFromInt(255 - alpha)); - canvas.pixel(x, @min(y_lower, height), @enumFromInt(alpha)); + canvas.pixel(x, @min(y_upper, height - 1), @enumFromInt(255 - alpha)); + canvas.pixel(x, @min(y_lower, height - 1), @enumFromInt(alpha)); // fill between upper and lower bound var y_fill: u32 = y_upper + 1; while (y_fill < y_lower) : (y_fill += 1) { - canvas.pixel(x, @min(y_fill, height), .on); + canvas.pixel(x, @min(y_fill, height - 1), .on); } }