Skip to content

Commit b3a4dec

Browse files
authored
Assert against infinite values of control points in CatmullRomSpline (flutter#131820)
When providing infinite values for the control points of CatmullRomSpline, a StackOverflowError occurs. This asserts against that and provides a helpful error message. Fixes flutter#131246
1 parent 0ad45f2 commit b3a4dec

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

packages/flutter/lib/src/animation/curves.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,27 @@ class CatmullRomSpline extends Curve2D {
705705
Offset? startHandle,
706706
Offset? endHandle,
707707
}) {
708+
assert(
709+
startHandle == null || startHandle.isFinite,
710+
'The provided startHandle of CatmullRomSpline must be finite. The '
711+
'startHandle given was $startHandle.'
712+
);
713+
assert(
714+
endHandle == null || endHandle.isFinite,
715+
'The provided endHandle of CatmullRomSpline must be finite. The endHandle '
716+
'given was $endHandle.'
717+
);
718+
assert(() {
719+
for (int index = 0; index < controlPoints.length; index++) {
720+
if (!controlPoints[index].isFinite) {
721+
throw FlutterError(
722+
'The provided CatmullRomSpline control point at index $index is not '
723+
'finite. The control point given was ${controlPoints[index]}.'
724+
);
725+
}
726+
}
727+
return true;
728+
}());
708729
// If not specified, select the first and last control points (which are
709730
// handles: they are not intersected by the resulting curve) so that they
710731
// extend the first and last segments, respectively.

packages/flutter/test/animation/curves_test.dart

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,28 @@ void main() {
305305
expect(() {
306306
CatmullRomSpline(const <Offset>[Offset.zero, Offset.zero, Offset.zero, Offset.zero], tension: 2.0);
307307
}, throwsAssertionError);
308+
expect(() {
309+
CatmullRomSpline(
310+
const <Offset>[Offset(double.infinity, 0.0), Offset.zero, Offset.zero, Offset.zero],
311+
).generateSamples();
312+
}, throwsAssertionError);
313+
expect(() {
314+
CatmullRomSpline(
315+
const <Offset>[Offset(0.0, double.infinity), Offset.zero, Offset.zero, Offset.zero],
316+
).generateSamples();
317+
}, throwsAssertionError);
318+
expect(() {
319+
CatmullRomSpline(
320+
startHandle: const Offset(0.0, double.infinity),
321+
const <Offset>[Offset.zero, Offset.zero, Offset.zero, Offset.zero],
322+
).generateSamples();
323+
}, throwsAssertionError);
324+
expect(() {
325+
CatmullRomSpline(
326+
endHandle: const Offset(0.0, double.infinity),
327+
const <Offset>[Offset.zero, Offset.zero, Offset.zero, Offset.zero],
328+
).generateSamples();
329+
}, throwsAssertionError);
308330
});
309331

310332
test('CatmullRomSpline interpolates values properly when precomputed', () {
@@ -353,6 +375,24 @@ void main() {
353375
expect(() {
354376
CatmullRomSpline.precompute(const <Offset>[Offset.zero, Offset.zero, Offset.zero, Offset.zero], tension: 2.0);
355377
}, throwsAssertionError);
378+
expect(() {
379+
CatmullRomSpline.precompute(const <Offset>[Offset(double.infinity, 0.0), Offset.zero, Offset.zero, Offset.zero]);
380+
}, throwsAssertionError);
381+
expect(() {
382+
CatmullRomSpline.precompute(const <Offset>[Offset(0.0, double.infinity), Offset.zero, Offset.zero, Offset.zero]);
383+
}, throwsAssertionError);
384+
expect(() {
385+
CatmullRomSpline.precompute(
386+
startHandle: const Offset(0.0, double.infinity),
387+
const <Offset>[Offset.zero, Offset.zero, Offset.zero, Offset.zero],
388+
);
389+
}, throwsAssertionError);
390+
expect(() {
391+
CatmullRomSpline.precompute(
392+
endHandle: const Offset(0.0, double.infinity),
393+
const <Offset>[Offset.zero, Offset.zero, Offset.zero, Offset.zero],
394+
);
395+
}, throwsAssertionError);
356396
});
357397

358398
test('CatmullRomCurve interpolates given points correctly', () {

0 commit comments

Comments
 (0)