Skip to content

Commit

Permalink
Added extra validation to several parts of the reflection code
Browse files Browse the repository at this point in the history
  • Loading branch information
hcpizzi committed Sep 28, 2021
1 parent ac6b59c commit 7189ee1
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 78 deletions.
17 changes: 9 additions & 8 deletions Source/NoesisEditor/Private/NoesisEditorModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,20 @@ void OnObjectImported(UFactory* ImportFactory, UObject* InObject)
PremultiplyAlpha(Texture);
}
}
Noesis::Ptr<Noesis::BaseComponent> Component = NoesisFindComponentForUObject(Texture);
if (Component != nullptr)
Noesis::Ptr<Noesis::TextureSource> TextureSource = Noesis::StaticPtrCast<Noesis::TextureSource>(NoesisFindComponentForUObject(Texture));
if (TextureSource != nullptr)
{
Noesis::TextureSource* TextureSource = (Noesis::TextureSource*)Component.GetPtr();
TextureSource->SetTexture(NoesisCreateTexture(Texture).GetPtr());
TextureSource->SetTexture(NoesisCreateTexture(Texture));
}
INoesisRuntimeModuleInterface::Get().OnTextureChanged(Texture);
}
}

void OnObjectPropertyChanged(UObject* Object, struct FPropertyChangedEvent& Event)
{
if (!IsValid(Object)) // Don't think this is possible, but better safe than sorry
return;

static uint32 ReentryGuard = 0;
if (!ReentryGuard)
{
Expand Down Expand Up @@ -154,11 +156,10 @@ void OnObjectPropertyChanged(UObject* Object, struct FPropertyChangedEvent& Even
}
}
}
Noesis::Ptr<Noesis::BaseComponent> Component = NoesisFindComponentForUObject(Texture);
if (Component != nullptr)
Noesis::Ptr<Noesis::TextureSource> TextureSource = Noesis::StaticPtrCast<Noesis::TextureSource>(NoesisFindComponentForUObject(Texture));
if (TextureSource != nullptr)
{
Noesis::TextureSource* TextureSource = (Noesis::TextureSource*)Component.GetPtr();
TextureSource->SetTexture(NoesisCreateTexture(Texture).GetPtr());
TextureSource->SetTexture(NoesisCreateTexture(Texture));
}
INoesisRuntimeModuleInterface::Get().OnTextureChanged(Texture);
}
Expand Down
3 changes: 1 addition & 2 deletions Source/NoesisEditor/Private/NoesisXamlFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,8 +536,7 @@ UObject* UNoesisXamlFactory::FactoryCreateBinary(UClass* Class, UObject* Parent,
Noesis::Factory::RegisterComponent(LocTableType->GetTypeId(), Noesis::Symbol::Null(), CreateLocTable);

// Show parsing errors in the console
Noesis::Ptr<Noesis::BaseComponent> Ptr = NoesisXaml->LoadXaml();
Noesis::IUITreeNode* Root = Noesis::DynamicCast<Noesis::IUITreeNode*>(Ptr.GetPtr());
Noesis::Ptr<Noesis::IUITreeNode> Root = Noesis::DynamicPtrCast<Noesis::IUITreeNode>(NoesisXaml->LoadXaml());

NoesisXaml->Texts.Empty();
for (auto Text : UnrealTexts.FindOrAdd(Root))
Expand Down
5 changes: 3 additions & 2 deletions Source/NoesisRuntime/Private/NoesisFunctionLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ void UNoesisFunctionLibrary::TrySetDataContext(UObject* Element, UObject* DataCo
UNoesisBaseComponent* BaseComponent = Cast<UNoesisBaseComponent>(Element);
if (BaseComponent)
{
Noesis::FrameworkElement* NoesisElement = Noesis::DynamicCast<Noesis::FrameworkElement*>(BaseComponent->NoesisComponent.GetPtr());
// OK to demote Ptr to *. The reference is kept by the UNoesisBaseComponent.
Noesis::FrameworkElement* NoesisElement = Noesis::DynamicPtrCast<Noesis::FrameworkElement>(BaseComponent->NoesisComponent);

if (NoesisElement)
{
Expand All @@ -53,7 +54,7 @@ UObject* UNoesisFunctionLibrary::LoadXaml(class UNoesisXaml* Xaml)
{
if (Xaml != nullptr)
{
return NoesisCreateUObjectForComponent(Xaml->LoadXaml().GetPtr());
return NoesisCreateUObjectForComponent(Xaml->LoadXaml());
}
return nullptr;
}
Expand Down
8 changes: 4 additions & 4 deletions Source/NoesisRuntime/Private/NoesisInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,15 +280,15 @@ void UNoesisInstance::InitInstance()

Noesis::Ptr<Noesis::BaseComponent> DataContext = Noesis::Ptr<Noesis::BaseComponent>(NoesisCreateComponentForUObject(this));

Xaml.Reset(Noesis::DynamicCast<Noesis::FrameworkElement*>(BaseXaml->LoadXaml().GetPtr()));
Xaml = Noesis::DynamicPtrCast<Noesis::FrameworkElement>(BaseXaml->LoadXaml());

if (Xaml)
{
Xaml->SetDataContext(DataContext.GetPtr());
Xaml->SetDataContext(DataContext);

XamlLoaded();

XamlView = Noesis::GUI::CreateView(Xaml.GetPtr());
XamlView = Noesis::GUI::CreateView(Xaml);

if (XamlView)
{
Expand Down Expand Up @@ -318,7 +318,7 @@ void UNoesisInstance::SetDataContext(UObject* InDataContext)
{
Noesis::Ptr<Noesis::BaseComponent> DataContext = Noesis::Ptr<Noesis::BaseComponent>(NoesisCreateComponentForUObject(InDataContext));

Xaml->SetDataContext(DataContext.GetPtr());
Xaml->SetDataContext(DataContext);
}
}

Expand Down
4 changes: 2 additions & 2 deletions Source/NoesisRuntime/Private/NoesisRuntimeModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,15 @@ void OnTouchUpShowTextBoxVirtualKeyboard(Noesis::BaseComponent*, const Noesis::T
{
if (LastSelectedTextBox)
{
ShowTextBoxVirtualKeyboard(LastSelectedTextBox.GetPtr());
ShowTextBoxVirtualKeyboard(LastSelectedTextBox);
}
}

void OnTouchUpShowPasswordBoxVirtualKeyboard(Noesis::BaseComponent*, const Noesis::TouchEventArgs&)
{
if (LastSelectedPasswordBox)
{
ShowPasswordBoxVirtualKeyboard(LastSelectedPasswordBox.GetPtr());
ShowPasswordBoxVirtualKeyboard(LastSelectedPasswordBox);
}
}

Expand Down
126 changes: 67 additions & 59 deletions Source/NoesisRuntime/Private/NoesisTypeClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Noesis::Ptr<Noesis::BaseComponent> NoesisCreateComponentForTMap(void* MapPtr, FM
Noesis::Ptr<Noesis::BaseComponent> NoesisCreateComponentForTMapStruct(void* MapPtr, FMapProperty* MapProperty, void* StructPtr);
const Noesis::Type* NoesisCreateTypeForTMap(FMapProperty* MapProperty);
bool AssignStruct(void*, UScriptStruct*, Noesis::BaseComponent*);
bool AssignEnum(void*, UEnum*, FNumericProperty*, Noesis::BaseComponent*);
const Noesis::Type* NoesisGetTypeForUClass(UClass*);
const Noesis::Type* NoesisGetTypeForUStruct(UStruct*);
Noesis::TypeClass* NoesisCreateTypeClassForUMaterial(UMaterialInterface* Material);
Expand Down Expand Up @@ -339,6 +340,10 @@ Noesis::Ptr<Noesis::BaseComponent> GenericGetter(void* BasePointer, FProperty* P
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;
Expand All @@ -353,31 +358,6 @@ const Noesis::Type* GenericGetType(FProperty*)
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*);
Expand Down Expand Up @@ -424,9 +404,9 @@ const Noesis::Type* StructGetType(FProperty* Property)

Noesis::Ptr<Noesis::BaseComponent> EnumGetter(void* BasePointer, FProperty* Property)
{
void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
check(Property->IsA<FEnumProperty>());
FEnumProperty* EnumProperty = (FEnumProperty*)Property;
void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
FNumericProperty* UnderlyingProperty = EnumProperty->GetUnderlyingProperty();
check(UnderlyingProperty->IsInteger());
int64 IntValue = UnderlyingProperty->GetSignedIntPropertyValue(Value);
Expand All @@ -435,16 +415,12 @@ Noesis::Ptr<Noesis::BaseComponent> EnumGetter(void* BasePointer, FProperty* Prop

bool EnumSetter(Noesis::BaseComponent* Input, void* BasePointer, FProperty* Property)
{
void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
check(Property->IsA<FEnumProperty>());
int32 EnumInput = Noesis::Boxing::Unbox<int32>(Input);
FEnumProperty* EnumProperty = (FEnumProperty*)Property;
void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
FNumericProperty* UnderlyingProperty = EnumProperty->GetUnderlyingProperty();
check(UnderlyingProperty->IsInteger());
int64 IntValue = UnderlyingProperty->GetSignedIntPropertyValue(Value);
bool Changed = ((int64)EnumInput != IntValue);
UnderlyingProperty->SetIntPropertyValue(Value, (int64)EnumInput);
return Changed;
return AssignEnum(Value, EnumProperty->GetEnum(), UnderlyingProperty, Input);
}

const Noesis::Type* EnumGetType(FProperty* Property)
Expand All @@ -458,9 +434,8 @@ Noesis::Ptr<Noesis::BaseComponent> ByteGetter(void* BasePointer, FProperty* Prop
{
check(Property->IsA<FByteProperty>());
FByteProperty* ByteProperty = (FByteProperty*)Property;
if (ByteProperty->Enum)
if (ByteProperty->Enum != nullptr)
{
//Noesis::TypeEnum* TypeEnum = NoesisCreateTypeEnumForUEnum(ByteProperty->Enum);
void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
uint8& ByteValue = *(uint8*)Value;
return NoesisCreateComponentForUEnum(ByteProperty->Enum, (int64)ByteValue);
Expand All @@ -473,21 +448,24 @@ Noesis::Ptr<Noesis::BaseComponent> ByteGetter(void* BasePointer, FProperty* Prop

bool ByteSetter(Noesis::BaseComponent* Input, void* BasePointer, FProperty* Property)
{
void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
check(Property->IsA<FByteProperty>());
int32 EnumInput = Noesis::Boxing::Unbox<int32>(Input);
FByteProperty* ByteProperty = (FByteProperty*)Property;
int64 IntValue = ByteProperty->GetSignedIntPropertyValue(Value);
bool Changed = ((int64)EnumInput != IntValue);
ByteProperty->SetIntPropertyValue(Value, (int64)EnumInput);
return Changed;
if (ByteProperty->Enum != nullptr)
{
void* Value = Property->template ContainerPtrToValuePtr<void>(BasePointer);
return AssignEnum(Value, ByteProperty->Enum, ByteProperty, Input);
}
else
{
return GenericSetter<uint8>(Input, BasePointer, Property);
}
}

const Noesis::Type* ByteGetType(FProperty* Property)
{
check(Property->IsA<FByteProperty>());
FByteProperty* ByteProperty = (FByteProperty*)Property;
if (ByteProperty->Enum)
if (ByteProperty->Enum != nullptr)
{
return NoesisCreateTypeEnumForUEnum(ByteProperty->Enum);
}
Expand Down Expand Up @@ -593,7 +571,7 @@ Noesis::Ptr<Noesis::BaseComponent> ArrayGetter(void* BasePointer, FProperty* Pro
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;
}

Expand Down Expand Up @@ -634,7 +612,7 @@ Noesis::Ptr<Noesis::BaseComponent> MapGetter(void* BasePointer, FProperty* Prope
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;
}

Expand Down Expand Up @@ -930,7 +908,15 @@ Noesis::Ptr<Noesis::BaseComponent> GetPropertyByRef(void* BasePointer, FProperty

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;
Expand Down Expand Up @@ -1246,7 +1232,7 @@ class NoesisArrayWrapper : public Noesis::BaseComponent, public Noesis::IList, p

// Preserve this in case it is deleted in the event handler
LOCAL_PRESERVE(this);
Noesis::NotifyCollectionChangedEventArgs CollectionChangedArgs = { Noesis::NotifyCollectionChangedAction_Add, -1, (int32)Index, nullptr, Item.GetPtr() };
Noesis::NotifyCollectionChangedEventArgs CollectionChangedArgs = { Noesis::NotifyCollectionChangedAction_Add, -1, (int32)Index, nullptr, Item };
CollectionChangedHandler(this, CollectionChangedArgs);
}

Expand All @@ -1263,7 +1249,7 @@ class NoesisArrayWrapper : public Noesis::BaseComponent, public Noesis::IList, p

// Preserve this in case it is deleted in the event handler
LOCAL_PRESERVE(this);
Noesis::NotifyCollectionChangedEventArgs CollectionChangedArgs = { Noesis::NotifyCollectionChangedAction_Replace, (int32)Index, (int32)Index, ItemToDelete.GetPtr(), NewItem.GetPtr() };
Noesis::NotifyCollectionChangedEventArgs CollectionChangedArgs = { Noesis::NotifyCollectionChangedAction_Replace, (int32)Index, (int32)Index, ItemToDelete, NewItem };
CollectionChangedHandler(this, CollectionChangedArgs);
ItemToDelete.Reset();
}
Expand All @@ -1284,7 +1270,7 @@ class NoesisArrayWrapper : public Noesis::BaseComponent, public Noesis::IList, p
check(ItemToDelete != nullptr);
// Preserve this in case it is deleted in the event handler
LOCAL_PRESERVE(this);
Noesis::NotifyCollectionChangedEventArgs CollectionChangedArgs = { Noesis::NotifyCollectionChangedAction_Remove, Index, -1, ItemToDelete.GetPtr(), nullptr };
Noesis::NotifyCollectionChangedEventArgs CollectionChangedArgs = { Noesis::NotifyCollectionChangedAction_Remove, Index, -1, ItemToDelete, nullptr };
CollectionChangedHandler(this, CollectionChangedArgs);
ItemToDelete.Reset();
}
Expand Down Expand Up @@ -1431,7 +1417,7 @@ class NoesisMapWrapper : public Noesis::BaseComponent, public Noesis::IDictionar
{
Noesis::Ptr<Noesis::BaseComponent> Item;
NativeFind(Key, Item);
Noesis::NotifyDictionaryChangedEventArgs DictionaryChangedArgs = { Noesis::NotifyDictionaryChangedAction_Add, Key, nullptr, Item.GetPtr() };
Noesis::NotifyDictionaryChangedEventArgs DictionaryChangedArgs = { Noesis::NotifyDictionaryChangedAction_Add, Key, nullptr, Item };
DictionaryChangedHandler(this, DictionaryChangedArgs);
}

Expand All @@ -1452,7 +1438,7 @@ class NoesisMapWrapper : public Noesis::BaseComponent, public Noesis::IDictionar
check(ItemToDelete != nullptr);
// Preserve this in case it is deleted in the event handler
LOCAL_PRESERVE(this);
Noesis::NotifyDictionaryChangedEventArgs DictionaryChangedArgs = { Noesis::NotifyDictionaryChangedAction_Add, Key, ItemToDelete.GetPtr(), nullptr };
Noesis::NotifyDictionaryChangedEventArgs DictionaryChangedArgs = { Noesis::NotifyDictionaryChangedAction_Add, Key, ItemToDelete, nullptr };
DictionaryChangedHandler(this, DictionaryChangedArgs);
ItemToDelete = nullptr;
}
Expand Down Expand Up @@ -3024,19 +3010,37 @@ void NoesisAssetRenamed(UObject* Object, FString OldPath)
}
#endif

bool AssignStruct(void* Dest, UScriptStruct* Struct, Noesis::BaseComponent* Value)
bool AssignStruct(void* Value, UScriptStruct* Struct, Noesis::BaseComponent* Input)
{
check(Value->GetClassType()->IsDescendantOf(NoesisStructWrapper::StaticGetClassType(nullptr)));
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;
}
if (!Input->GetClassType()->IsDescendantOf(NoesisStructWrapper::StaticGetClassType(nullptr)))
return false;

return false;
check(Noesis::DynamicCast<const NoesisTypeClass*>(Input->GetClassType()));
if (((NoesisTypeClass*)Input->GetClassType())->Class != Struct)
return false;

NoesisStructWrapper* Wrapper = ((NoesisStructWrapper*)Input);
bool Changed = !Struct->CompareScriptStruct(Value, Wrapper->GetStructPtr(), PPF_None);
Struct->CopyScriptStruct(Value, Wrapper->GetStructPtr(), 1);
return Changed;
}

bool AssignEnum(void* Value, UEnum* Enum, FNumericProperty* ValueProperty, Noesis::BaseComponent* Input)
{
NoesisEnumWrapper* Wrapper = Noesis::DynamicCast<NoesisEnumWrapper*>(Input);
if (Wrapper == nullptr)
return false;

const Noesis::Type* TypeEnum = Wrapper->GetValueType();
check(Noesis::DynamicCast<const NoesisTypeEnum*>(TypeEnum));
if (((NoesisTypeEnum*)TypeEnum)->Enum != Enum)
return false;

int64 InputValue = (int64)Noesis::Boxing::Unbox<int32>(Input);
int64 IntValue = ValueProperty->GetSignedIntPropertyValue(Value);
bool Changed = (InputValue != IntValue);
ValueProperty->SetIntPropertyValue(Value, InputValue);
return Changed;
}

const Noesis::Type* NoesisGetTypeForUStruct(UStruct* Class)
Expand Down Expand Up @@ -3190,6 +3194,10 @@ NOESISRUNTIME_API Noesis::Ptr<Noesis::BaseComponent> NoesisCreateComponentForUOb

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)
{
Expand Down
2 changes: 1 addition & 1 deletion Source/NoesisRuntime/Private/Render/NoesisRenderDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class FNoesisRenderTarget : public Noesis::RenderTarget
// RenderTarget interface
virtual Noesis::Texture* GetTexture() override
{
return Texture.GetPtr();
return Texture;
}
// End of RenderTarget interface

Expand Down

0 comments on commit 7189ee1

Please sign in to comment.