fix undefined behavior in resource.hpp

Today, uvw triggers undefined behavior in resource.hpp:
  runtime error: downcast of address which does not point to an object of type 'uvw::FsEventHandle'
  note: object is of type 'uvw::BaseHandle'

It looks like we're saving the current handle in the void* data member
so it can be retrieved on the next callback run. This downcast to a
derived class from its parents ctor as it's being constructed isn't
valid.

Since we're storing this as a void* anyways and all the callsites using
it need to do their own cast on retrieval, we can instead persist the
this pointer. For downcasting to work in all cases the Resource class
tree needs to be leftmost in Handler's multiple inheritance.

Tested by verifying that my unit tests no longer show ubsan errors and
uvw's test suite still passes.
This commit is contained in:
Eli Lindsey 2020-04-02 14:37:45 -04:00
parent 8233a6e6b2
commit fc197b5117
2 changed files with 2 additions and 2 deletions

View File

@ -26,7 +26,7 @@ struct CloseEvent {};
* Base type for all `uvw` handle types.
*/
template<typename T, typename U>
class Handle: public BaseHandle, public Resource<T, U> {
class Handle: public Resource<T, U>, public BaseHandle {
protected:
static void closeCallback(uv_handle_t *handle) {
Handle<T, U> &ref = *(static_cast<T*>(handle->data));

View File

@ -42,7 +42,7 @@ public:
Emitter<T>{},
std::enable_shared_from_this<T>{}
{
this->get()->data = static_cast<T*>(this);
this->get()->data = this;
}
/**