From 346327a0d4cc7ead202518dcf9cbc33433abed0d Mon Sep 17 00:00:00 2001 From: nerix Date: Tue, 21 Oct 2025 17:17:49 +0200 Subject: [PATCH] fix: overflow when computing scrollbar rect (#6547) Co-authored-by: Kasia --- CHANGELOG.md | 1 + src/widgets/Scrollbar.cpp | 19 ++++++++++--------- src/widgets/Scrollbar.hpp | 15 +++++++++------ 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b2b3e5a..23673fe1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Minor: Added link support to plugin message API. (#6386) - Minor: Added a description for the logging option under moderation tab. (#6514) - Bugfix: Expose the "Extra extension IDs" setting on non-Windows systems too. (#6509) +- Bugfix: Fixed scrollbar rect cmputation potentially resulting in overflows. (#6547) - Dev: Update release documentation. (#6498) - Dev: Make code sanitizers opt in with the `CHATTERINO_SANITIZER_SUPPORT` CMake option. After that's enabled, use the `SANITIZE_*` flag to enable individual sanitizers. (#6493) - Dev: Remove unused QTextCodec includes. (#6487) diff --git a/src/widgets/Scrollbar.cpp b/src/widgets/Scrollbar.cpp index f85f7084..1e3f77ba 100644 --- a/src/widgets/Scrollbar.cpp +++ b/src/widgets/Scrollbar.cpp @@ -465,16 +465,17 @@ void Scrollbar::updateScroll() { this->trackHeight_ = this->height() - MIN_THUMB_HEIGHT - 1; - auto div = std::max(0.0000001, this->maximum_ - this->minimum_); + auto nMessages = std::max(1.0, this->maximum_ - this->minimum_); - this->thumbRect_ = - QRect(0, - static_cast((this->getRelativeCurrentValue()) / div * - this->trackHeight_) + - 1, - this->width(), - static_cast(this->pageSize_ / div * this->trackHeight_) + - MIN_THUMB_HEIGHT); + this->thumbRect_ = QRect{ + 0, + static_cast((this->getRelativeCurrentValue()) / nMessages * + this->trackHeight_) + + 1, + this->width(), + static_cast(this->pageSize_ / nMessages * this->trackHeight_) + + MIN_THUMB_HEIGHT, + }; this->update(); } diff --git a/src/widgets/Scrollbar.hpp b/src/widgets/Scrollbar.hpp index ba02ac06..dac86ae6 100644 --- a/src/widgets/Scrollbar.hpp +++ b/src/widgets/Scrollbar.hpp @@ -35,18 +35,21 @@ class ChannelView; /// index is computed by `scrollbarPos - minimum` - thus a scrollbar position /// of a message is at `index + minimum. /// -/// @cond src-only -/// /// The following illustrates a scrollbar in a channel view with seven /// messages. The scrollbar is at the bottom. No animation is active, thus /// `currentValue = desiredValue`. /// +/// ```text /// ┌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┐←╌╌╌ minimum -/// Alice: This message is quite = 0 +/// Bob: Ugh, I can't see this = 0 +/// message, it's outside of my +/// ChannelView +/// ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +/// Alice: Your message is quite /// ┬ ╭─────────────────────────────────╮←╮ /// │ │ long, so it gets wrapped │ ┆ /// │ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ ╰╌╌╌ currentValue -/// │ │ Bob: are you sure? │ = 0.5 +/// │ │ Bob: are you sure? │ = 1.5 /// │ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ = desiredValue /// pageSize ╌╌╌┤ │ Alice: Works for me... try for │ = maximum /// = 6.5 │ │ yourself │ - pageSize @@ -63,8 +66,8 @@ class ChannelView; /// ┴╭→╰─────────────────────────────────╯ /// ┆ /// maximum -/// = 7 -/// @endcond +/// = 8 +/// ``` /// /// When messages are added at the bottom, both maximum and minimum are offset /// by 1 and after a layout, the desired value is updated, causing the content