Bug 894245 part 2 - Reject unknown enum color in CSS parser. r=dholbert
MozReview-Commit-ID: 6jfNESnFde5
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();