Issue:
In commit 1bf40a0, the type of the _pConfig member was changed from a raw pointer to Poco::AutoPtr, but the duplicate()/ release() calls in the implementation were not adapted accordingly. In most cases, the usage counter is now incremented twice, but not in a call to binding(), because the function still takes a raw pointer and assignment of a raw pointer to AutoPtr does not increment the counter. Since the Option destructor will call release() twice (once manually, once in the AutoPtr destructor), counter is decremented by 2.
If more than one option is bound to the same configuration object, this will result in an early free of the associated AbstractConfiguration object, and subsequent destructors will dereference a deleted pointer and cause a crash.
How to reproduce:
- Create a class based on
Poco::Util::Application.
- Add a member of type
Poco::Util::MapConfiguration::Ptr to the app and initialize it.
- Define two options in
defineOptions() bound to the configuration above.
- Run the application.
Expected result:
The application should terminate without error.
Actual result:
Depending on the compiler and OS, the application will crash with a C library error or segmentation fault. It's not totally reliable though, depending on memory layout.
Debugging with a breakpoint in Poco::Util::Option::~Option() and watching pConfig will always show the behaviour.
Issue:
In commit 1bf40a0, the type of the
_pConfigmember was changed from a raw pointer toPoco::AutoPtr, but theduplicate()/release()calls in the implementation were not adapted accordingly. In most cases, the usage counter is now incremented twice, but not in a call tobinding(), because the function still takes a raw pointer and assignment of a raw pointer to AutoPtr does not increment the counter. Since the Option destructor will callrelease()twice (once manually, once in the AutoPtr destructor), counter is decremented by 2.If more than one option is bound to the same configuration object, this will result in an early free of the associated AbstractConfiguration object, and subsequent destructors will dereference a deleted pointer and cause a crash.
How to reproduce:
Poco::Util::Application.Poco::Util::MapConfiguration::Ptrto the app and initialize it.defineOptions()bound to the configuration above.Expected result:
The application should terminate without error.
Actual result:
Depending on the compiler and OS, the application will crash with a C library error or segmentation fault. It's not totally reliable though, depending on memory layout.
Debugging with a breakpoint in
Poco::Util::Option::~Option()and watching pConfig will always show the behaviour.