Bug 913990 - When encountering bogus URI during style computation for filter, fall back to initial value. r=dholbert
authorMax Vujovic <mvujovic@adobe.com>
Thu, 17 Oct 2013 14:37:57 -0400
changeset 164963 fa7709266585498718027f85d0a299df47af58ec
parent 164962 79a1f60d83dfe343308ab19d491a22d9f4d68078
child 164964 ae664f27e66337dd3d878289e32d32e14a1c92eb
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs913990
milestone27.0a1
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
Bug 913990 - When encountering bogus URI during style computation for filter, fall back to initial value. r=dholbert
layout/style/nsRuleNode.cpp
layout/style/nsRuleNode.h
layout/style/test/property_database.js
layout/style/test/test_value_computation.html
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -7987,27 +7987,31 @@ nsRuleNode::ComputeSVGData(void* aStartS
               svg->mTextRendering, canStoreInRuleTree,
               SETDSC_ENUMERATED | SETDSC_UNSET_INHERIT,
               parentSVG->mTextRendering,
               NS_STYLE_TEXT_RENDERING_AUTO, 0, 0, 0, 0);
 
   COMPUTE_END_INHERITED(SVG, svg)
 }
 
-void
+// Returns true if the nsStyleFilter was successfully set using the nsCSSValue.
+bool
 nsRuleNode::SetStyleFilterToCSSValue(nsStyleFilter* aStyleFilter,
                                      const nsCSSValue& aValue,
                                      nsStyleContext* aStyleContext,
                                      nsPresContext* aPresContext,
                                      bool& aCanStoreInRuleTree)
 {
   nsCSSUnit unit = aValue.GetUnit();
   if (unit == eCSSUnit_URL) {
-    aStyleFilter->SetURL(aValue.GetURLValue());
-    return;
+    nsIURI* url = aValue.GetURLValue();
+    if (!url)
+      return false;
+    aStyleFilter->SetURL(url);
+    return true;
   }
 
   NS_ABORT_IF_FALSE(unit == eCSSUnit_Function, "expected a filter function");
 
   nsCSSValue::Array* filterFunction = aValue.GetArrayValue();
   nsCSSKeyword functionName =
     (nsCSSKeyword)filterFunction->Item(0).GetIntValue();
 
@@ -8019,17 +8023,17 @@ nsRuleNode::SetStyleFilterToCSSValue(nsS
   NS_ABORT_IF_FALSE(foundKeyword, "unknown filter type");
   if (type == NS_STYLE_FILTER_DROP_SHADOW) {
     nsRefPtr<nsCSSShadowArray> shadowArray = GetShadowData(
       filterFunction->Item(1).GetListValue(),
       aStyleContext,
       false,
       aCanStoreInRuleTree);
     aStyleFilter->SetDropShadow(shadowArray);
-    return;
+    return true;
   }
 
   int32_t mask = SETCOORD_PERCENT | SETCOORD_FACTOR;
   if (type == NS_STYLE_FILTER_BLUR) {
     mask = SETCOORD_LENGTH | SETCOORD_STORE_CALC;
   } else if (type == NS_STYLE_FILTER_HUE_ROTATE) {
     mask = SETCOORD_ANGLE;
   }
@@ -8041,16 +8045,17 @@ nsRuleNode::SetStyleFilterToCSSValue(nsS
   nsCSSValue& arg = filterFunction->Item(1);
   nsStyleCoord filterParameter;
   DebugOnly<bool> didSetCoord = SetCoord(arg, filterParameter,
                                          nsStyleCoord(), mask,
                                          aStyleContext, aPresContext,
                                          aCanStoreInRuleTree);
   aStyleFilter->SetFilterParameter(filterParameter, type);
   NS_ABORT_IF_FALSE(didSetCoord, "unexpected unit");
+  return true;
 }
 
 const void*
 nsRuleNode::ComputeSVGResetData(void* aStartStruct,
                                 const nsRuleData* aRuleData,
                                 nsStyleContext* aContext,
                                 nsRuleNode* aHighestNode,
                                 const RuleDetail aRuleDetail,
@@ -8145,18 +8150,21 @@ nsRuleNode::ComputeSVGResetData(void* aS
       svgReset->mFilters = parentSVGReset->mFilters;
       break;
     case eCSSUnit_List:
     case eCSSUnit_ListDep: {
       svgReset->mFilters.Clear();
       const nsCSSValueList* cur = filterValue->GetListValue();
       while(cur) {
         nsStyleFilter styleFilter;
-        SetStyleFilterToCSSValue(&styleFilter, cur->mValue, aContext,
-                                 mPresContext, canStoreInRuleTree);
+        if (!SetStyleFilterToCSSValue(&styleFilter, cur->mValue, aContext,
+                                      mPresContext, canStoreInRuleTree)) {
+          svgReset->mFilters.Clear();
+          break;
+        }
         NS_ABORT_IF_FALSE(styleFilter.GetType() != NS_STYLE_FILTER_NONE,
                           "filter should be set");
         svgReset->mFilters.AppendElement(styleFilter);
         cur = cur->mNext;
       }
       break;
     }
     default:
--- a/layout/style/nsRuleNode.h
+++ b/layout/style/nsRuleNode.h
@@ -623,17 +623,17 @@ protected:
   inline RuleDetail CheckSpecifiedProperties(const nsStyleStructID aSID,
                                              const nsRuleData* aRuleData);
 
   already_AddRefed<nsCSSShadowArray>
               GetShadowData(const nsCSSValueList* aList,
                             nsStyleContext* aContext,
                             bool aIsBoxShadow,
                             bool& aCanStoreInRuleTree);
-  void SetStyleFilterToCSSValue(nsStyleFilter* aStyleFilter,
+  bool SetStyleFilterToCSSValue(nsStyleFilter* aStyleFilter,
                                 const nsCSSValue& aValue,
                                 nsStyleContext* aStyleContext,
                                 nsPresContext* aPresContext,
                                 bool& aCanStoreInRuleTree);
 
 private:
   nsRuleNode(nsPresContext* aPresContext, nsRuleNode* aParent,
              nsIStyleRule* aRule, uint8_t aLevel, bool aIsImportant);
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -4437,16 +4437,22 @@ if (SpecialPowers.getBoolPref("layout.cs
 			// Filter functions
 			"opacity(50%) saturate(1.0)",
 			"invert(50%) sepia(0.1) brightness(90%)",
 
 			// Mixed SVG reference filters and filter functions
 			"grayscale(1) url(#my-filter-1)",
 			"url(#my-filter-1) brightness(50%) contrast(0.9)",
 
+			// The CSS parser will accept these weird URLs. However, we'll fail
+			// to resolve them when computing style, so we'll fall back to the
+			// initial value ("none").
+			"url('feed:javascript:5')",
+			"blur(3px) url('feed:javascript:5') grayscale(50%)",
+
 			"blur(0)",
 			"blur(0px)",
 			"blur(0.5px)",
 			"blur(3px)",
 			"blur(100px)",
 			"blur(0.1em)",
 			"blur(calc(-1px))", // Parses and becomes blur(0px).
 			"blur(calc(0px))",
--- a/layout/style/test/test_value_computation.html
+++ b/layout/style/test/test_value_computation.html
@@ -36,16 +36,21 @@
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for computation of values in property database **/
 
 var gBadComputed = {
+  // The CSS parser will accept these weird URLs. However, we'll fail to
+  // resolve them when computing style, so we'll fall back to the initial
+  // value ("none").
+  "filter": [ "url('feed:javascript:5')", "blur(3px) url('feed:javascript:5') grayscale(50%)" ],
+
   // These values are treated as auto.
   "page-break-after": [ "avoid" ],
   "page-break-before": [ "avoid" ],
 
   // This is the only SVG-length property (i.e., length allowing
   // unitless lengths) whose initial value is zero.
   "stroke-dashoffset": [ "0", "-moz-objectValue" ],
 };