From cb62b5e34be4f2bca686028b4f7d10381529d7de Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 10 Aug 2011 18:25:22 -0400 Subject: [PATCH] Bug 676413 - crossOrigin attribute invalid-value-default should be Anonymous - r=sicking As specified in http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#cors-settings-attribute "The empty string is also a valid keyword, and maps to the Anonymous state. The attribute's invalid value default is the Anonymous state. The missing value default, used when the attribute is omitted, is the No CORS state." --- content/base/src/nsAttrValue.cpp | 39 ++++++++++++------- content/base/src/nsAttrValue.h | 16 +++++--- .../html/content/src/nsHTMLImageElement.cpp | 17 +++++--- 3 files changed, 46 insertions(+), 26 deletions(-) diff --git a/content/base/src/nsAttrValue.cpp b/content/base/src/nsAttrValue.cpp index 6387e2dd6cbb..70ce9bd49be2 100644 --- a/content/base/src/nsAttrValue.cpp +++ b/content/base/src/nsAttrValue.cpp @@ -980,28 +980,35 @@ nsAttrValue::SetIntValueAndType(PRInt32 aValue, ValueType aType, } } -PRBool -nsAttrValue::GetEnumTableIndex(const EnumTable* aTable, PRInt16& aResult) +PRInt16 +nsAttrValue::GetEnumTableIndex(const EnumTable* aTable) { PRInt16 index = sEnumTableArray->IndexOf(aTable); if (index < 0) { index = sEnumTableArray->Length(); NS_ASSERTION(index <= NS_ATTRVALUE_ENUMTABLEINDEX_MAXVALUE, "too many enum tables"); - if (!sEnumTableArray->AppendElement(aTable)) { - return PR_FALSE; - } + sEnumTableArray->AppendElement(aTable); } - aResult = index; + return index; +} - return PR_TRUE; +PRInt32 +nsAttrValue::EnumTableEntryToValue(const EnumTable* aEnumTable, + const EnumTable* aTableEntry) +{ + PRInt16 index = GetEnumTableIndex(aEnumTable); + PRInt32 value = (aTableEntry->value << NS_ATTRVALUE_ENUMTABLEINDEX_BITS) + + index; + return value; } PRBool nsAttrValue::ParseEnumValue(const nsAString& aValue, const EnumTable* aTable, - PRBool aCaseSensitive) + PRBool aCaseSensitive, + const EnumTable* aDefaultValue) { ResetIfSet(); const EnumTable* tableEntry = aTable; @@ -1009,13 +1016,7 @@ nsAttrValue::ParseEnumValue(const nsAString& aValue, while (tableEntry->tag) { if (aCaseSensitive ? aValue.EqualsASCII(tableEntry->tag) : aValue.LowerCaseEqualsASCII(tableEntry->tag)) { - PRInt16 index; - if (!GetEnumTableIndex(aTable, index)) { - return PR_FALSE; - } - - PRInt32 value = (tableEntry->value << NS_ATTRVALUE_ENUMTABLEINDEX_BITS) + - index; + PRInt32 value = EnumTableEntryToValue(aTable, tableEntry); PRBool equals = aCaseSensitive || aValue.EqualsASCII(tableEntry->tag); if (!equals) { @@ -1035,6 +1036,14 @@ nsAttrValue::ParseEnumValue(const nsAString& aValue, tableEntry++; } + if (aDefaultValue) { + NS_PRECONDITION(aTable <= aDefaultValue && aDefaultValue < tableEntry, + "aDefaultValue not inside aTable?"); + SetIntValueAndType(EnumTableEntryToValue(aTable, aDefaultValue), + eEnum, &aValue); + return PR_TRUE; + } + return PR_FALSE; } diff --git a/content/base/src/nsAttrValue.h b/content/base/src/nsAttrValue.h index 8e45bda07f2d..683044425f7c 100644 --- a/content/base/src/nsAttrValue.h +++ b/content/base/src/nsAttrValue.h @@ -213,11 +213,15 @@ public: * @param aValue the string to find the value for * @param aTable the enumeration to map with * @param aCaseSensitive specify if the parsing has to be case sensitive + * @param aDefaultValue if non-null, this function will always return true. + * Failure to parse aValue as one of the values in aTable will just + * cause aDefaultValue->value to be stored as the enumeration value. * @return whether the enum value was found or not */ PRBool ParseEnumValue(const nsAString& aValue, const EnumTable* aTable, - PRBool aCaseSensitive); + PRBool aCaseSensitive, + const EnumTable* aDefaultValue = nsnull); /** * Parse a string into an integer. Can optionally parse percent (n%). @@ -347,13 +351,11 @@ private: /** * Get the index of an EnumTable in the sEnumTableArray. * If the EnumTable is not in the sEnumTableArray, it is added. - * If there is no more space in sEnumTableArray, it returns PR_FALSE. * * @param aTable the EnumTable to get the index of. - * @param aResult the index of the EnumTable. - * @return whether the index has been found or inserted. + * @return the index of the EnumTable. */ - PRBool GetEnumTableIndex(const EnumTable* aTable, PRInt16& aResult); + PRInt16 GetEnumTableIndex(const EnumTable* aTable); inline void SetPtrValueAndType(void* aValue, ValueBaseType aType); void SetIntValueAndType(PRInt32 aValue, ValueType aType, @@ -377,6 +379,10 @@ private: PRInt32* aErrorCode, PRBool aCanBePercent = PR_FALSE, PRBool* aIsPercent = nsnull) const; + // Given an enum table and a particular entry in that table, return + // the actual integer value we should store. + PRInt32 EnumTableEntryToValue(const EnumTable* aEnumTable, + const EnumTable* aTableEntry); static nsTArray* sEnumTableArray; diff --git a/content/html/content/src/nsHTMLImageElement.cpp b/content/html/content/src/nsHTMLImageElement.cpp index c5b48090b6d1..e9bc8cf37bbe 100644 --- a/content/html/content/src/nsHTMLImageElement.cpp +++ b/content/html/content/src/nsHTMLImageElement.cpp @@ -228,15 +228,15 @@ NS_IMPL_STRING_ATTR(nsHTMLImageElement, UseMap, usemap) NS_IMPL_INT_ATTR(nsHTMLImageElement, Vspace, vspace) static const nsAttrValue::EnumTable kCrossOriginTable[] = { - { "", nsImageLoadingContent::CORS_NONE }, + // Order matters here; see ParseAttribute { "anonymous", nsImageLoadingContent::CORS_ANONYMOUS }, { "use-credentials", nsImageLoadingContent::CORS_USE_CREDENTIALS }, { 0 } }; -// Default crossOrigin mode is CORS_NONE. -static const nsAttrValue::EnumTable* kCrossOriginDefault = &kCrossOriginTable[0]; -NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLImageElement, CrossOrigin, crossorigin, kCrossOriginDefault->tag) +// crossorigin is not "limited to only known values" per spec, so it's +// just a string attr purposes of the DOM crossOrigin property. +NS_IMPL_STRING_ATTR(nsHTMLImageElement, CrossOrigin, crossorigin) NS_IMETHODIMP nsHTMLImageElement::GetDraggable(PRBool* aDraggable) @@ -352,7 +352,10 @@ nsHTMLImageElement::ParseAttribute(PRInt32 aNamespaceID, return ParseAlignValue(aValue, aResult); } if (aAttribute == nsGkAtoms::crossorigin) { - return aResult.ParseEnumValue(aValue, kCrossOriginTable, PR_FALSE); + return aResult.ParseEnumValue(aValue, kCrossOriginTable, PR_FALSE, + // default value is anonymous if aValue is + // not a value we understand + &kCrossOriginTable[0]); } if (ParseImageAttribute(aAttribute, aValue, aResult)) { return PR_TRUE; @@ -656,7 +659,9 @@ nsHTMLImageElement::GetCORSMode() nsImageLoadingContent::CORSMode ret = nsImageLoadingContent::CORS_NONE; const nsAttrValue* value = GetParsedAttr(nsGkAtoms::crossorigin); - if (value && value->Type() == nsAttrValue::eEnum) { + if (value) { + NS_ASSERTION(value->Type() == nsAttrValue::eEnum, + "Why is this not an enum value?"); ret = (nsImageLoadingContent::CORSMode) value->GetEnumValue(); }