From 70ea8dca923a45bd222204ffa1d87d9be32bd479 Mon Sep 17 00:00:00 2001 From: Rafael Siejakowski Date: Sat, 30 Mar 2024 14:17:35 +0100 Subject: [PATCH 1/2] Fix a use-after-free in OKLab picker rendering Replace an externally managed pixel buffer with one internal to the Cairo surface. --- src/ui/widget/oklab-color-wheel.cpp | 14 ++++++++------ src/ui/widget/oklab-color-wheel.h | 1 - 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ui/widget/oklab-color-wheel.cpp b/src/ui/widget/oklab-color-wheel.cpp index bcdfc00e64..e1b1433af9 100644 --- a/src/ui/widget/oklab-color-wheel.cpp +++ b/src/ui/widget/oklab-color-wheel.cpp @@ -50,6 +50,7 @@ bool OKWheel::setRgb(double r, double g, double b, if (changed_lightness) { _updateChromaBounds(); _redrawDisc(); + queue_drawing_area_draw(); } bool const changed = changed_hue || changed_saturation || changed_lightness; @@ -218,13 +219,17 @@ void OKWheel::on_drawing_area_draw(Cairo::RefPtr const &cr, int, void OKWheel::_redrawDisc() { int const size = std::ceil(2.0 * _disc_radius); - _pixbuf.resize(4 * size * size); - double const radius = 0.5 * size; double const inverse_radius = 1.0 / radius; + if (!_disc || _disc->get_height() != size) { + _disc = Cairo::ImageSurface::create(Cairo::Surface::Format::RGB24, size, size); + } + // Fill buffer with (, R, G, B) values. - uint32_t *pos = (uint32_t *)(_pixbuf.data()); + uint32_t *pos = reinterpret_cast(_disc->get_data()); + g_assert(pos); + for (int y = 0; y < size; y++) { // Convert (x, y) to a coordinate system where the // disc is the unit disc and the y-axis points up. @@ -234,9 +239,6 @@ void OKWheel::_redrawDisc() *pos++ = _discColor(pt); } } - - int const stride = Cairo::ImageSurface::format_stride_for_width(Cairo::Surface::Format::RGB24, size); - _disc = Cairo::ImageSurface::create(_pixbuf.data(), Cairo::Surface::Format::RGB24, size, size, stride); } /** @brief Convert widget (event) coordinates to an abstract coordinate system diff --git a/src/ui/widget/oklab-color-wheel.h b/src/ui/widget/oklab-color-wheel.h index ba9c20ee0b..db91196d69 100644 --- a/src/ui/widget/oklab-color-wheel.h +++ b/src/ui/widget/oklab-color-wheel.h @@ -68,7 +68,6 @@ private: double _disc_radius = 1.0; Geom::Point _margin; Cairo::RefPtr _disc; - std::vector _pixbuf; std::array _bounds; }; -- GitLab From 28f0e97fdb7f52147a3854c93d99b5305bb95107 Mon Sep 17 00:00:00 2001 From: Rafael Siejakowski Date: Sat, 30 Mar 2024 14:19:15 +0100 Subject: [PATCH 2/2] Simplify a function call --- src/ui/widget/oklab-color-wheel.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ui/widget/oklab-color-wheel.cpp b/src/ui/widget/oklab-color-wheel.cpp index e1b1433af9..d4b1538391 100644 --- a/src/ui/widget/oklab-color-wheel.cpp +++ b/src/ui/widget/oklab-color-wheel.cpp @@ -235,8 +235,7 @@ void OKWheel::_redrawDisc() // disc is the unit disc and the y-axis points up. double const normalized_y = inverse_radius * (radius - y); for (int x = 0; x < size; x++) { - auto const pt = Geom::Point(inverse_radius * (x - radius), normalized_y); - *pos++ = _discColor(pt); + *pos++ = _discColor({inverse_radius * (x - radius), normalized_y}); } } } -- GitLab