Better fix for bug 47852 (NAMESPACE_ERR not being thrown when setting Node.prefix). r/sr=sicking.

git-svn-id: svn://10.0.0.236/trunk@194509 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
peterv%propagandism.org 2006-04-17 17:13:11 +00:00
parent eda09625d4
commit 78cadf3883
5 changed files with 60 additions and 66 deletions

View File

@ -786,6 +786,18 @@ public:
return sInitialized;
}
/**
* Checks if the localname/prefix/namespace triple is valid wrt prefix
* and namespace according to the Namespaces in XML and DOM Code
* specfications.
*
* @param aLocalname localname of the node
* @param aPrefix prefix of the node
* @param aNamespaceID namespace of the node
*/
static PRBool IsValidNodeName(nsIAtom *aLocalName, nsIAtom *aPrefix,
PRInt32 aNamespaceID);
private:
static nsresult doReparentContentWrapper(nsIContent *aChild,
JSContext *cx,

View File

@ -1857,26 +1857,10 @@ nsContentUtils::GetNodeInfoFromQName(const nsAString& aNamespaceURI,
}
NS_ENSURE_SUCCESS(rv, rv);
nsIAtom* prefix = (*aNodeInfo)->GetPrefixAtom();
nsIAtom* nil = nsnull;
// NAMESPACE_ERR: Raised if the qualifiedName is a malformed qualified name,
// if the qualifiedName has a prefix and the namespaceURI is null, if the
// qualifiedName has a prefix that is "xml" and the namespaceURI is different
// from "http://www.w3.org/XML/1998/namespace", if the qualifiedName or its
// prefix is "xmlns" and the namespaceURI is different from
// "http://www.w3.org/2000/xmlns/", or if the namespaceURI is
// "http://www.w3.org/2000/xmlns/" and neither the qualifiedName nor its
// prefix is "xmlns".
PRBool xmlPrefix = prefix == nsLayoutAtoms::xml;
PRBool xmlns = (*aNodeInfo)->Equals(nsLayoutAtoms::xmlns, nil) ||
prefix == nsLayoutAtoms::xmlns;
return (prefix && DOMStringIsNull(aNamespaceURI)) ||
(xmlPrefix && nsID != kNameSpaceID_XML) ||
(xmlns && nsID != kNameSpaceID_XMLNS) ||
(nsID == kNameSpaceID_XMLNS && !xmlns) ?
NS_ERROR_DOM_NAMESPACE_ERR : NS_OK;
return nsContentUtils::IsValidNodeName((*aNodeInfo)->NameAtom(),
(*aNodeInfo)->GetPrefixAtom(),
(*aNodeInfo)->NamespaceID()) ?
NS_OK : NS_ERROR_DOM_NAMESPACE_ERR;
}
// static
@ -3028,3 +3012,34 @@ nsContentUtils::RemoveRangeList(nsIContent *aContent)
PL_DHashTableOperate(&sRangeListsHash, aContent, PL_DHASH_REMOVE);
}
}
/* static */
PRBool
nsContentUtils::IsValidNodeName(nsIAtom *aLocalName, nsIAtom *aPrefix,
PRInt32 aNamespaceID)
{
if (!aPrefix) {
// If the prefix is null, then either the QName must be xmlns or the
// namespace must not be XMLNS.
return (aLocalName == nsGkAtoms::xmlns) ==
(aNamespaceID == kNameSpaceID_XMLNS);
}
// If the prefix is non-null then the namespace must not be null.
if (aNamespaceID == kNameSpaceID_None) {
return PR_FALSE;
}
// If the namespace is the XMLNS namespace then the prefix must be xmlns,
// but the localname must not be xmlns.
if (aNamespaceID == kNameSpaceID_XMLNS) {
return aPrefix == nsGkAtoms::xmlns && aLocalName != nsGkAtoms::xmlns;
}
// If the namespace is not the XMLNS namespace then the prefix must not be
// xmlns.
// If the namespace is the XML namespace then the prefix can be anything.
// If the namespace is not the XML namespace then the prefix must not be xml.
return aPrefix != nsGkAtoms::xmlns &&
(aNamespaceID == kNameSpaceID_XML || aPrefix != nsGkAtoms::xml);
}

View File

@ -437,40 +437,15 @@ nsDOMAttribute::SetPrefix(const nsAString& aPrefix)
nsCOMPtr<nsINodeInfo> newNodeInfo;
nsCOMPtr<nsIAtom> prefix;
PRBool qnameIsXMLNS = mNodeInfo->NameAtom() == nsGkAtoms::xmlns &&
!mNodeInfo->GetPrefixAtom();
if (!aPrefix.IsEmpty()) {
prefix = do_GetAtom(aPrefix);
if (!prefix) {
return NS_ERROR_OUT_OF_MEMORY;
}
// If the namespace of the attribute is null then setting a non-null prefix
// isn't allowed.
// If the QName of the attribute is |xmlns| then setting a non-null prefix
// isn't allowed.
// If the namespace of the attribute is the XMLNS namespace then setting
// a prefix other than xmlns isn't allowed, if the namespace of the
// attribute is not the XMLNS namespace then setting the prefix to xmlns
// isn't allowed.
if (mNodeInfo->NamespaceID() == kNameSpaceID_None || qnameIsXMLNS ||
((mNodeInfo->NamespaceID() == kNameSpaceID_XMLNS) !=
(prefix == nsGkAtoms::xmlns))) {
return NS_ERROR_DOM_NAMESPACE_ERR;
}
}
else if (!qnameIsXMLNS && mNodeInfo->NamespaceID() == kNameSpaceID_XMLNS) {
// Setting the prefix to null on an attribute that is in the XMLNS
// namespace but whose QName isn't |xmlns| is not allowed.
return NS_ERROR_DOM_NAMESPACE_ERR;
}
// If the namespace of the attribute is the XML namespace then setting a
// prefix other than xml isn't allowed, if the namespace of the attribute is
// not the XML namespace then setting the prefix to xml isn't allowed.
if ((mNodeInfo->NamespaceID() == kNameSpaceID_XML) !=
(prefix == nsGkAtoms::xml)) {
if (!nsContentUtils::IsValidNodeName(mNodeInfo->NameAtom(), prefix,
mNodeInfo->NamespaceID())) {
return NS_ERROR_DOM_NAMESPACE_ERR;
}

View File

@ -1063,24 +1063,10 @@ nsGenericElement::SetPrefix(const nsAString& aPrefix)
if (!aPrefix.IsEmpty()) {
prefix = do_GetAtom(aPrefix);
NS_ENSURE_TRUE(prefix, NS_ERROR_OUT_OF_MEMORY);
// If the namespace of the element is null then setting a non-null prefix
// isn't allowed.
if (mNodeInfo->NamespaceID() == kNameSpaceID_None) {
return NS_ERROR_DOM_NAMESPACE_ERR;
}
}
// If the namespace of the element is the XML namespace then setting a prefix
// other than xml isn't allowed, if the namespace of the element is not the
// XML namespace then setting the prefix to xml isn't allowed.
// If the namespace of the element is the XMLNS namespace then setting a
// prefix other than xmlns isn't allowed, if the namespace of the element is
// not the XMLNS namespace then setting the prefix to xmlns isn't allowed.
if (((mNodeInfo->NamespaceID() == kNameSpaceID_XML) !=
(prefix == nsGkAtoms::xml)) ||
((mNodeInfo->NamespaceID() == kNameSpaceID_XMLNS) !=
(prefix == nsGkAtoms::xmlns))) {
if (!nsContentUtils::IsValidNodeName(mNodeInfo->NameAtom(), prefix,
mNodeInfo->NamespaceID())) {
return NS_ERROR_DOM_NAMESPACE_ERR;
}

View File

@ -344,9 +344,15 @@ nsXMLContentSerializer::ConfirmPrefix(nsAString& aPrefix,
nsIDOMElement* aElement,
PRBool aIsAttribute)
{
if (aPrefix.EqualsLiteral(kXMLNS) ||
(aPrefix.EqualsLiteral("xml") &&
aURI.EqualsLiteral("http://www.w3.org/XML/1998/namespace"))) {
if (aPrefix.EqualsLiteral(kXMLNS)) {
return PR_FALSE;
}
if (aURI.EqualsLiteral("http://www.w3.org/XML/1998/namespace")) {
// The prefix must be xml for this namespace. We don't need to declare it,
// so always just set the prefix to xml.
aPrefix.AssignLiteral("xml");
return PR_FALSE;
}