Bug 880544 - Fix leak in DOMSVGLengthList. r=dzbarksy

This commit is contained in:
Jonathan Watt 2013-07-12 11:25:26 +01:00
parent f27c614f62
commit 5b7080e74d
5 changed files with 44 additions and 23 deletions

View File

@ -176,7 +176,18 @@ DOMSVGLengthList::Initialize(nsIDOMSVGLength *newItem,
return InsertItemBefore(newItem, 0, error); return InsertItemBefore(newItem, 0, error);
} }
nsIDOMSVGLength* already_AddRefed<nsIDOMSVGLength>
DOMSVGLengthList::GetItem(uint32_t index, ErrorResult& error)
{
bool found;
nsRefPtr<nsIDOMSVGLength> item = IndexedGetter(index, found, error);
if (!found) {
error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
}
return item.forget();
}
already_AddRefed<nsIDOMSVGLength>
DOMSVGLengthList::IndexedGetter(uint32_t index, bool& found, ErrorResult& error) DOMSVGLengthList::IndexedGetter(uint32_t index, bool& found, ErrorResult& error)
{ {
if (IsAnimValList()) { if (IsAnimValList()) {
@ -184,8 +195,7 @@ DOMSVGLengthList::IndexedGetter(uint32_t index, bool& found, ErrorResult& error)
} }
found = index < LengthNoFlush(); found = index < LengthNoFlush();
if (found) { if (found) {
EnsureItemAt(index); return GetItemAt(index);
return mItems[index];
} }
return nullptr; return nullptr;
} }
@ -307,13 +317,12 @@ DOMSVGLengthList::RemoveItem(uint32_t index,
// internal value. // internal value.
MaybeRemoveItemFromAnimValListAt(index); MaybeRemoveItemFromAnimValListAt(index);
// We have to return the removed item, so make sure it exists: // We have to return the removed item, so get it, creating it if necessary:
EnsureItemAt(index); nsCOMPtr<nsIDOMSVGLength> result = GetItemAt(index);
// Notify the DOM item of removal *before* modifying the lists so that the // Notify the DOM item of removal *before* modifying the lists so that the
// DOM item can copy its *old* value: // DOM item can copy its *old* value:
mItems[index]->RemovingFromList(); mItems[index]->RemovingFromList();
nsCOMPtr<nsIDOMSVGLength> result = mItems[index];
InternalList().RemoveItem(index); InternalList().RemoveItem(index);
mItems.RemoveElementAt(index); mItems.RemoveElementAt(index);
@ -327,12 +336,16 @@ DOMSVGLengthList::RemoveItem(uint32_t index,
return result.forget(); return result.forget();
} }
void already_AddRefed<nsIDOMSVGLength>
DOMSVGLengthList::EnsureItemAt(uint32_t aIndex) DOMSVGLengthList::GetItemAt(uint32_t aIndex)
{ {
MOZ_ASSERT(aIndex < mItems.Length());
if (!mItems[aIndex]) { if (!mItems[aIndex]) {
mItems[aIndex] = new DOMSVGLength(this, AttrEnum(), aIndex, IsAnimValList()); mItems[aIndex] = new DOMSVGLength(this, AttrEnum(), aIndex, IsAnimValList());
} }
nsRefPtr<nsIDOMSVGLength> result = mItems[aIndex];
return result.forget();
} }
void void

View File

@ -103,17 +103,10 @@ public:
void Clear(ErrorResult& aError); void Clear(ErrorResult& aError);
already_AddRefed<nsIDOMSVGLength> Initialize(nsIDOMSVGLength *newItem, already_AddRefed<nsIDOMSVGLength> Initialize(nsIDOMSVGLength *newItem,
ErrorResult& error); ErrorResult& error);
nsIDOMSVGLength* GetItem(uint32_t index, ErrorResult& error) already_AddRefed<nsIDOMSVGLength> GetItem(uint32_t index,
{ ErrorResult& error);
bool found; already_AddRefed<nsIDOMSVGLength> IndexedGetter(uint32_t index, bool& found,
nsIDOMSVGLength* item = IndexedGetter(index, found, error); ErrorResult& error);
if (!found) {
error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
}
return item;
}
nsIDOMSVGLength* IndexedGetter(uint32_t index, bool& found,
ErrorResult& error);
already_AddRefed<nsIDOMSVGLength> InsertItemBefore(nsIDOMSVGLength *newItem, already_AddRefed<nsIDOMSVGLength> InsertItemBefore(nsIDOMSVGLength *newItem,
uint32_t index, uint32_t index,
ErrorResult& error); ErrorResult& error);
@ -163,8 +156,8 @@ private:
*/ */
SVGLengthList& InternalList() const; SVGLengthList& InternalList() const;
/// Creates a DOMSVGLength for aIndex, if it doesn't already exist. /// Returns the nsIDOMSVGLength at aIndex, creating it if necessary.
void EnsureItemAt(uint32_t aIndex); already_AddRefed<nsIDOMSVGLength> GetItemAt(uint32_t aIndex);
void MaybeInsertNullInAnimValListAt(uint32_t aIndex); void MaybeInsertNullInAnimValListAt(uint32_t aIndex);
void MaybeRemoveItemFromAnimValListAt(uint32_t aIndex); void MaybeRemoveItemFromAnimValListAt(uint32_t aIndex);

View File

@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg">
<script>//<![CDATA[
function add_watch()
{
document.getElementById("e").x.baseVal.watch("0", function(){});
}
window.addEventListener("load", add_watch, false);
//]]></script>
<text id="e" x="10">foo</text>
</svg>

After

Width:  |  Height:  |  Size: 283 B

View File

@ -67,3 +67,4 @@ load 837450-1.svg
load 842463-1.html load 842463-1.html
load 864509.svg load 864509.svg
load 880544-1.svg load 880544-1.svg
load 880544-2.svg

View File

@ -933,8 +933,7 @@ DOMInterfaces = {
'SVGLengthList': { 'SVGLengthList': {
'nativeType': 'mozilla::DOMSVGLengthList', 'nativeType': 'mozilla::DOMSVGLengthList',
'headerFile': 'DOMSVGLengthList.h', 'headerFile': 'DOMSVGLengthList.h'
'resultNotAddRefed': [ 'getItem' ]
}, },
'SVGLinearGradientElement': { 'SVGLinearGradientElement': {