Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8c3c51bb authored by Mathias Agopian's avatar Mathias Agopian
Browse files

Fix a bug in sp<> and wp<> which could cause memory corruptions

when assigning a smart pointer to another one, we need to make
sure to read all the data we need from the right-hand-side
reference (the assignee) before we decRef the assigned.

This bug would cause linked-list of smart-pointers to fail
miserably.

Change-Id: Ibb554c15fddf909f7737c632b7c80322e80ea93f
parent 01e4483b
Loading
Loading
Loading
Loading
+20 −12
Original line number Diff line number Diff line
@@ -333,9 +333,10 @@ sp<T>::~sp()

template<typename T>
sp<T>& sp<T>::operator = (const sp<T>& other) {
    if (other.m_ptr) other.m_ptr->incStrong(this);
    T* otherPtr(other.m_ptr);
    if (otherPtr) otherPtr->incStrong(this);
    if (m_ptr) m_ptr->decStrong(this);
    m_ptr = other.m_ptr;
    m_ptr = otherPtr;
    return *this;
}

@@ -351,9 +352,10 @@ sp<T>& sp<T>::operator = (T* other)
template<typename T> template<typename U>
sp<T>& sp<T>::operator = (const sp<U>& other)
{
    if (other.m_ptr) other.m_ptr->incStrong(this);
    U* otherPtr(other.m_ptr);
    if (otherPtr) otherPtr->incStrong(this);
    if (m_ptr) m_ptr->decStrong(this);
    m_ptr = other.m_ptr;
    m_ptr = otherPtr;
    return *this;
}

@@ -466,10 +468,12 @@ wp<T>& wp<T>::operator = (T* other)
template<typename T>
wp<T>& wp<T>::operator = (const wp<T>& other)
{
    if (other.m_ptr) other.m_refs->incWeak(this);
    weakref_type* otherRefs(other.m_refs);
    T* otherPtr(other.m_ptr);
    if (otherPtr) otherRefs->incWeak(this);
    if (m_ptr) m_refs->decWeak(this);
    m_ptr = other.m_ptr;
    m_refs = other.m_refs;
    m_ptr = otherPtr;
    m_refs = otherRefs;
    return *this;
}

@@ -478,8 +482,9 @@ wp<T>& wp<T>::operator = (const sp<T>& other)
{
    weakref_type* newRefs =
        other != NULL ? other->createWeak(this) : 0;
    T* otherPtr(other.m_ptr);
    if (m_ptr) m_refs->decWeak(this);
    m_ptr = other.get();
    m_ptr = otherPtr;
    m_refs = newRefs;
    return *this;
}
@@ -498,10 +503,12 @@ wp<T>& wp<T>::operator = (U* other)
template<typename T> template<typename U>
wp<T>& wp<T>::operator = (const wp<U>& other)
{
    if (other.m_ptr) other.m_refs->incWeak(this);
    weakref_type* otherRefs(other.m_refs);
    U* otherPtr(other.m_ptr);
    if (otherPtr) otherRefs->incWeak(this);
    if (m_ptr) m_refs->decWeak(this);
    m_ptr = other.m_ptr;
    m_refs = other.m_refs;
    m_ptr = otherPtr;
    m_refs = otherRefs;
    return *this;
}

@@ -510,8 +517,9 @@ wp<T>& wp<T>::operator = (const sp<U>& other)
{
    weakref_type* newRefs =
        other != NULL ? other->createWeak(this) : 0;
    U* otherPtr(other.m_ptr);
    if (m_ptr) m_refs->decWeak(this);
    m_ptr = other.get();
    m_ptr = otherPtr;
    m_refs = newRefs;
    return *this;
}