Bug 466576 - Null deref [@ nsSVGTransformList::GetValueString] after failed appendItem. r+sr=roc a1.9.0.12=dveditz

git-svn-id: svn://10.0.0.236/trunk@257323 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
longsonr%gmail.com 2009-05-30 20:03:13 +00:00
parent f7d78a4cf0
commit ce16f9d2c2

View File

@ -49,6 +49,15 @@
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsIDOMClassInfo.h" #include "nsIDOMClassInfo.h"
#define NS_ENSURE_NATIVE_TRANSFORM(obj, retval) \
{ \
nsresult rv; \
if (retval) \
*retval = nsnull; \
nsCOMPtr<nsISVGValue> transform = do_QueryInterface(obj, &rv); \
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SVG_WRONG_TYPE_ERR); \
}
nsresult nsresult
nsSVGTransformList::Create(nsIDOMSVGTransformList** aResult) nsSVGTransformList::Create(nsIDOMSVGTransformList** aResult)
{ {
@ -75,7 +84,6 @@ nsSVGTransformList::ReleaseTransforms()
for (PRInt32 i = 0; i < count; ++i) { for (PRInt32 i = 0; i < count; ++i) {
nsIDOMSVGTransform* transform = ElementAt(i); nsIDOMSVGTransform* transform = ElementAt(i);
nsCOMPtr<nsISVGValue> val = do_QueryInterface(transform); nsCOMPtr<nsISVGValue> val = do_QueryInterface(transform);
if (val)
val->RemoveObserver(this); val->RemoveObserver(this);
NS_RELEASE(transform); NS_RELEASE(transform);
} }
@ -95,7 +103,6 @@ nsSVGTransformList::AppendElement(nsIDOMSVGTransform* aElement)
if (rv) { if (rv) {
NS_ADDREF(aElement); NS_ADDREF(aElement);
nsCOMPtr<nsISVGValue> val = do_QueryInterface(aElement); nsCOMPtr<nsISVGValue> val = do_QueryInterface(aElement);
if (val)
val->AddObserver(this); val->AddObserver(this);
} }
@ -244,18 +251,16 @@ NS_IMETHODIMP nsSVGTransformList::Clear()
NS_IMETHODIMP nsSVGTransformList::Initialize(nsIDOMSVGTransform *newItem, NS_IMETHODIMP nsSVGTransformList::Initialize(nsIDOMSVGTransform *newItem,
nsIDOMSVGTransform **_retval) nsIDOMSVGTransform **_retval)
{ {
*_retval = newItem; NS_ENSURE_NATIVE_TRANSFORM(newItem, _retval);
if (!newItem)
return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
nsSVGValueAutoNotifier autonotifier(this); nsSVGValueAutoNotifier autonotifier(this);
ReleaseTransforms(); ReleaseTransforms();
if (!AppendElement(newItem)) { if (!AppendElement(newItem)) {
*_retval = nsnull;
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
*_retval = newItem;
NS_ADDREF(*_retval); NS_ADDREF(*_retval);
return NS_OK; return NS_OK;
} }
@ -278,24 +283,21 @@ NS_IMETHODIMP nsSVGTransformList::InsertItemBefore(nsIDOMSVGTransform *newItem,
PRUint32 index, PRUint32 index,
nsIDOMSVGTransform **_retval) nsIDOMSVGTransform **_retval)
{ {
*_retval = newItem; NS_ENSURE_NATIVE_TRANSFORM(newItem, _retval);
if (!newItem)
return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
nsSVGValueAutoNotifier autonotifier(this); nsSVGValueAutoNotifier autonotifier(this);
PRUint32 count = mTransforms.Count(); PRUint32 count = mTransforms.Count();
if (!mTransforms.InsertElementAt((void*)newItem, (index < count)? index: count)) { if (!mTransforms.InsertElementAt((void*)newItem, (index < count)? index: count)) {
*_retval = nsnull;
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
NS_ADDREF(newItem); NS_ADDREF(newItem);
nsCOMPtr<nsISVGValue> val = do_QueryInterface(newItem); nsCOMPtr<nsISVGValue> val = do_QueryInterface(newItem);
if (val)
val->AddObserver(this); val->AddObserver(this);
*_retval = newItem;
NS_ADDREF(*_retval); NS_ADDREF(*_retval);
return NS_OK; return NS_OK;
} }
@ -305,10 +307,7 @@ NS_IMETHODIMP nsSVGTransformList::ReplaceItem(nsIDOMSVGTransform *newItem,
PRUint32 index, PRUint32 index,
nsIDOMSVGTransform **_retval) nsIDOMSVGTransform **_retval)
{ {
if (!newItem) NS_ENSURE_NATIVE_TRANSFORM(newItem, _retval);
return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
*_retval = nsnull;
nsSVGValueAutoNotifier autonotifier(this); nsSVGValueAutoNotifier autonotifier(this);
@ -323,11 +322,9 @@ NS_IMETHODIMP nsSVGTransformList::ReplaceItem(nsIDOMSVGTransform *newItem,
} }
nsCOMPtr<nsISVGValue> val = do_QueryInterface(oldItem); nsCOMPtr<nsISVGValue> val = do_QueryInterface(oldItem);
if (val)
val->RemoveObserver(this); val->RemoveObserver(this);
NS_RELEASE(oldItem); NS_RELEASE(oldItem);
val = do_QueryInterface(newItem); val = do_QueryInterface(newItem);
if (val)
val->AddObserver(this); val->AddObserver(this);
NS_ADDREF(newItem); NS_ADDREF(newItem);
@ -355,7 +352,6 @@ NS_IMETHODIMP nsSVGTransformList::RemoveItem(PRUint32 index, nsIDOMSVGTransform
} }
nsCOMPtr<nsISVGValue> val = do_QueryInterface(*_retval); nsCOMPtr<nsISVGValue> val = do_QueryInterface(*_retval);
if (val)
val->RemoveObserver(this); val->RemoveObserver(this);
// don't NS_ADDREF(*_retval) // don't NS_ADDREF(*_retval)
@ -366,17 +362,15 @@ NS_IMETHODIMP nsSVGTransformList::RemoveItem(PRUint32 index, nsIDOMSVGTransform
NS_IMETHODIMP nsSVGTransformList::AppendItem(nsIDOMSVGTransform *newItem, NS_IMETHODIMP nsSVGTransformList::AppendItem(nsIDOMSVGTransform *newItem,
nsIDOMSVGTransform **_retval) nsIDOMSVGTransform **_retval)
{ {
*_retval = newItem; NS_ENSURE_NATIVE_TRANSFORM(newItem, _retval);
if (!newItem)
return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
nsSVGValueAutoNotifier autonotifier(this); nsSVGValueAutoNotifier autonotifier(this);
if (!AppendElement(newItem)) { if (!AppendElement(newItem)) {
*_retval = nsnull;
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
*_retval = newItem;
NS_ADDREF(*_retval); NS_ADDREF(*_retval);
return NS_OK; return NS_OK;
} }