1010namespace ftxui ::box_helper {
1111
1212namespace {
13+
14+ int SafeRatio (int value, int numerator, int denominator) {
15+ return static_cast <int64_t >(value) * static_cast <int64_t >(numerator) /
16+ std::max (static_cast <int64_t >(denominator), static_cast <int64_t >(1 ));
17+ }
18+
1319// Called when the size allowed is greater than the requested size. This
1420// distributes the extra spaces toward the flexible elements, in relative
1521// proportions.
@@ -18,7 +24,7 @@ void ComputeGrow(std::vector<Element>* elements,
1824 int flex_grow_sum) {
1925 for (Element& element : *elements) {
2026 const int added_space =
21- extra_space * element.flex_grow / std::max (flex_grow_sum, 1 );
27+ SafeRatio ( extra_space, element.flex_grow , flex_grow_sum );
2228 extra_space -= added_space;
2329 flex_grow_sum -= element.flex_grow ;
2430 element.size = element.min_size + added_space;
@@ -32,8 +38,8 @@ void ComputeShrinkEasy(std::vector<Element>* elements,
3238 int extra_space,
3339 int flex_shrink_sum) {
3440 for (Element& element : *elements) {
35- const int added_space = extra_space * element. min_size *
36- element.flex_shrink / std::max (flex_shrink_sum, 1 );
41+ const int added_space = SafeRatio (
42+ extra_space, element. min_size * element.flex_shrink , flex_shrink_sum );
3743 extra_space -= added_space;
3844 flex_shrink_sum -= element.flex_shrink * element.min_size ;
3945 element.size = element.min_size + added_space;
@@ -53,17 +59,7 @@ void ComputeShrinkHard(std::vector<Element>* elements,
5359 continue ;
5460 }
5561
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 ));
62+ const int added_space = SafeRatio (extra_space, element.min_size , size);
6763
6864 extra_space -= added_space;
6965 size -= element.min_size ;
0 commit comments