mirror of
https://github.com/hyprwm/hyprutils.git
synced 2024-12-22 10:49:48 +01:00
memory: avoid undefined behaviour from downcasting ptr implentation (#5)
* sharedptr: dont downcast ptr implentation avoid runtime errors of wrong downcasts by adding a underlaying ptr data getter and only cast the data, downcasting the implentation type isnt inherited from eachother, while the intention was do upcast/downcast a derived class to a base class. found with UBSAN "runtime error: downcast of address which does not point to an object of type "CSharedPointer_::impl<IKeyboard>" note: object is of type "Hyprutils::Memory::CSharedPointer_::impl<CKeyboard>" also make dataNonNull check against != nullptr. * sharedptr: use reinterpret_cast instead of c style make it more type safe, C style casts tries every single one until one works, or not. compilers also produces better warnings/errors when using c++ casts in favour of C style ones.
This commit is contained in:
parent
1f6bbec595
commit
7e1b6610a2
2 changed files with 13 additions and 8 deletions
|
@ -20,7 +20,7 @@ namespace Hyprutils {
|
|||
namespace CSharedPointer_ {
|
||||
class impl_base {
|
||||
public:
|
||||
virtual ~impl_base(){};
|
||||
virtual ~impl_base() {};
|
||||
|
||||
virtual void inc() noexcept = 0;
|
||||
virtual void dec() noexcept = 0;
|
||||
|
@ -31,6 +31,7 @@ namespace Hyprutils {
|
|||
virtual void destroy() noexcept = 0;
|
||||
virtual bool destroying() noexcept = 0;
|
||||
virtual bool dataNonNull() noexcept = 0;
|
||||
virtual void* getData() noexcept = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
@ -107,6 +108,10 @@ namespace Hyprutils {
|
|||
}
|
||||
|
||||
virtual bool dataNonNull() noexcept {
|
||||
return _data != nullptr;
|
||||
}
|
||||
|
||||
virtual void* getData() noexcept {
|
||||
return _data;
|
||||
}
|
||||
|
||||
|
@ -213,11 +218,11 @@ namespace Hyprutils {
|
|||
}
|
||||
|
||||
bool operator()(const CSharedPointer& lhs, const CSharedPointer& rhs) const {
|
||||
return (uintptr_t)lhs.impl_ < (uintptr_t)rhs.impl_;
|
||||
return reinterpret_cast<uintptr_t>(lhs.impl_) < reinterpret_cast<uintptr_t>(rhs.impl_);
|
||||
}
|
||||
|
||||
bool operator<(const CSharedPointer& rhs) const {
|
||||
return (uintptr_t)impl_ < (uintptr_t)rhs.impl_;
|
||||
return reinterpret_cast<uintptr_t>(impl_) < reinterpret_cast<uintptr_t>(rhs.impl_);
|
||||
}
|
||||
|
||||
T* operator->() const {
|
||||
|
@ -234,7 +239,7 @@ namespace Hyprutils {
|
|||
}
|
||||
|
||||
T* get() const {
|
||||
return (T*)(impl_ ? static_cast<CSharedPointer_::impl<T>*>(impl_)->_data : nullptr);
|
||||
return impl_ ? static_cast<T*>(impl_->getData()) : nullptr;
|
||||
}
|
||||
|
||||
unsigned int strongRef() const {
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace Hyprutils {
|
|||
/* create a weak ptr from a shared ptr with assignment */
|
||||
template <typename U>
|
||||
validHierarchy<const CWeakPointer<U>&> operator=(const CSharedPointer<U>& rhs) {
|
||||
if ((uintptr_t)impl_ == (uintptr_t)rhs.impl_)
|
||||
if (reinterpret_cast<uintptr_t>(impl_) == reinterpret_cast<uintptr_t>(rhs.impl_))
|
||||
return *this;
|
||||
|
||||
decrementWeak();
|
||||
|
@ -139,15 +139,15 @@ namespace Hyprutils {
|
|||
}
|
||||
|
||||
bool operator()(const CWeakPointer& lhs, const CWeakPointer& rhs) const {
|
||||
return (uintptr_t)lhs.impl_ < (uintptr_t)rhs.impl_;
|
||||
return reinterpret_cast<uintptr_t>(lhs.impl_) < reinterpret_cast<uintptr_t>(rhs.impl_);
|
||||
}
|
||||
|
||||
bool operator<(const CWeakPointer& rhs) const {
|
||||
return (uintptr_t)impl_ < (uintptr_t)rhs.impl_;
|
||||
return reinterpret_cast<uintptr_t>(impl_) < reinterpret_cast<uintptr_t>(rhs.impl_);
|
||||
}
|
||||
|
||||
T* get() const {
|
||||
return (T*)(impl_ ? static_cast<CSharedPointer_::impl<T>*>(impl_)->_data : nullptr);
|
||||
return impl_ ? static_cast<T*>(impl_->getData()) : nullptr;
|
||||
}
|
||||
|
||||
T* operator->() const {
|
||||
|
|
Loading…
Reference in a new issue