Fix division-by-zero crash that dholbert saw, although I haven't been able to, and make the code a bit more robust. (Bug 582379) r=bzbarsky a2.0=blocking
authorL. David Baron <dbaron@dbaron.org>
Wed, 10 Nov 2010 07:49:53 -0800
changeset 57249 f1f708845d4de39958152fa95dd60945f5406821
parent 57248 3c75b7bea31ac5e0b8f89b71464ce343c8de5dc5
child 57250 e250978a21be0e1c7d87a95db2980404c0299eec
push id16847
push userdbaron@mozilla.com
push dateWed, 10 Nov 2010 15:50:38 +0000
treeherdermozilla-central@e250978a21be [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs582379
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Fix division-by-zero crash that dholbert saw, although I haven't been able to, and make the code a bit more robust. (Bug 582379) r=bzbarsky a2.0=blocking
layout/style/nsTransitionManager.cpp
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -199,22 +199,33 @@ ElementTransitions::EnsureStyleRuleFor(T
         continue;
       }
 
       nsStyleAnimation::Value *val = mStyleRule->AddEmptyValue(pt.mProperty);
       if (!val) {
         continue;
       }
 
-      double timePortion =
-        (aRefreshTime - pt.mStartTime).ToSeconds() / pt.mDuration.ToSeconds();
-      if (timePortion < 0.0)
-        timePortion = 0.0; // use start value during transition-delay
-      if (timePortion > 1.0)
-        timePortion = 1.0; // we might be behind on flushing
+      double duration = pt.mDuration.ToSeconds();
+      NS_ABORT_IF_FALSE(duration >= 0.0, "negative duration forbidden");
+      double timePortion;
+      if (duration == 0.0) {
+        if (aRefreshTime >= pt.mStartTime) {
+          timePortion = 0.0;
+        } else {
+          timePortion = 1.0;
+        }
+      } else {
+        timePortion = (aRefreshTime - pt.mStartTime).ToSeconds() /
+                      pt.mDuration.ToSeconds();
+        if (timePortion < 0.0)
+          timePortion = 0.0; // use start value during transition-delay
+        if (timePortion > 1.0)
+          timePortion = 1.0; // we might be behind on flushing
+      }
 
       double valuePortion =
         pt.mTimingFunction.GetSplineValue(timePortion);
 #ifdef DEBUG
       PRBool ok =
 #endif
         nsStyleAnimation::Interpolate(pt.mProperty,
                                       pt.mStartValue, pt.mEndValue,
@@ -631,16 +642,20 @@ nsTransitionManager::ConsiderStartingTra
   }
 
 
   nsRefreshDriver *rd = presContext->RefreshDriver();
 
   pt.mProperty = aProperty;
   float delay = aTransition.GetDelay();
   float duration = aTransition.GetDuration();
+  if (duration < 0.0) {
+    // The spec says a negative duration is treated as zero.
+    duration = 0.0;
+  }
   if (durationFraction != 1.0) {
     // Negative delays are essentially part of the transition
     // function, so reduce them along with the duration, but don't
     // reduce positive delays.  (See comment above about
     // durationFraction.)
     if (delay < 0.0f)
         delay *= durationFraction;
     duration *= durationFraction;