Bug 383488: don't accept trailing tokens in 'value' in style.setProperty(prop,value,"important"). r=dbaron

This commit is contained in:
Mats Palmgren 2010-04-01 23:07:40 -07:00
parent 99f6865d5e
commit 57a4d3a783
9 changed files with 120 additions and 28 deletions

View File

@ -1132,7 +1132,7 @@ MappedAttrParser::ParseMappedAttrValue(nsIAtom* aMappedAttrName,
nsCSSProps::LookupProperty(nsAtomString(aMappedAttrName));
PRBool changed; // outparam for ParseProperty. (ignored)
mParser.ParseProperty(propertyID, aMappedAttrValue, mDocURI, mBaseURI,
mNodePrincipal, mDecl, &changed);
mNodePrincipal, mDecl, &changed, PR_FALSE);
}
already_AddRefed<nsICSSStyleRule>

View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html><head>
<style>
span { font-family: sans-serif; font-size: 72px; }
</style>
</head><body>
<p>The X'es below should have the same size:</p>
<!-- The wonky placement of line breaks below is to eliminate all
significant whitespace within the paragraph. -->
<p
><span>X</span
><span>X</span
><span>X</span
><span>X</span
><span>X</span
><span>X</span
><span>X</span
><span>X</span
><span>X</span
><span>X</span
><span>X</span
><span>X</span
><span>X</span
><span>X</span
><span>X</span
><span>X</span></p>
</body>
</html>

View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html><head>
<style>
span { font-family: sans-serif }
#a14 { font-size:72px; }
</style>
<script>
window.onload = function()
{
function S(id) {
return document.getElementById(id).style;
}
S("a1").setProperty("font-size", "illegal", "important");
S("a2").setProperty("font-size", "24px;", "important");
S("a3").setProperty("font-size", "24px; font-size-adjust:2", "important");
S("a4").setProperty("font-size", ";", "important");
S("a5").setProperty("font", "24px sans-serif;", "important");
S("a6").setProperty("font", "24px;", "important");
S("a7").setProperty("font-size", " 72px ", "important"); // correct
S("a8").setProperty("font", ";", "important");
S("a9").setProperty("font", " 72px sans-serif ", "important"); // correct
S("a10").setProperty("font-size", "!", "important");
S("a11").setProperty("font-size", "!important", "important");
S("a12").setProperty("font-size", "}", "important");
S("a13").setProperty("font-size", "; font-size:24px", "important");
S("a14").setProperty("font-size", "", "important"); // correct
S("a15").setProperty("font-size", "24px !important;", "important");
S("a16").setProperty("font-size", "24px !important; height:1px", "important");
}
</script>
</head><body>
<p>The X'es below should have the same size:</p>
<!-- The wonky placement of line breaks below is to eliminate all
significant whitespace within the paragraph. -->
<p
><span id="a1" style="font-size:72px!important;">X</span
><span id="a2" style="font-size:72px!important;">X</span
><span id="a3" style="font-size:72px!important;">X</span
><span id="a4" style="font-size:72px!important;">X</span
><span id="a5" style="font-size:72px!important;">X</span
><span id="a6" style="font-size:72px!important;">X</span
><span id="a7" style="font-size:24px!important;">X</span
><span id="a8" style="font-size:72px!important;">X</span
><span id="a9" style="font:24px sans-serif!important;">X</span
><span id="a10" style="font-size:72px!important;">X</span
><span id="a11" style="font-size:72px!important;">X</span
><span id="a12" style="font-size:72px!important;">X</span
><span id="a13" style="font-size:72px!important;">X</span
><span id="a14" style="font-size:24px!important;">X</span
><span id="a15" style="font-size:72px!important;">X</span
><span id="a16" style="font-size:72px!important;">X</span
></p>
</body></html>

View File

@ -671,6 +671,7 @@ random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 379316-2.html 379316-2-ref.html # bug
== 382916-1.html 382916-1-ref.html
== 383035-1.html about:blank
== 383035-2.html about:blank
== 383488-1.html 383488-1-ref.html
== 383551-1.html 383551-1-ref.html
== 383883-1.html 383883-1-ref.html
== 383883-2.html 383883-2-ref.html

View File

@ -215,7 +215,8 @@ public:
nsIURI* aBaseURL,
nsIPrincipal* aSheetPrincipal,
nsCSSDeclaration* aDeclaration,
PRBool* aChanged);
PRBool* aChanged,
PRBool aIsImportant);
nsresult ParseMediaList(const nsSubstring& aBuffer,
nsIURI* aURL, // for error reporting
@ -1089,7 +1090,8 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID,
nsIURI* aBaseURI,
nsIPrincipal* aSheetPrincipal,
nsCSSDeclaration* aDeclaration,
PRBool* aChanged)
PRBool* aChanged,
PRBool aIsImportant)
{
NS_PRECONDITION(aSheetPrincipal, "Must have principal here!");
AssertInitialState();
@ -1117,17 +1119,20 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID,
mData.AssertInitialState();
mTempData.AssertInitialState();
// We know that our new value is not !important, and that we don't need to
// force a ValueAppended call for it. So if there's already a value for this
// property in the declaration, and it's not !important, and our prop is not
// a shorthand, we parse successfully, then we can just directly copy our
// parsed value into the declaration without going through the whole
// expand/compress thing.
// We know we don't need to force a ValueAppended call for the new
// value. So if we are not processing an !important decl or a
// shorthand, there's already a value for this property in the
// declaration, it's not !important, and we parse successfully, then
// we can just directly copy our parsed value into the declaration
// without going through the whole expand/compress thing.
if (!aDeclaration->EnsureMutable()) {
NS_WARNING("out of memory");
return NS_ERROR_OUT_OF_MEMORY;
}
void* valueSlot = aDeclaration->SlotForValue(aPropID);
void* valueSlot = nsnull;
if (!aIsImportant) {
valueSlot = aDeclaration->SlotForValue(aPropID);
}
if (!valueSlot) {
// Do it the slow way
aDeclaration->ExpandTo(&mData);
@ -1139,7 +1144,7 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID,
CopyValue(mTempData.PropertyAt(aPropID), valueSlot, aPropID, aChanged);
mTempData.ClearPropertyBit(aPropID);
} else {
TransferTempData(aDeclaration, aPropID, PR_FALSE, PR_FALSE, aChanged);
TransferTempData(aDeclaration, aPropID, aIsImportant, PR_FALSE, aChanged);
}
} else {
if (parsedOK) {
@ -9229,11 +9234,12 @@ nsCSSParser::ParseProperty(const nsCSSProperty aPropID,
nsIURI* aBaseURI,
nsIPrincipal* aSheetPrincipal,
nsCSSDeclaration* aDeclaration,
PRBool* aChanged)
PRBool* aChanged,
PRBool aIsImportant)
{
return static_cast<CSSParserImpl*>(mImpl)->
ParseProperty(aPropID, aPropValue, aSheetURI, aBaseURI,
aSheetPrincipal, aDeclaration, aChanged);
aSheetPrincipal, aDeclaration, aChanged, aIsImportant);
}
nsresult

View File

@ -151,7 +151,8 @@ public:
nsIURI* aBaseURL,
nsIPrincipal* aSheetPrincipal,
nsCSSDeclaration* aDeclaration,
PRBool* aChanged);
PRBool* aChanged,
PRBool aIsImportant);
/**
* Parse aBuffer into a media list |aMediaList|, which must be

View File

@ -103,7 +103,7 @@ nsDOMCSSDeclaration::SetPropertyValue(const nsCSSProperty aPropID,
return RemoveProperty(aPropID);
}
return ParsePropertyValue(aPropID, aValue);
return ParsePropertyValue(aPropID, aValue, PR_FALSE);
}
@ -206,24 +206,24 @@ nsDOMCSSDeclaration::SetProperty(const nsAString& aPropertyName,
if (propID == eCSSProperty_UNKNOWN) {
return NS_OK;
}
if (aValue.IsEmpty()) {
// If the new value of the property is an empty string we remove the
// property.
// XXX this ignores the priority string, should it?
return RemoveProperty(propID);
}
if (aPriority.IsEmpty()) {
return ParsePropertyValue(propID, aValue);
return ParsePropertyValue(propID, aValue, PR_FALSE);
}
// ParsePropertyValue does not handle priorities correctly -- it's
// optimized for speed. And the priority is not part of the
// property value anyway.... So we have to use the full-blown
// ParseDeclaration()
return ParseDeclaration(aPropertyName + NS_LITERAL_STRING(":") +
aValue + NS_LITERAL_STRING("!") + aPriority,
PR_TRUE, PR_FALSE);
if (aPriority.EqualsLiteral("important")) {
return ParsePropertyValue(propID, aValue, PR_TRUE);
}
// XXX silent failure?
return NS_OK;
}
NS_IMETHODIMP
@ -245,7 +245,8 @@ nsDOMCSSDeclaration::RemoveProperty(const nsAString& aPropertyName,
nsresult
nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSProperty aPropID,
const nsAString& aPropValue)
const nsAString& aPropValue,
PRBool aIsImportant)
{
nsCSSDeclaration* decl;
nsresult result = GetCSSDeclaration(&decl, PR_TRUE);
@ -275,7 +276,8 @@ nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSProperty aPropID,
nsCSSParser cssParser(cssLoader);
PRBool changed;
result = cssParser.ParseProperty(aPropID, aPropValue, sheetURI, baseURI,
sheetPrincipal, decl, &changed);
sheetPrincipal, decl, &changed,
aIsImportant);
if (NS_SUCCEEDED(result) && changed) {
result = DeclarationChanged();
}

View File

@ -122,7 +122,8 @@ protected:
mozilla::css::Loader** aCSSLoader) = 0;
nsresult ParsePropertyValue(const nsCSSProperty aPropID,
const nsAString& aPropValue);
const nsAString& aPropValue,
PRBool aIsImportant);
nsresult ParseDeclaration(const nsAString& aDecl,
PRBool aParseOnlyOneDecl, PRBool aClearOldDecl);

View File

@ -954,7 +954,7 @@ BuildStyleRule(nsCSSProperty aProperty,
NS_FAILED(parser.ParseProperty(aProperty, aSpecifiedValue,
doc->GetDocumentURI(), baseURI,
aTargetElement->NodePrincipal(),
declaration, &changed)) ||
declaration, &changed, PR_FALSE)) ||
// check whether property parsed without CSS parsing errors
!declaration->HasNonImportantValueFor(propertyToCheck) ||
NS_FAILED(NS_NewCSSStyleRule(getter_AddRefs(styleRule), nsnull,