]> git.tdb.fi Git - ext/sigc++-2.0.git/blob - tests/test_copy_invalid_slot.cc
Adjust the name of the library to match upstream
[ext/sigc++-2.0.git] / tests / test_copy_invalid_slot.cc
1 #include "testutilities.h"
2 #include <sstream>
3 #include <cstdlib>
4 #include <sigc++/sigc++.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 namespace
9 {
10 std::ostringstream result_stream;
11
12 void Foo(sigc::trackable&)
13 {
14   result_stream << "Foo(x)";
15 }
16
17 } // end anonymous namespace
18
19 int main(int argc, char* argv[])
20 {
21   auto util = TestUtilities::get_instance();
22
23   if (!util->check_command_args(argc, argv))
24     return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
25
26   std::ostringstream pointer_stream;
27   auto t = new sigc::trackable();
28   pointer_stream << t;
29   result_stream << "sigc::trackable instance at " << pointer_stream.str();
30   util->check_result(result_stream, "sigc::trackable instance at " + pointer_stream.str());
31   pointer_stream.str("");
32
33   sigc::slot<void> foo = sigc::bind(sigc::ptr_fun(Foo), std::ref(*t));
34   foo();
35   util->check_result(result_stream, "Foo(x)");
36
37   // This invalidates foo.
38   delete t;
39
40   // Try to crash if the invalid slot parameter is used by libsigc++,
41   // and get a debugger backtrace at the point that it happens.
42   //
43   // Comment this out to get a meaningful backtrace from valgrind.
44   //
45   // Try to pollute the memory previously occupied by the sigc::trackable
46   // instance. The hope is that with a regular memory allocator (i.e. not
47   // valgrind), we end up with buffer == (void *)t.
48   void* buffer = malloc(sizeof(sigc::trackable));
49   memset(buffer, 0xFF, sizeof(sigc::trackable));
50   pointer_stream << buffer;
51   result_stream << "         Polluted buffer at " << pointer_stream.str();
52   util->check_result(result_stream, "         Polluted buffer at " + pointer_stream.str());
53   pointer_stream.str("");
54
55   // Now copy foo: up to libsigc++ version 2.0.11, the copy constructor fails
56   // because the pointer value it dereferences does not point to a
57   // sigc::trackable anymore, it now points to a polluted buffer.
58   sigc::slot<void> bar = foo;
59   bar();
60   util->check_result(result_stream, "");
61
62   free(buffer);
63
64   return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
65 }