Bug 1290994 - Do not multiply 0 by infinity in nsCSSScanner::ScanNumber. r?heycam draft
authorHiroyuki Ikezoe <hiikezoe@mozilla-japan.org>
Wed, 03 Aug 2016 19:09:58 +0900
changeset 396099 fc003ff14962858b2bef24b5c26fca34a5099e9e
parent 395624 6608e5864780589b25d5421c3d3673ab30c4c318
child 527125 57756aa9d0263a73560b4b2f0a0655e9a6b39e05
push id24919
push userbmo:hiikezoe@mozilla-japan.org
push dateWed, 03 Aug 2016 10:10:29 +0000
reviewersheycam
bugs1290994, 1290995
milestone51.0a1
Bug 1290994 - Do not multiply 0 by infinity in nsCSSScanner::ScanNumber. r?heycam Without this patch test cases 1290995-{1,2,3}.html causes an assertion. 1290995-4.html is hit by the assertion in this patch if we don't avoid the multiplication. MozReview-Commit-ID: AtPVyPtd0r8
layout/style/crashtests/1290994-1.html
layout/style/crashtests/1290994-2.html
layout/style/crashtests/1290994-3.html
layout/style/crashtests/1290994-4.html
layout/style/crashtests/crashtests.list
layout/style/nsCSSScanner.cpp
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/1290994-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<script>
+window.onload=function(){
+  var a = document.createElement("div");
+  document.documentElement.appendChild(a);
+  a.animate([{borderLeftColor:"black"},
+             {borderLeftColor:"hsl(0,0e309%,0%)"}]);
+};
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/1290994-2.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<script>
+window.onload=function(){
+  var a = document.createElement("div");
+  document.documentElement.appendChild(a);
+  a.animate([{color:"rgb(0,0,0)"},
+             {color:"rgb(0e309%,0%,0%)"}]);
+};
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/1290994-3.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<script>
+window.onload=function(){
+  var a = document.createElement("div");
+  document.documentElement.appendChild(a);
+  a.animate([{background: "-webkit-gradient(radial, 1 2, 8, 3 4, 9, from(lime))"},
+             {background: "-webkit-gradient(radial, 0e309 2, 8, 3 4, 9, from(lime))"}]);
+};
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/1290994-4.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<style>
+@keyframes anim {
+  0e309% {}
+}
+</style>
+</html>
--- a/layout/style/crashtests/crashtests.list
+++ b/layout/style/crashtests/crashtests.list
@@ -148,8 +148,12 @@ load font-face-truncated-src.html
 load large_border_image_width.html
 load long-url-list-stack-overflow.html
 pref(layout.css.background-clip-text.enabled,true) load 1264949.html
 pref(layout.css.background-clip-text.enabled,true) load 1270795.html
 pref(layout.css.background-clip-text.enabled,true) load 1275026.html
 load 1278463-1.html
 pref(dom.animations-api.core.enabled,true) load 1277908-1.html
 load 1277908-2.html
+pref(dom.animations-api.core.enabled,true) load 1290994-1.html
+pref(dom.animations-api.core.enabled,true) load 1290994-2.html
+pref(dom.animations-api.core.enabled,true) load 1290994-3.html
+load 1290994-4.html
--- a/layout/style/nsCSSScanner.cpp
+++ b/layout/style/nsCSSScanner.cpp
@@ -925,19 +925,22 @@ nsCSSScanner::ScanNumber(nsCSSToken& aTo
   // Set mIntegerValid for all cases (except %, below) because we need
   // it for the "2n" in :nth-child(2n).
   aToken.mIntegerValid = false;
 
   // Time to reassemble our number.
   // Do all the math in double precision so it's truncated only once.
   double value = sign * (intPart + fracPart);
   if (gotE) {
-    // Explicitly cast expSign*exponent to double to avoid issues with
-    // overloaded pow() on Windows.
-    value *= pow(10.0, double(expSign * exponent));
+    // Avoid multiplication of 0 by Infinity.
+    if (value != 0.0) {
+      // Explicitly cast expSign*exponent to double to avoid issues with
+      // overloaded pow() on Windows.
+      value *= pow(10.0, double(expSign * exponent));
+    }
   } else if (!gotDot) {
     // Clamp values outside of integer range.
     if (sign > 0) {
       aToken.mInteger = int32_t(std::min(intPart, double(INT32_MAX)));
     } else {
       aToken.mInteger = int32_t(std::max(-intPart, double(INT32_MIN)));
     }
     aToken.mIntegerValid = true;
@@ -953,16 +956,17 @@ nsCSSScanner::ScanNumber(nsCSSToken& aTo
       }
     } else if (c == '%') {
       Advance();
       type = eCSSToken_Percentage;
       value = value / 100.0f;
       aToken.mIntegerValid = false;
     }
   }
+  MOZ_ASSERT(!IsNaN(value), "The value should not be NaN");
   aToken.mNumber = value;
   aToken.mType = type;
   return true;
 }
 
 /**
  * Scan a string constant ('foo' or "foo").  Will always produce
  * either a String or a Bad_String token; the latter occurs when the