diff options
author | Murray Cumming <murrayc@murrayc.com> | 2005-05-01 02:00:47 +0000 |
---|---|---|
committer | Murray Cumming <murrayc@src.gnome.org> | 2005-05-01 02:00:47 +0000 |
commit | 66b2af11838094e8b4459f1d6fdedd8d35d4c483 (patch) | |
tree | bb2fb99656dd243c2c79af08703124b4940ee8e6 | |
parent | 9d3a58d8953932e3619da68ee2b31d8aff5d1f98 (diff) | |
download | sigc++-66b2af11838094e8b4459f1d6fdedd8d35d4c483.tar.gz |
slot_base::slot_base(src): If the source slot_base has a null rep->call_,
2005-05-01 Murray Cumming <murrayc@murrayc.com>
* sigc++/functors/slot_base.cc:
slot_base::slot_base(src): If the source
slot_base has a null rep->call_, meaning that the
slot is invalid, just return a default-constructed
slot, to prevent the crash shown in
tests/tests_copy_invalid_slot.cc. Bug #302515 by
Régis Duchesne.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | sigc++/functors/slot_base.cc | 14 | ||||
-rw-r--r-- | tests/test_copy_invalid_slot.cc | 5 |
3 files changed, 28 insertions, 1 deletions
@@ -1,5 +1,15 @@ 2005-05-01 Murray Cumming <murrayc@murrayc.com> + * sigc++/functors/slot_base.cc: + slot_base::slot_base(src): If the source + slot_base has a null rep->call_, meaning that the + slot is invalid, just return a default-constructed + slot, to prevent the crash shown in + tests/tests_copy_invalid_slot.cc. Bug #302515 by + Régis Duchesne. + +2005-05-01 Murray Cumming <murrayc@murrayc.com> + * sigc++/functors/macros/mem_fun.h.m4: bound_*<>: Add a new is_base_and_derived<sigc::trackable> parameter to the template and thereby provide a diff --git a/sigc++/functors/slot_base.cc b/sigc++/functors/slot_base.cc index 6f57e74..27e37ae 100644 --- a/sigc++/functors/slot_base.cc +++ b/sigc++/functors/slot_base.cc @@ -55,9 +55,11 @@ void slot_rep::disconnect() void* slot_rep::notify(void* data) { slot_rep* self_ = reinterpret_cast<slot_rep*>(data); + self_->call_ = 0; // Invalidate the slot. self_->destroy(); // Detach the stored functor from the other referred trackables and destroy it. self_->disconnect(); // Disconnect the slot (might lead to deletion of self_!). + return 0; } @@ -78,7 +80,17 @@ slot_base::slot_base(const slot_base& src) blocked_(src.blocked_) { if (src.rep_) - rep_ = src.rep_->dup(); + { + //Check call_ so we can ignore invalidated slots. + //Otherwise, destroyed bound reference parameters (whose destruction caused the slot's invalidation) may be used during dup(). + //Note: I'd prefer to check somewhere during dup(). murrayc. + if (src.rep_->call_) + rep_ = src.rep_->dup(); + else + { + *this = slot_base(); //Return the default invalid slot. + } + } } slot_base::~slot_base() diff --git a/tests/test_copy_invalid_slot.cc b/tests/test_copy_invalid_slot.cc index 4739c17..40162b0 100644 --- a/tests/test_copy_invalid_slot.cc +++ b/tests/test_copy_invalid_slot.cc @@ -11,6 +11,11 @@ int main(int argc, char **argv) // This invalidates foo. delete t; + // Try to crash if the invalid slot parameter is used by libsigc++, + // and get a debugger backtrace at the point that it happens. + // + // Comment this out to get a meaningful backtrace from valgrind. + // // Try to pollute the memory previously occupied by the sigc::trackable // instance. The hope is that with a regular memory allocator (i.e. not // valgrind), we end up with buffer == (void *)t. |