Browse Source

Possible double free fixed (#146).

main
offa 6 years ago
parent
commit
6ffc328198
3 changed files with 36 additions and 1 deletions
  1. +4
    -1
      include/unique_resource.h
  2. +23
    -0
      test/CallMocks.h
  3. +9
    -0
      test/UniqueResourceTest.cpp

+ 4
- 1
include/unique_resource.h View File

@@ -63,7 +63,10 @@ namespace sr
&& std::is_nothrow_move_constructible_v<D>)
: resource(std::move_if_noexcept(other.resource.get()), scope_exit{[] { }}),
deleter(std::move_if_noexcept(other.deleter.get()), scope_exit{[&other] {
other.get_deleter()(other.resource.get());
if( other.execute_on_reset == true )
{
other.get_deleter()(other.resource.get());
}
other.release(); }}),
execute_on_reset(std::exchange(other.execute_on_reset, false))
{

+ 23
- 0
test/CallMocks.h View File

@@ -168,5 +168,28 @@ namespace mock
CopyMock(const CopyMock&) { }
};

struct ConditionalThrowOnCopyDeleter
{
ConditionalThrowOnCopyDeleter() { }

ConditionalThrowOnCopyDeleter(const ConditionalThrowOnCopyDeleter&)
{
if( throwOnNextCopy == true )
{
throw std::exception{};
}
throwOnNextCopy = false;
}

MAKE_CONST_MOCK1(deleter, void(Handle));

void operator()(Handle h) const
{
this->deleter(h);
}

static inline bool throwOnNextCopy{false};
};

}


+ 9
- 0
test/UniqueResourceTest.cpp View File

@@ -81,6 +81,15 @@ TEST_CASE("move-construction with copy", "[UniqueResource]")
[[maybe_unused]] auto guard = std::move(movedFrom);
}

TEST_CASE("move-construction prevents double release", "[UniqueResource]")
{
auto movedFrom = sr::unique_resource{Handle{3}, ConditionalThrowOnCopyDeleter{}};
movedFrom.release();
ConditionalThrowOnCopyDeleter::throwOnNextCopy = true;

REQUIRE_THROWS([&movedFrom] { [[maybe_unused]] auto guard = std::move(movedFrom); }());
}

TEST_CASE("move assignment calls deleter", "[UniqueResource]")
{
auto moveFrom = sr::unique_resource{Handle{3}, deleter};

Loading…
Cancel
Save