Skip to content
This repository has been archived by the owner on Jun 23, 2022. It is now read-only.

Commit

Permalink
fix(asan): pointer used after free in autoref_ptr_test (#361)
Browse files Browse the repository at this point in the history
  • Loading branch information
foreverneverer authored and Wu Tao committed Dec 20, 2019
1 parent 1e1e6e0 commit 03a8ef9
Showing 1 changed file with 16 additions and 67 deletions.
83 changes: 16 additions & 67 deletions include/dsn/utility/autoref_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@

#include <atomic>
#include <cassert>
#include <type_traits>
#include <utility>

namespace dsn {
class ref_counter
Expand Down Expand Up @@ -106,21 +108,15 @@ class ref_ptr
_obj->add_ref();
}

template <typename U>
ref_ptr(U *obj) : _obj(obj)
{
if (nullptr != _obj)
_obj->add_ref();
}

ref_ptr(const ref_ptr<T> &r)
{
_obj = r.get();
if (nullptr != _obj)
_obj->add_ref();
}

template <typename U>
template <typename U,
typename = typename std::enable_if<std::is_convertible<U *, T *>::value>::type>
ref_ptr(const ref_ptr<U> &r)
{
_obj = r.get();
Expand All @@ -130,8 +126,9 @@ class ref_ptr

ref_ptr(ref_ptr<T> &&r) : _obj(r._obj) { r._obj = nullptr; }

template <typename U>
ref_ptr(ref_ptr<U> &&r) : _obj(r._obj)
template <typename U,
typename = typename std::enable_if<std::is_convertible<U *, T *>::value>::type>
ref_ptr(ref_ptr<U> &&r) noexcept : _obj(r._obj)
{
r._obj = nullptr;
}
Expand All @@ -143,72 +140,24 @@ class ref_ptr
}
}

ref_ptr<T> &operator=(T *obj)
{
if (_obj == obj)
return *this;

if (nullptr != _obj) {
_obj->release_ref();
}

_obj = obj;

if (obj != nullptr) {
_obj->add_ref();
}
ref_ptr<T> &operator=(T *obj) { return *this = ref_ptr(obj); }

return *this;
}

template <typename U>
ref_ptr<T> &operator=(U *obj)
ref_ptr<T> &operator=(ref_ptr<T> r) noexcept
{
if (_obj == obj)
return *this;
if (nullptr != _obj) {
_obj->release_ref();
}
_obj = obj;
if (_obj != nullptr) {
_obj->add_ref();
}
swap(r);
return *this;
}

ref_ptr<T> &operator=(const ref_ptr<T> &obj) { return operator=(obj._obj); }

template <typename U>
ref_ptr<T> &operator=(const ref_ptr<U> &obj)
template <typename U,
typename = typename std::enable_if<std::is_convertible<U *, T *>::value>::type>
ref_ptr<T> &operator=(ref_ptr<U> r) noexcept
{
return operator=(obj._obj);
}

ref_ptr<T> &operator=(ref_ptr<T> &&obj)
{
if (this == &obj) {
return *this;
}

if (nullptr != _obj) {
_obj->release_ref();
}

_obj = obj._obj;
obj._obj = nullptr;
ref_ptr<T> p(r);
swap(p);
return *this;
}

template <typename U>
ref_ptr<T> &operator=(ref_ptr<U> &&obj)
{
if (nullptr != _obj) {
_obj->release_ref();
}
_obj = obj._obj;
obj._obj = nullptr;
return *this;
}
void swap(ref_ptr<T> &r) noexcept { std::swap(_obj, r._obj); }

T *get() const { return _obj; }

Expand Down

0 comments on commit 03a8ef9

Please sign in to comment.