Skip to content

Commit e87e851

Browse files
add division by zero defence check for rounded values
1 parent 23e13d5 commit e87e851

1 file changed

Lines changed: 58 additions & 36 deletions

File tree

packages/react-native/React/Fabric/Utils/RCTBackgroundImageUtils.mm

Lines changed: 58 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,19 @@ + (CALayer *)createBackgroundImageLayerWithSize:(const CGRect&)positioningArea
6969
// Use rounded values to avoid floating point precision issues
7070
auto roundedAvailableWidth = round(availableWidthForCenterImages);
7171
auto roundedItemWidth = round(itemSize.width);
72-
auto centerImagesCount = floor(roundedAvailableWidth / roundedItemWidth);
73-
auto centerImagesWidth = centerImagesCount * itemSize.width;
74-
auto totalFreeSpace = availableWidthForCenterImages - centerImagesWidth;
75-
auto totalInstances = centerImagesCount + 2;
76-
auto spacing = totalFreeSpace / (totalInstances - 1);
77-
replicatorX.instanceTransform = CATransform3DMakeTranslation(itemSize.width + spacing, 0, 0);
78-
replicatorX.instanceCount = totalInstances;
79-
finalX = paintingArea.origin.x;
80-
finalW = paintingArea.size.width;
72+
if (roundedItemWidth > 0) {
73+
auto centerImagesCount = floor(roundedAvailableWidth / roundedItemWidth);
74+
auto centerImagesWidth = centerImagesCount * itemSize.width;
75+
auto totalFreeSpace = availableWidthForCenterImages - centerImagesWidth;
76+
auto totalInstances = centerImagesCount + 2;
77+
auto spacing = totalFreeSpace / (totalInstances - 1);
78+
replicatorX.instanceTransform = CATransform3DMakeTranslation(itemSize.width + spacing, 0, 0);
79+
replicatorX.instanceCount = totalInstances;
80+
finalX = paintingArea.origin.x;
81+
finalW = paintingArea.size.width;
82+
} else {
83+
replicatorX.instanceCount = 1;
84+
}
8185
}
8286
// Only one image can fit in the space
8387
else {
@@ -92,12 +96,16 @@ + (CALayer *)createBackgroundImageLayerWithSize:(const CGRect&)positioningArea
9296
auto roundedGradientFrameX = round(gradientFrameX);
9397
auto roundedItemWidth = round(itemSize.width);
9498
auto roundedPaintingWidth = round(paintingArea.size.width);
95-
auto tilesBeforeX = ceil(roundedGradientFrameX / roundedItemWidth);
96-
auto tilesAfterX = ceil((roundedPaintingWidth - roundedGradientFrameX) / roundedItemWidth);
97-
auto totalInstances = tilesBeforeX + tilesAfterX;
98-
replicatorX.instanceCount = totalInstances;
99-
finalX = gradientFrameX - (tilesBeforeX * itemSize.width);
100-
finalW = totalInstances * itemSize.width;
99+
if (roundedItemWidth > 0) {
100+
auto tilesBeforeX = ceil(roundedGradientFrameX / roundedItemWidth);
101+
auto tilesAfterX = ceil((roundedPaintingWidth - roundedGradientFrameX) / roundedItemWidth);
102+
auto totalInstances = tilesBeforeX + tilesAfterX;
103+
replicatorX.instanceCount = totalInstances;
104+
finalX = gradientFrameX - (tilesBeforeX * itemSize.width);
105+
finalW = totalInstances * itemSize.width;
106+
} else {
107+
replicatorX.instanceCount = 1;
108+
}
101109
}
102110
}
103111

@@ -121,15 +129,19 @@ + (CALayer *)createBackgroundImageLayerWithSize:(const CGRect&)positioningArea
121129
// Use pixel rounded values to avoid floating point precision issues
122130
auto roundedAvailableHeight = round(availableHeightForCenterImages);
123131
auto roundedItemHeight = round(itemSize.height);
124-
auto centerImagesCount = floor(roundedAvailableHeight / roundedItemHeight);
125-
auto centerImagesHeight = centerImagesCount * itemSize.height;
126-
auto totalFreeSpace = availableHeightForCenterImages - centerImagesHeight;
127-
auto totalInstances = centerImagesCount + 2;
128-
auto spacing = totalFreeSpace / (totalInstances - 1);
129-
replicatorY.instanceTransform = CATransform3DMakeTranslation(0, itemSize.height + spacing, 0);
130-
replicatorY.instanceCount = totalInstances;
131-
finalY = paintingArea.origin.y;
132-
finalH = paintingArea.size.height;
132+
if (roundedItemHeight > 0) {
133+
auto centerImagesCount = floor(roundedAvailableHeight / roundedItemHeight);
134+
auto centerImagesHeight = centerImagesCount * itemSize.height;
135+
auto totalFreeSpace = availableHeightForCenterImages - centerImagesHeight;
136+
auto totalInstances = centerImagesCount + 2;
137+
auto spacing = totalFreeSpace / (totalInstances - 1);
138+
replicatorY.instanceTransform = CATransform3DMakeTranslation(0, itemSize.height + spacing, 0);
139+
replicatorY.instanceCount = totalInstances;
140+
finalY = paintingArea.origin.y;
141+
finalH = paintingArea.size.height;
142+
} else {
143+
replicatorY.instanceCount = 1;
144+
}
133145
} else {
134146
replicatorY.instanceCount = 1;
135147
}
@@ -142,12 +154,16 @@ + (CALayer *)createBackgroundImageLayerWithSize:(const CGRect&)positioningArea
142154
auto roundedGradientFrameY = round(gradientFrameY);
143155
auto roundedItemHeight = round(itemSize.height);
144156
auto roundedPaintingHeight = round(paintingArea.size.height);
145-
auto tilesBeforeY = ceil(roundedGradientFrameY / roundedItemHeight);
146-
auto tilesAfterY = ceil((roundedPaintingHeight - roundedGradientFrameY) / roundedItemHeight);
147-
auto instanceCount = tilesBeforeY + tilesAfterY;
148-
replicatorY.instanceCount = instanceCount;
149-
finalY = gradientFrameY - (tilesBeforeY * itemSize.height);
150-
finalH = instanceCount * itemSize.height;
157+
if (roundedItemHeight > 0) {
158+
auto tilesBeforeY = ceil(roundedGradientFrameY / roundedItemHeight);
159+
auto tilesAfterY = ceil((roundedPaintingHeight - roundedGradientFrameY) / roundedItemHeight);
160+
auto instanceCount = tilesBeforeY + tilesAfterY;
161+
replicatorY.instanceCount = instanceCount;
162+
finalY = gradientFrameY - (tilesBeforeY * itemSize.height);
163+
finalH = instanceCount * itemSize.height;
164+
} else {
165+
replicatorY.instanceCount = 1;
166+
}
151167
}
152168
}
153169

@@ -197,9 +213,13 @@ + (CGSize)calculateBackgroundImageSize:(const CGRect&)positioningArea
197213
if (!floatEquality(remainder, 0.0)) {
198214
auto roundedPositioningWidth = round(positioningAreaSize.width);
199215
auto roundedItemFinalWidth = round(itemFinalSize.width);
200-
auto divisor = round(roundedPositioningWidth / roundedItemFinalWidth);
201-
if (divisor > 0) {
202-
itemFinalSize.width = positioningAreaSize.width / divisor;
216+
if (roundedItemFinalWidth > 0) {
217+
auto divisor = round(roundedPositioningWidth / roundedItemFinalWidth);
218+
if (divisor > 0) {
219+
itemFinalSize.width = positioningAreaSize.width / divisor;
220+
}
221+
} else {
222+
itemFinalSize.width = 0;
203223
}
204224
}
205225
}
@@ -211,9 +231,11 @@ + (CGSize)calculateBackgroundImageSize:(const CGRect&)positioningArea
211231
if (!floatEquality(remainder, 0.0)) {
212232
auto roundedPositioningHeight = round(positioningAreaSize.height);
213233
auto roundedItemFinalHeight = round(itemFinalSize.height);
214-
auto divisor = round(roundedPositioningHeight / roundedItemFinalHeight);
215-
if (divisor > 0) {
216-
itemFinalSize.height = positioningAreaSize.height / divisor;
234+
if (roundedItemFinalHeight > 0) {
235+
auto divisor = round(roundedPositioningHeight / roundedItemFinalHeight);
236+
if (divisor > 0) {
237+
itemFinalSize.height = positioningAreaSize.height / divisor;
238+
}
217239
}
218240
}
219241
}

0 commit comments

Comments
 (0)