mirror of
https://github.com/hyprwm/hyprutils.git
synced 2024-11-17 00:15:58 +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_ {
|
namespace CSharedPointer_ {
|
||||||
class impl_base {
|
class impl_base {
|
||||||
public:
|
public:
|
||||||
virtual ~impl_base(){};
|
virtual ~impl_base() {};
|
||||||
|
|
||||||
virtual void inc() noexcept = 0;
|
virtual void inc() noexcept = 0;
|
||||||
virtual void dec() noexcept = 0;
|
virtual void dec() noexcept = 0;
|
||||||
|
@ -31,6 +31,7 @@ namespace Hyprutils {
|
||||||
virtual void destroy() noexcept = 0;
|
virtual void destroy() noexcept = 0;
|
||||||
virtual bool destroying() noexcept = 0;
|
virtual bool destroying() noexcept = 0;
|
||||||
virtual bool dataNonNull() noexcept = 0;
|
virtual bool dataNonNull() noexcept = 0;
|
||||||
|
virtual void* getData() noexcept = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -107,6 +108,10 @@ namespace Hyprutils {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool dataNonNull() noexcept {
|
virtual bool dataNonNull() noexcept {
|
||||||
|
return _data != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void* getData() noexcept {
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,11 +218,11 @@ namespace Hyprutils {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const CSharedPointer& lhs, const CSharedPointer& rhs) const {
|
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 {
|
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 {
|
T* operator->() const {
|
||||||
|
@ -234,7 +239,7 @@ namespace Hyprutils {
|
||||||
}
|
}
|
||||||
|
|
||||||
T* get() const {
|
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 {
|
unsigned int strongRef() const {
|
||||||
|
|
|
@ -80,7 +80,7 @@ namespace Hyprutils {
|
||||||
/* create a weak ptr from a shared ptr with assignment */
|
/* create a weak ptr from a shared ptr with assignment */
|
||||||
template <typename U>
|
template <typename U>
|
||||||
validHierarchy<const CWeakPointer<U>&> operator=(const CSharedPointer<U>& rhs) {
|
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;
|
return *this;
|
||||||
|
|
||||||
decrementWeak();
|
decrementWeak();
|
||||||
|
@ -139,15 +139,15 @@ namespace Hyprutils {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const CWeakPointer& lhs, const CWeakPointer& rhs) const {
|
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 {
|
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 {
|
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 {
|
T* operator->() const {
|
||||||
|
|
Loading…
Reference in a new issue