Commit 2dbb0409 authored by Peter Kasting's avatar Peter Kasting Committed by Commit Bot

Restructure conditionals to avoid multiply-by-infinity.

The code clearly expects infinity to be possible, but unconditionally
multiplies by it (and discards the result in the infinity case).  This
is UB; avoid the multiplication in this case.

Bug: 1116289
Change-Id: I5b1297e92be68e3477b3dcbb17146d4f7a3d4098
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2355404
Auto-Submit: Peter Kasting <pkasting@chromium.org>
Commit-Queue: Robert Flack <flackr@chromium.org>
Reviewed-by: default avatarKevin Ellis <kevers@chromium.org>
Reviewed-by: default avatarRobert Flack <flackr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798828}
parent 19c92386
......@@ -198,21 +198,22 @@ KeyframeModel::Phase KeyframeModel::CalculatePhase(
(local_time == before_active_boundary_time && playback_rate_ < 0)) {
return KeyframeModel::Phase::BEFORE;
}
// Scaling the duration is against spec but needed to comply with the cc
// implementation. By spec (in blink) the playback rate is an Animation level
// concept but in cc it's per KeyframeModel. We grab the active time
// calculated here and later scale it with the playback rate in order to get a
// proper progress. Therefore we need to un-scale it here. This can be fixed
// once we scale the local time by playback rate. See
// https://crbug.com/912407.
base::TimeDelta active_duration =
curve_->Duration() * iterations_ / std::abs(playback_rate_);
// TODO(crbug.com/909794): By spec end time = max(start delay + duration +
// end delay, 0). The logic should be updated once "end delay" is supported.
base::TimeDelta active_after_boundary_time =
std::isfinite(iterations_)
? std::max(opposite_time_offset + active_duration, base::TimeDelta())
: base::TimeDelta::Max();
base::TimeDelta active_after_boundary_time = base::TimeDelta::Max();
if (std::isfinite(iterations_)) {
// Scaling the duration is against spec but needed to comply with the cc
// implementation. By spec (in blink) the playback rate is an Animation
// level concept but in cc it's per KeyframeModel. We grab the active time
// calculated here and later scale it with the playback rate in order to get
// a proper progress. Therefore we need to un-scale it here. This can be
// fixed once we scale the local time by playback rate. See
// https://crbug.com/912407.
base::TimeDelta active_duration =
curve_->Duration() * iterations_ / std::abs(playback_rate_);
active_after_boundary_time =
std::max(opposite_time_offset + active_duration, base::TimeDelta());
}
if (local_time > active_after_boundary_time ||
(local_time == active_after_boundary_time && playback_rate_ > 0)) {
return KeyframeModel::Phase::AFTER;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment