Skip to content

Commit 3e962d3

Browse files
harsha-cppmeta-codesync[bot]
authored andcommitted
guard shrink-factor division against floating-point near-zero (#57175)
Summary: Pull Request resolved: #57175 fixes react/yoga#1665. **problem:** when all flex children are frozen to their min-width in the first pass, `totalFlexShrinkScaledFactors` is reduced to near-zero by floating-point cancellation rather than exactly 0. the guard in `distributeFreeSpaceSecondPass` uses exact equality (`== 0`), so it never fires, and the second pass divides `remainingFreeSpace` by a value on the order of 1e-7, producing a childSize on the order of 1e11 that overwhelms the min/max clamp. **fix:** replace the exact-zero check with a relative epsilon guard (`shrinkFactorMagnitude < 1e-6f`). when the magnitude is that small, all items were already frozen in the first pass; the safe fallback (`childFlexBasis + flexShrinkScaledFactor`) applies and the subsequent `boundAxisWithAutoMin` clamps correctly to minWidth. regression: `YGFlexShrinkBorderBug.flex_basis_0_border_minwidth_row` reproduces the original crash — 4 children, `borderWidth` difference of 1e-6 across them, all now compute to their correct minWidth. ## Changelog: [Internal] - X-link: react/yoga#1974 Reviewed By: javache Differential Revision: D108030908 Pulled By: cipolleschi fbshipit-source-id: 3e8d4ef6773bc31703a54005bf610b2432f22d2d
1 parent b933d18 commit 3e962d3

1 file changed

Lines changed: 8 additions & 1 deletion

File tree

packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1104,8 +1104,15 @@ static float distributeFreeSpaceSecondPass(
11041104
if (flexShrinkScaledFactor != 0) {
11051105
float childSize = YGUndefined;
11061106

1107+
// Use a relative epsilon guard instead of exact equality: after the
1108+
// first pass removes all constrained items,
1109+
// totalFlexShrinkScaledFactors may be near-zero rather than exactly 0
1110+
// due to floating-point cancellation. Dividing by a near-zero value
1111+
// produces a gigantic childSize that overwhelms the min/max clamp.
1112+
const float shrinkFactorMagnitude =
1113+
std::abs(flexLine.layout.totalFlexShrinkScaledFactors);
11071114
if (yoga::isDefined(flexLine.layout.totalFlexShrinkScaledFactors) &&
1108-
flexLine.layout.totalFlexShrinkScaledFactors == 0) {
1115+
shrinkFactorMagnitude < 1e-6f) {
11091116
childSize = childFlexBasis + flexShrinkScaledFactor;
11101117
} else {
11111118
childSize = childFlexBasis +

0 commit comments

Comments
 (0)