Bug 324723: Make nsPropertyTable resistent against using the wrong base pointer by enforcing type safety. r/sr=jst

git-svn-id: svn://10.0.0.236/trunk@188286 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
cvshook%sicking.cc
2006-01-26 23:40:49 +00:00
parent e6e187191b
commit 8d4b46ee48
5 changed files with 48 additions and 34 deletions

View File

@@ -70,8 +70,7 @@ nsDOMAttribute::~nsDOMAttribute()
if (doc) {
doc->CallUserDataHandler(nsIDOMUserDataHandler::NODE_DELETED, this,
nsnull, nsnull);
doc->PropertyTable()->
DeleteAllPropertiesFor(NS_STATIC_CAST(nsINode*, this));
doc->PropertyTable()->DeleteAllPropertiesFor(this);
}
if (mChildList) {
@@ -139,8 +138,7 @@ nsDOMAttribute::SetOwnerDocument(nsIDocument* aDocument)
nsIDocument *doc = GetOwnerDoc();
NS_ASSERTION(doc != aDocument, "bad call to nsDOMAttribute::SetOwnerDocument");
if (doc) {
doc->PropertyTable()->
DeleteAllPropertiesFor(NS_STATIC_CAST(nsINode*, this));
doc->PropertyTable()->DeleteAllPropertiesFor(this);
}
nsCOMPtr<nsINodeInfo> newNodeInfo;

View File

@@ -72,8 +72,7 @@ nsGenericDOMDataNode::~nsGenericDOMDataNode()
if (document) {
document->CallUserDataHandler(nsIDOMUserDataHandler::NODE_DELETED,
this, nsnull, nsnull);
document->PropertyTable()->
DeleteAllPropertiesFor(NS_STATIC_CAST(nsINode*, this));
document->PropertyTable()->DeleteAllPropertiesFor(this);
}
}
@@ -718,8 +717,7 @@ nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
ownerDocument->CopyUserData(this, aDocument);
// Remove all properties.
ownerDocument->PropertyTable()->
DeleteAllPropertiesFor(NS_STATIC_CAST(nsINode*, this));
ownerDocument->PropertyTable()->DeleteAllPropertiesFor(this);
}
// get a new nodeinfo

View File

@@ -867,8 +867,7 @@ nsGenericElement::~nsGenericElement()
if (document) {
document->CallUserDataHandler(nsIDOMUserDataHandler::NODE_DELETED,
this, nsnull, nsnull);
document->PropertyTable()->
DeleteAllPropertiesFor(NS_STATIC_CAST(nsINode*, this));
document->PropertyTable()->DeleteAllPropertiesFor(this);
}
}
@@ -1927,8 +1926,7 @@ nsGenericElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
ownerDocument->CopyUserData(this, aDocument);
// Remove all properties.
ownerDocument->PropertyTable()->
DeleteAllPropertiesFor(NS_STATIC_CAST(nsINode*, this));
ownerDocument->PropertyTable()->DeleteAllPropertiesFor(this);
}
// get a new nodeinfo

View File

@@ -70,7 +70,7 @@ public:
// Removes the property associated with the given object, and destroys
// the property value
NS_HIDDEN_(PRBool) DeletePropertyFor(const void * aObject);
NS_HIDDEN_(PRBool) DeletePropertyFor(nsPropertyOwner aObject);
// Destroy all remaining properties (without removing them)
NS_HIDDEN_(void) Destroy();
@@ -120,7 +120,7 @@ nsPropertyTable::DeleteAllProperties()
}
void
nsPropertyTable::DeleteAllPropertiesFor(const void *aObject)
nsPropertyTable::DeleteAllPropertiesFor(nsPropertyOwner aObject)
{
for (PropertyList* prop = mPropertyList; prop; prop = prop->mNext) {
prop->DeletePropertyFor(aObject);
@@ -128,7 +128,7 @@ nsPropertyTable::DeleteAllPropertiesFor(const void *aObject)
}
void
nsPropertyTable::Enumerate(const void *aObject, PRUint32 aCategory,
nsPropertyTable::Enumerate(nsPropertyOwner aObject, PRUint32 aCategory,
NSPropertyFunc aCallback, void *aData)
{
PropertyList* prop;
@@ -138,7 +138,7 @@ nsPropertyTable::Enumerate(const void *aObject, PRUint32 aCategory,
PL_DHashTableOperate(&prop->mObjectValueMap, aObject,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
aCallback(NS_CONST_CAST(void*, aObject), prop->mName, entry->value,
aCallback(NS_CONST_CAST(void*, aObject.get()), prop->mName, entry->value,
aData);
}
}
@@ -146,7 +146,7 @@ nsPropertyTable::Enumerate(const void *aObject, PRUint32 aCategory,
}
void*
nsPropertyTable::GetPropertyInternal(const void *aObject,
nsPropertyTable::GetPropertyInternal(nsPropertyOwner aObject,
PRUint32 aCategory,
nsIAtom *aPropertyName,
PRBool aRemove,
@@ -178,7 +178,7 @@ nsPropertyTable::GetPropertyInternal(const void *aObject,
}
nsresult
nsPropertyTable::SetPropertyInternal(const void *aObject,
nsPropertyTable::SetPropertyInternal(nsPropertyOwner aObject,
PRUint32 aCategory,
nsIAtom *aPropertyName,
void *aPropertyValue,
@@ -236,7 +236,7 @@ nsPropertyTable::SetPropertyInternal(const void *aObject,
}
nsresult
nsPropertyTable::DeleteProperty(const void *aObject,
nsPropertyTable::DeleteProperty(nsPropertyOwner aObject,
PRUint32 aCategory,
nsIAtom *aPropertyName)
{
@@ -315,7 +315,7 @@ nsPropertyTable::PropertyList::Destroy()
}
PRBool
nsPropertyTable::PropertyList::DeletePropertyFor(const void* aObject)
nsPropertyTable::PropertyList::DeletePropertyFor(nsPropertyOwner aObject)
{
PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*,
PL_DHashTableOperate(&mObjectValueMap, aObject, PL_DHASH_LOOKUP));
@@ -323,7 +323,7 @@ nsPropertyTable::PropertyList::DeletePropertyFor(const void* aObject)
return PR_FALSE;
if (mDtorFunc)
mDtorFunc(NS_CONST_CAST(void*, aObject), mName,
mDtorFunc(NS_CONST_CAST(void*, aObject.get()), mName,
entry->value, GetDtorData());
PL_DHashTableRawRemove(&mObjectValueMap, entry);

View File

@@ -73,6 +73,26 @@ typedef void
* is the opaque destructor data that was passed to SetProperty().
**/
typedef NSPropertyFunc NSPropertyDtorFunc;
class nsINode;
class nsIFrame;
class nsPropertyOwner
{
public:
nsPropertyOwner(const nsPropertyOwner& aOther) : mObject(aOther.mObject) {}
// These are the types of objects that can own properties. No object should
// inherit more then one of these classes.
// To add support for more types just add to this list.
nsPropertyOwner(const nsINode* aObject) : mObject(aObject) {}
nsPropertyOwner(const nsIFrame* aObject) : mObject(aObject) {}
operator const void*() { return mObject; }
const void* get() { return mObject; }
private:
const void* mObject;
};
// Categories of properties
// 0x00000000U is global.
@@ -87,14 +107,14 @@ class nsPropertyTable
* Get the value of the property |aPropertyName| for node |aObject|.
* |aResult|, if supplied, is filled in with a return status code.
**/
void* GetProperty(const void *aObject,
void* GetProperty(nsPropertyOwner aObject,
nsIAtom *aPropertyName,
nsresult *aResult = nsnull)
{
return GetPropertyInternal(aObject, 0, aPropertyName, PR_FALSE, aResult);
}
void* GetProperty(const void *aObject,
void* GetProperty(nsPropertyOwner aObject,
PRUint32 aCategory,
nsIAtom *aPropertyName,
nsresult *aResult = nsnull)
@@ -115,7 +135,7 @@ class nsPropertyTable
* it will contain the old value after the function returns (the destructor
* for the old value will not be run in that case).
*/
NS_HIDDEN_(nsresult) SetProperty(const void *aObject,
NS_HIDDEN_(nsresult) SetProperty(nsPropertyOwner aObject,
nsIAtom *aPropertyName,
void *aPropertyValue,
NSPropertyDtorFunc aDtor,
@@ -137,7 +157,7 @@ class nsPropertyTable
* old value after the function returns (the destructor for the old value
* will not be run in that case).
*/
NS_HIDDEN_(nsresult) SetProperty(const void *aObject,
NS_HIDDEN_(nsresult) SetProperty(nsPropertyOwner aObject,
PRUint32 aCategory,
nsIAtom *aPropertyName,
void *aPropertyValue,
@@ -152,7 +172,7 @@ class nsPropertyTable
* Delete the property |aPropertyName| in the global category for object
* |aObject|. The property's destructor function will be called.
*/
NS_HIDDEN_(nsresult) DeleteProperty(const void *aObject,
NS_HIDDEN_(nsresult) DeleteProperty(nsPropertyOwner aObject,
nsIAtom *aPropertyName)
{
return DeleteProperty(aObject, 0, aPropertyName);
@@ -162,7 +182,7 @@ class nsPropertyTable
* Delete the property |aPropertyName| in category |aCategory| for object
* |aObject|. The property's destructor function will be called.
*/
NS_HIDDEN_(nsresult) DeleteProperty(const void *aObject,
NS_HIDDEN_(nsresult) DeleteProperty(nsPropertyOwner aObject,
PRUint32 aCategory,
nsIAtom *aPropertyName);
@@ -171,7 +191,7 @@ class nsPropertyTable
* |aObject|, but do not call the property's destructor function. The
* property value is returned.
*/
void* UnsetProperty(const void *aObject,
void* UnsetProperty(nsPropertyOwner aObject,
nsIAtom *aPropertyName,
nsresult *aStatus = nsnull)
{
@@ -183,7 +203,7 @@ class nsPropertyTable
* |aObject|, but do not call the property's destructor function. The
* property value is returned.
*/
void* UnsetProperty(const void *aObject,
void* UnsetProperty(nsPropertyOwner aObject,
PRUint32 aCategory,
nsIAtom *aPropertyName,
nsresult *aStatus = nsnull)
@@ -196,14 +216,14 @@ class nsPropertyTable
* Deletes all of the properties for object |aObject|, calling the
* destructor function for each property.
*/
NS_HIDDEN_(void) DeleteAllPropertiesFor(const void *aObject);
NS_HIDDEN_(void) DeleteAllPropertiesFor(nsPropertyOwner aObject);
/**
* Enumerate the properties in category |aCategory| for object |aObject|.
* For every property |aCallback| will be called with as arguments |aObject|,
* the property name, the property value and |aData|.
*/
NS_HIDDEN_(void) Enumerate(const void *aObject, PRUint32 aCategory,
NS_HIDDEN_(void) Enumerate(nsPropertyOwner aObject, PRUint32 aCategory,
NSPropertyFunc aCallback, void *aData);
/**
@@ -216,18 +236,18 @@ class nsPropertyTable
DeleteAllProperties();
}
struct PropertyList;
class PropertyList;
private:
NS_HIDDEN_(void) DestroyPropertyList();
NS_HIDDEN_(PropertyList*) GetPropertyListFor(PRUint32 aCategory,
nsIAtom *aPropertyName) const;
NS_HIDDEN_(void*) GetPropertyInternal(const void *aObject,
NS_HIDDEN_(void*) GetPropertyInternal(nsPropertyOwner aObject,
PRUint32 aCategory,
nsIAtom *aPropertyName,
PRBool aRemove,
nsresult *aStatus);
NS_HIDDEN_(nsresult) SetPropertyInternal(const void *aObject,
NS_HIDDEN_(nsresult) SetPropertyInternal(nsPropertyOwner aObject,
PRUint32 aCategory,
nsIAtom *aPropertyName,
void *aPropertyValue,