Bug 894245 part 2 - Reject unknown enum color in CSS parser. r=dholbert draft
authorXidorn Quan <me@upsuper.org>
Fri, 30 Dec 2016 14:52:10 +1100
changeset 454957 dbe0b7f1eb45a59ef4df67ba5f1d75da1892cb17
parent 454956 6b6c7fb1a578d2a129e399c534a8b651f32075bd
child 540859 a585a390323132a0ade1bbc4867cc137f0af7d64
push id40096
push userxquan@mozilla.com
push dateFri, 30 Dec 2016 23:12:12 +0000
reviewersdholbert
bugs894245
milestone53.0a1
Bug 894245 part 2 - Reject unknown enum color in CSS parser. r=dholbert MozReview-Commit-ID: 6jfNESnFde5
layout/style/crashtests/894245-1.html
layout/style/crashtests/crashtests.list
layout/style/nsCSSParser.cpp
layout/style/nsRuleNode.cpp
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/894245-1.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<div style="background-color: -moz-mac-defaultbuttontext"></div>
+<div style="background-color: -moz-mac-focusring"></div>
+<div style="background-color: -moz-win-communicationstext"></div>
+<div style="background-color: -moz-gtk-info-bar-text"></div>
--- a/layout/style/crashtests/crashtests.list
+++ b/layout/style/crashtests/crashtests.list
@@ -98,16 +98,17 @@ load 827591-1.html
 load 829817.html
 load 840898.html
 load 842134.html
 load 861489-1.html
 load 862113.html
 asserts-if(stylo,5) load 867487.html # bug 1324634
 load 873222.html
 asserts-if(stylo,2) load 880862.html # bug 1324701
+load 894245-1.html
 load 915440.html
 load 927734-1.html
 load 930270-1.html
 load 930270-2.html
 load 945048-1.html
 load 972199-1.html
 load 989965-1.html
 load 992333-1.html
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* parsing of CSS stylesheets, based on a token stream from the CSS scanner */
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/DebugOnly.h"
+#include "mozilla/Maybe.h"
 #include "mozilla/Move.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/TypedEnumBits.h"
 
 #include <algorithm> // for std::stable_sort
 #include <limits> // for std::numeric_limits
 
 #include "nsCSSParser.h"
@@ -46,16 +47,17 @@
 #include "nsIPrincipal.h"
 #include "nsICSSUnprefixingService.h"
 #include "mozilla/Sprintf.h"
 #include "nsContentUtils.h"
 #include "nsAutoPtr.h"
 #include "CSSCalc.h"
 #include "nsMediaFeatures.h"
 #include "nsLayoutUtils.h"
+#include "mozilla/LookAndFeel.h"
 #include "mozilla/Preferences.h"
 #include "nsRuleData.h"
 #include "mozilla/CSSVariableValues.h"
 #include "mozilla/dom/AnimationEffectReadOnlyBinding.h"
 #include "mozilla/dom/URL.h"
 #include "gfxFontFamilyList.h"
 
 using namespace mozilla;
@@ -6683,16 +6685,41 @@ CSSParserImpl::ParseDeclarationBlock(uin
       // Since the skipped declaration didn't end the block we parse
       // the next declaration.
     }
   }
   declaration->CompressFrom(&mData);
   return declaration.forget();
 }
 
+static Maybe<int32_t>
+GetEnumColorValue(nsCSSKeyword aKeyword, bool aIsChrome)
+{
+  int32_t value;
+  if (!nsCSSProps::FindKeyword(aKeyword, nsCSSProps::kColorKTable, value)) {
+    // Unknown color keyword.
+    return Nothing();
+  }
+  if (value < 0) {
+    // Known special color keyword handled by style system,
+    // e.g. NS_COLOR_CURRENTCOLOR. See nsStyleConsts.h.
+    return Some(value);
+  }
+  nscolor color;
+  auto colorID = static_cast<LookAndFeel::ColorID>(value);
+  if (NS_FAILED(LookAndFeel::GetColor(colorID, !aIsChrome, &color))) {
+    // Known LookAndFeel::ColorID, but this platform's LookAndFeel impl
+    // doesn't map it to a color. (This might be a platform-specific
+    // ColorID, which only makes sense on another platform.)
+    return Nothing();
+  }
+  // Known color provided by LookAndFeel.
+  return Some(value);
+}
+
 CSSParseResult
 CSSParserImpl::ParseColor(nsCSSValue& aValue)
 {
   if (!GetToken(true)) {
     REPORT_UNEXPECTED_EOF(PEColorEOF);
     return CSSParseResult::NotFound;
   }
 
@@ -6720,30 +6747,28 @@ CSSParserImpl::ParseColor(nsCSSValue& aV
             unit = eCSSUnit_HexColorAlpha;
             break;
         }
         aValue.SetIntegerColorValue(rgba, unit);
         return CSSParseResult::Ok;
       }
       break;
 
-    case eCSSToken_Ident:
+    case eCSSToken_Ident: {
       if (NS_ColorNameToRGB(tk->mIdent, &rgba)) {
         aValue.SetStringValue(tk->mIdent, eCSSUnit_Ident);
         return CSSParseResult::Ok;
       }
-      else {
-        nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(tk->mIdent);
-        int32_t value;
-        if (nsCSSProps::FindKeyword(keyword, nsCSSProps::kColorKTable, value)) {
-          aValue.SetIntValue(value, eCSSUnit_EnumColor);
-          return CSSParseResult::Ok;
-        }
-      }
-      break;
+      nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(tk->mIdent);
+      if (Maybe<int32_t> value = GetEnumColorValue(keyword, mIsChrome)) {
+        aValue.SetIntValue(value.value(), eCSSUnit_EnumColor);
+        return CSSParseResult::Ok;
+      }
+      break;
+    }
     case eCSSToken_Function: {
       bool isRGB;
       bool isHSL;
       if ((isRGB = mToken.mIdent.LowerCaseEqualsLiteral("rgb")) ||
           mToken.mIdent.LowerCaseEqualsLiteral("rgba")) {
         // rgb() = rgb( <percentage>{3} [ / <alpha-value> ]? ) |
         //         rgb( <number>{3} [ / <alpha-value> ]? ) |
         //         rgb( <percentage>#{3} , <alpha-value>? ) |
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -1039,20 +1039,21 @@ static bool SetColor(const nsCSSValue& a
     }
   }
   else if (eCSSUnit_EnumColor == unit) {
     int32_t intValue = aValue.GetIntValue();
     if (0 <= intValue) {
       LookAndFeel::ColorID colorID = (LookAndFeel::ColorID) intValue;
       bool useStandinsForNativeColors = aPresContext &&
                                         !aPresContext->IsChrome();
-      if (NS_SUCCEEDED(LookAndFeel::GetColor(colorID,
-                                    useStandinsForNativeColors, &aResult))) {
-        result = true;
-      }
+      DebugOnly<nsresult> rv =
+        LookAndFeel::GetColor(colorID, useStandinsForNativeColors, &aResult);
+      MOZ_ASSERT(NS_SUCCEEDED(rv),
+                 "Unknown enum colors should have been rejected by parser");
+      result = true;
     }
     else {
       aResult = NS_RGB(0, 0, 0);
       result = false;
       switch (intValue) {
         case NS_COLOR_MOZ_HYPERLINKTEXT:
           if (aPresContext) {
             aResult = aPresContext->DefaultLinkColor();