Skip to content

Commit 68281ce

Browse files
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 <[email protected]>
1 parent d4fda16 commit 68281ce

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ Next
3232
- Fix vertical `ftxui::Slider`. The "up" key was previously decreasing the
3333
value. Thanks @its-pablo in #1093 for reporting the issue.
3434

35+
### Dom
36+
- Fix integer overflow in `ComputeShrinkHard`. Thanks @its-pablo in #1137 for
37+
reporting and fixing the issue.
3538

3639
6.1.9 (2025-05-07)
3740
------------

src/ftxui/dom/box_helper.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
#include "ftxui/dom/box_helper.hpp"
55

66
#include <algorithm> // for max
7-
#include <vector> // for vector
7+
#include <cstdint>
8+
#include <vector> // for vector
89

910
namespace ftxui::box_helper {
1011

@@ -40,7 +41,7 @@ void ComputeShrinkEasy(std::vector<Element>* elements,
4041
}
4142

4243
// Called when the size allowed is lower than the requested size, and the
43-
// shrinkable element can not absorbe the (negative) extra_space. This assign
44+
// shrinkable element can not absorb the (negative) extra_space. This assigns
4445
// zero to shrinkable elements and distribute the remaining (negative)
4546
// extra_space toward the other non shrinkable elements.
4647
void ComputeShrinkHard(std::vector<Element>* elements,
@@ -52,7 +53,18 @@ void ComputeShrinkHard(std::vector<Element>* elements,
5253
continue;
5354
}
5455

55-
const int added_space = extra_space * element.min_size / std::max(1, size);
56+
// Perform operation into int64_t to avoid overflow.
57+
// The size of an int is at most 32 bits, so the multiplication can't
58+
// overflow int64_t. Since `size` is the sum of elements.min_size, it is
59+
// greater than every element.min_size. The added_space represents the
60+
// fraction of extra_space assigned to this element, so it is always less
61+
// than extra_space in absolute. Since extra_space fits into int,
62+
// added_space fits into int as well.
63+
int added_space =
64+
static_cast<int>(static_cast<int64_t>(extra_space) *
65+
static_cast<int64_t>(element.min_size) /
66+
std::max(static_cast<int64_t>(size), 1L));
67+
5668
extra_space -= added_space;
5769
size -= element.min_size;
5870

0 commit comments

Comments
 (0)