Skip to content

Commit 9983795

Browse files
SaadArdatiBirjuVachhani
authored andcommitted
🔧 Fix stack overflow when clamping rect is smaller than the main rect.
1 parent 555b69c commit 9983795

File tree

3 files changed

+91
-15
lines changed

3 files changed

+91
-15
lines changed

packages/box_transform/lib/src/enums.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,30 @@ enum HandlePosition {
200200
throw ArgumentError('HandlePosition.none is not supported!');
201201
}
202202
}
203+
204+
/// Displayable representation of the [HandlePosition] value.
205+
String get prettify {
206+
switch (this) {
207+
case HandlePosition.topLeft:
208+
return 'Top Left';
209+
case HandlePosition.top:
210+
return 'Top';
211+
case HandlePosition.topRight:
212+
return 'Top Right';
213+
case HandlePosition.left:
214+
return 'Left';
215+
case HandlePosition.right:
216+
return 'Right';
217+
case HandlePosition.bottomLeft:
218+
return 'Bottom Left';
219+
case HandlePosition.bottom:
220+
return 'Bottom';
221+
case HandlePosition.bottomRight:
222+
return 'Bottom Right';
223+
case HandlePosition.none:
224+
return 'None';
225+
}
226+
}
203227
}
204228

205229
/// Represents the flip state of a rectangle, or, in other words, if the

packages/box_transform/lib/src/resizers/scale_resizing.dart

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,53 @@ final class ScaleResizer extends Resizer {
1313
required HandlePosition handle,
1414
required Constraints constraints,
1515
required Flip flip,
16+
}) {
17+
({Box rect, Box largest, bool hasValidFlip}) result = _resizeRect(
18+
initialRect: initialRect,
19+
explodedRect: explodedRect,
20+
clampingRect: clampingRect,
21+
handle: handle,
22+
constraints: constraints,
23+
flip: flip,
24+
);
25+
26+
if (!result.hasValidFlip) {
27+
// Since we can't flip the box, explodedRect (which is a raw rect with delta applied)
28+
// would be flipped so we can't use that because it would make the size
29+
// calculations wrong. Instead we use box from the result which is the
30+
// flipped box but with correct constraints applied. (min rect always).
31+
final newResult = _resizeRect(
32+
explodedRect: result.rect,
33+
initialRect: initialRect,
34+
clampingRect: clampingRect,
35+
handle: handle,
36+
flip: Flip.none,
37+
constraints: constraints,
38+
);
39+
40+
if (!newResult.hasValidFlip) {
41+
// This should never happen. If it does, it means that the box is
42+
// invalid even after flipping it back to the original state and we
43+
// can't flip it back again. This means that the box might be invalid
44+
// in the first place or something catastrophic happened!!! Contact
45+
// the package author if this happens.
46+
return (rect: initialRect,largest: clampingRect, hasValidFlip: false);
47+
throw StateError('Box found to be invalid more than once!');
48+
}
49+
50+
return newResult;
51+
}
52+
53+
return result;
54+
}
55+
56+
({Box rect, Box largest, bool hasValidFlip}) _resizeRect({
57+
required Box initialRect,
58+
required Box explodedRect,
59+
required Box clampingRect,
60+
required HandlePosition handle,
61+
required Constraints constraints,
62+
required Flip flip,
1663
}) {
1764
final flippedHandle = handle.flip(flip);
1865
final effectiveInitialRect = flipRect(initialRect, flip, handle);
@@ -56,21 +103,6 @@ final class ScaleResizer extends Resizer {
56103
break;
57104
}
58105

59-
if (!result.hasValidFlip) {
60-
// Since we can't flip the box, explodedRect (which is a raw rect with delta applied)
61-
// would be flipped so we can't use that because it would make the size
62-
// calculations wrong. Instead we use box from the result which is the
63-
// flipped box but with correct constraints applied. (min rect always).
64-
return resize(
65-
explodedRect: result.rect,
66-
initialRect: initialRect,
67-
clampingRect: clampingRect,
68-
handle: handle,
69-
flip: Flip.none,
70-
constraints: constraints,
71-
);
72-
}
73-
74106
return result;
75107
}
76108

packages/box_transform/lib/src/transformer.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,26 @@ class BoxTransformer {
118118
);
119119
}
120120

121+
// Check if clampingRect is smaller than initialRect.
122+
// If it is, then we return the initialRect and not resize it.
123+
if (clampingRect.width < initialRect.width ||
124+
clampingRect.height < initialRect.height) {
125+
return ResizeResult(
126+
rect: initialRect,
127+
oldRect: initialRect,
128+
flip: initialFlip,
129+
resizeMode: resizeMode,
130+
delta: delta,
131+
handle: handle,
132+
rawSize: initialRect.size,
133+
minWidthReached: false,
134+
minHeightReached: false,
135+
largestRect: clampingRect,
136+
maxHeightReached: false,
137+
maxWidthReached: false,
138+
);
139+
}
140+
121141
// Symmetric resizing requires the delta to be doubled since it grows or
122142
// shrinks in all directions from center.
123143
if (resizeMode.hasSymmetry) delta = Vector2(delta.x * 2, delta.y * 2);

0 commit comments

Comments
 (0)