LibGfx: Clip out-of-bounds pixel accesses in Painter::draw_rect()

This commit is contained in:
Andreas Kling 2024-04-14 13:31:19 +02:00
parent d5c7959c45
commit 217cb01708
Notes: sideshowbarker 2024-07-17 02:55:44 +09:00
2 changed files with 20 additions and 8 deletions

View File

@ -45,3 +45,11 @@ TEST_CASE(draw_scaled_bitmap_with_transform)
}
}
}
TEST_CASE(draw_rect_rough_bounds)
{
auto bitmap = MUST(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, { 10, 10 }));
Gfx::Painter painter(*bitmap);
painter.draw_rect(Gfx::IntRect(0, 0, 1, 1), Color::Black, true);
painter.draw_rect(Gfx::IntRect(9, 9, 1, 1), Color::Black, true);
}

View File

@ -570,17 +570,21 @@ void Painter::draw_rect(IntRect const& a_rect, Color color, bool rough)
int scale = this->scale();
if (rect.top() >= clipped_rect.top() && rect.top() < clipped_rect.bottom()) {
int start_x = rough ? max(rect.x() + 1, clipped_rect.x()) : clipped_rect.x();
int width = rough ? min(rect.width() - 2, clipped_rect.width()) : clipped_rect.width();
for (int i = 0; i < scale; ++i)
fill_physical_scanline_with_draw_op(rect.top() * scale + i, start_x * scale, width * scale, color);
int width = rough ? max(0, min(rect.width() - 2, clipped_rect.width())) : clipped_rect.width();
if (width > 0) {
int start_x = rough ? max(rect.x() + 1, clipped_rect.x()) : clipped_rect.x();
for (int i = 0; i < scale; ++i)
fill_physical_scanline_with_draw_op(rect.top() * scale + i, start_x * scale, width * scale, color);
}
++min_y;
}
if (rect.bottom() > clipped_rect.top() && rect.bottom() <= clipped_rect.bottom()) {
int start_x = rough ? max(rect.x() + 1, clipped_rect.x()) : clipped_rect.x();
int width = rough ? min(rect.width() - 2, clipped_rect.width()) : clipped_rect.width();
for (int i = 0; i < scale; ++i)
fill_physical_scanline_with_draw_op(max_y * scale + i, start_x * scale, width * scale, color);
int width = rough ? max(0, min(rect.width() - 2, clipped_rect.width())) : clipped_rect.width();
if (width > 0) {
int start_x = rough ? max(rect.x() + 1, clipped_rect.x()) : clipped_rect.x();
for (int i = 0; i < scale; ++i)
fill_physical_scanline_with_draw_op(max_y * scale + i, start_x * scale, width * scale, color);
}
--max_y;
}