View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0002130 | NoesisGUI | Unreal | public | 2021-09-24 13:45 | 2021-12-10 15:14 |
| Reporter | hcpizzi | Assigned To | hcpizzi | ||
| Priority | normal | Severity | crash | ||
| Status | resolved | Resolution | fixed | ||
| Product Version | 3.1.1 | ||||
| Target Version | 3.1.2 | Fixed in Version | 3.1.2 | ||
| Summary | 0002130: Crash in SetPropertyByRef when Input is null | ||||
| Description | SetPropertyByRef and the underlying setters don't do enough validation on the Input parameter, including checking for null. | ||||
| Steps To Reproduce | Load the Buttons sample. | ||||
| Attached Files | NoesisTypeClass.cpp.patch (5,480 bytes)
Index: NoesisRuntime/Private/NoesisTypeClass.cpp
===================================================================
--- NoesisRuntime/Private/NoesisTypeClass.cpp (revision 10752)
+++ NoesisRuntime/Private/NoesisTypeClass.cpp (revision 10753)
@@ -339,6 +339,10 @@
template<class T>
bool GenericSetter(Noesis::BaseComponent* Input, void* BasePointer, FProperty* Property)
{
+ auto Boxed = Noesis::DynamicCast<Noesis::Boxed<typename NoesisTypeTraits<T>::NoesisType>*>(Input);
+ if (Boxed == nullptr)
+ return false;
+
void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
T TInput = NoesisTypeTraits<T>::ToUnreal(Noesis::Boxing::Unbox<typename NoesisTypeTraits<T>::NoesisType>(Input));
T& TValue = *(T*)Value;
@@ -353,31 +357,6 @@
return Noesis::TypeOf<typename NoesisTypeTraits<T>::NoesisType>();
}
-template<class T>
-Noesis::Ptr<Noesis::BaseComponent> GenericGetterPtr(void* BasePointer, FProperty* Property)
-{
- void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
- T& TValue = *(T*)Value;
- return Noesis::Ptr<Noesis::RemovePointer<typename NoesisTypeTraits<T>::NoesisType>>(*NoesisTypeTraits<T>::ToNoesis(TValue));
-}
-
-template<class T>
-bool GenericSetterPtr(Noesis::BaseComponent* Input, void* BasePointer, FProperty* Property)
-{
- void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
- T TInput = NoesisTypeTraits<T>::ToUnreal((typename NoesisTypeTraits<T>::NoesisType)Input);
- T& TValue = *(T*)Value;
- bool Changed = !NoesisTypeTraits<T>::Equals(TInput, TValue);
- TValue = TInput;
- return Changed;
-}
-
-template<class T>
-const Noesis::Type* GenericGetTypePtr(FProperty*)
-{
- return Noesis::TypeOf< Noesis::RemovePointer<typename NoesisTypeTraits<T>::NoesisType>>();
-}
-
typedef Noesis::Ptr<Noesis::BaseComponent>(*GetterFn)(void*, FProperty*);
typedef bool (*SetterFn)(Noesis::BaseComponent*, void*, FProperty*);
typedef const Noesis::Type* (*GetTypeFn)(FProperty*);
@@ -435,6 +414,10 @@
bool EnumSetter(Noesis::BaseComponent* Input, void* BasePointer, FProperty* Property)
{
+ auto Boxed = Noesis::DynamicCast<Noesis::Boxed<int32>*>(Input);
+ if (Boxed == nullptr)
+ return false;
+
void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
check(Property->IsA<FEnumProperty>());
int32 EnumInput = Noesis::Boxing::Unbox<int32>(Input);
@@ -473,6 +456,10 @@
bool ByteSetter(Noesis::BaseComponent* Input, void* BasePointer, FProperty* Property)
{
+ auto Boxed = Noesis::DynamicCast<Noesis::Boxed<int32>*>(Input);
+ if (Boxed == nullptr)
+ return false;
+
void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
check(Property->IsA<FByteProperty>());
int32 EnumInput = Noesis::Boxing::Unbox<int32>(Input);
@@ -593,7 +580,7 @@
bool ArraySetter(Noesis::BaseComponent* Input, void* BasePointer, FProperty* Property)
{
void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
- check(false);
+ UE_LOG(LogNoesis, Warning, TEXT("Setting TArrays is not supported"));
return false;
}
@@ -634,7 +621,7 @@
bool MapSetter(Noesis::BaseComponent* Input, void* BasePointer, FProperty* Property)
{
void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
- check(false);
+ UE_LOG(LogNoesis, Warning, TEXT("Setting TMaps is not supported"));
return false;
}
@@ -930,7 +917,15 @@
bool SetPropertyByRef(void* BasePointer, FProperty* Property, Noesis::BaseComponent* Input)
{
+ check(BasePointer != nullptr);
+ check(Property != nullptr);
+
FFieldClass* PropertyClass = Property->GetClass();
+
+ // Setting non object properties to null is invalid.
+ if (Input == nullptr && PropertyClass != FObjectProperty::StaticClass())
+ return false;
+
if (PropertyClass == FStructProperty::StaticClass())
{
FStructProperty* StructProperty = (FStructProperty*)Property;
@@ -3026,17 +3021,17 @@
bool AssignStruct(void* Dest, UScriptStruct* Struct, Noesis::BaseComponent* Value)
{
- check(Value->GetClassType()->IsDescendantOf(NoesisStructWrapper::StaticGetClassType(nullptr)));
+ if (!Value->GetClassType()->IsDescendantOf(NoesisStructWrapper::StaticGetClassType(nullptr)))
+ return false;
+
check(Noesis::DynamicCast<const NoesisTypeClass*>(Value->GetClassType()));
- if (((NoesisTypeClass*)Value->GetClassType())->Class == Struct)
- {
- NoesisStructWrapper* Wrapper = ((NoesisStructWrapper*)Value);
- bool Changed = !Struct->CompareScriptStruct(Dest, Wrapper->GetStructPtr(), PPF_None);
- Struct->CopyScriptStruct(Dest, Wrapper->GetStructPtr(), 1);
- return Changed;
- }
-
- return false;
+ if (((NoesisTypeClass*)Value->GetClassType())->Class != Struct)
+ return false;
+
+ NoesisStructWrapper* Wrapper = ((NoesisStructWrapper*)Value);
+ bool Changed = !Struct->CompareScriptStruct(Dest, Wrapper->GetStructPtr(), PPF_None);
+ Struct->CopyScriptStruct(Dest, Wrapper->GetStructPtr(), 1);
+ return Changed;
}
const Noesis::Type* NoesisGetTypeForUStruct(UStruct* Class)
@@ -3190,6 +3185,10 @@
NOESISRUNTIME_API UObject* NoesisCreateUObjectForComponent(Noesis::BaseComponent* Component)
{
+ // Don't create a UNoesisBaseComponent for null Components
+ if (Component == nullptr)
+ return nullptr;
+
NoesisObjectWrapper* Wrapper = Noesis::DynamicCast<NoesisObjectWrapper*>(Component);
if (Wrapper != nullptr)
{
| ||||
| Platform | Any | ||||
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2021-09-24 13:45 | hcpizzi | New Issue | |
| 2021-09-24 13:47 | hcpizzi | File Added: NoesisTypeClass.cpp.patch | |
| 2021-09-24 13:47 | hcpizzi | Note Added: 0007480 | |
| 2021-09-24 13:50 | jsantos | Target Version | => 3.1.2 |
| 2021-09-24 13:50 | jsantos | Assigned To | => hcpizzi |
| 2021-09-24 13:50 | jsantos | Status | new => assigned |
| 2021-09-24 13:55 | hcpizzi | File Deleted: NoesisTypeClass.cpp.patch | |
| 2021-09-24 14:00 | hcpizzi | File Added: NoesisTypeClass.cpp.patch | |
| 2021-12-10 15:14 | hcpizzi | Status | assigned => resolved |
| 2021-12-10 15:14 | hcpizzi | Resolution | open => fixed |
| 2021-12-10 15:14 | hcpizzi | Fixed in Version | => 3.1.2 |