From 68281ce3e88146ee71c18f882c486d947f7726ae Mon Sep 17 00:00:00 2001 From: its-pablo Date: Sun, 19 Oct 2025 01:06:46 -0700 Subject: [PATCH] Mitigate integer overflow in ComputeShrinkHard (#1138) The multiplication in ComputeShrinkHard has the potential to overflow when very large elements are present inside of a vbox. To mitigate the issue, the multiplication happens in int64_t values. Co-authored-by: ArthurSonzogni --- CHANGELOG.md | 3 +++ src/ftxui/dom/box_helper.cpp | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7bd7a99..2bab7f60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,9 @@ Next - Fix vertical `ftxui::Slider`. The "up" key was previously decreasing the value. Thanks @its-pablo in #1093 for reporting the issue. +### Dom +- Fix integer overflow in `ComputeShrinkHard`. Thanks @its-pablo in #1137 for + reporting and fixing the issue. 6.1.9 (2025-05-07) ------------ diff --git a/src/ftxui/dom/box_helper.cpp b/src/ftxui/dom/box_helper.cpp index 8284cf30..95fe027c 100644 --- a/src/ftxui/dom/box_helper.cpp +++ b/src/ftxui/dom/box_helper.cpp @@ -4,7 +4,8 @@ #include "ftxui/dom/box_helper.hpp" #include // for max -#include // for vector +#include +#include // for vector namespace ftxui::box_helper { @@ -40,7 +41,7 @@ void ComputeShrinkEasy(std::vector* elements, } // Called when the size allowed is lower than the requested size, and the -// shrinkable element can not absorbe the (negative) extra_space. This assign +// shrinkable element can not absorb the (negative) extra_space. This assigns // zero to shrinkable elements and distribute the remaining (negative) // extra_space toward the other non shrinkable elements. void ComputeShrinkHard(std::vector* elements, @@ -52,7 +53,18 @@ void ComputeShrinkHard(std::vector* elements, continue; } - const int added_space = extra_space * element.min_size / std::max(1, size); + // Perform operation into int64_t to avoid overflow. + // The size of an int is at most 32 bits, so the multiplication can't + // overflow int64_t. Since `size` is the sum of elements.min_size, it is + // greater than every element.min_size. The added_space represents the + // fraction of extra_space assigned to this element, so it is always less + // than extra_space in absolute. Since extra_space fits into int, + // added_space fits into int as well. + int added_space = + static_cast(static_cast(extra_space) * + static_cast(element.min_size) / + std::max(static_cast(size), 1L)); + extra_space -= added_space; size -= element.min_size;