Prevent Unity crashing on PropertyInfo evaluation

Unity crashes from checking Canvas.renderingDisplaySize on a Canvas set to WorldSpace with no worldCamera set.
This commit is contained in:
Sinai 2022-02-19 17:50:10 +11:00
parent d0bccae50c
commit a90292f47f
5 changed files with 36 additions and 8 deletions

View File

@ -21,7 +21,7 @@ namespace UnityExplorer.CacheObject
{ {
public abstract Type DeclaringType { get; } public abstract Type DeclaringType { get; }
public string NameForFiltering { get; protected set; } public string NameForFiltering { get; protected set; }
public object DeclaringInstance => IsStatic ? null : (m_declaringInstance ?? (m_declaringInstance = Owner.Target.TryCast(DeclaringType))); public object DeclaringInstance => IsStatic ? null : (m_declaringInstance ??= Owner.Target.TryCast(DeclaringType));
private object m_declaringInstance; private object m_declaringInstance;
public abstract bool IsStatic { get; } public abstract bool IsStatic { get; }
@ -94,8 +94,8 @@ namespace UnityExplorer.CacheObject
base.SetValueState(cell, args); base.SetValueState(cell, args);
} }
private static readonly Color evalEnabledColor = new Color(0.15f, 0.25f, 0.15f); private static readonly Color evalEnabledColor = new(0.15f, 0.25f, 0.15f);
private static readonly Color evalDisabledColor = new Color(0.15f, 0.15f, 0.15f); private static readonly Color evalDisabledColor = new(0.15f, 0.15f, 0.15f);
protected override bool TryAutoEvaluateIfUnitialized(CacheObjectCell objectcell) protected override bool TryAutoEvaluateIfUnitialized(CacheObjectCell objectcell)
{ {
@ -242,7 +242,7 @@ namespace UnityExplorer.CacheObject
var sig = GetSig(member); var sig = GetSig(member);
//ExplorerCore.Log($"Trying to cache member {sig}... ({member.MemberType})"); // ExplorerCore.Log($"Trying to cache member {sig}... ({member.MemberType})");
CacheMember cached; CacheMember cached;
Type returnType; Type returnType;

View File

@ -3,7 +3,9 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using UnityEngine;
using UnityExplorer.Inspectors; using UnityExplorer.Inspectors;
using UnityExplorer.Runtime;
namespace UnityExplorer.CacheObject namespace UnityExplorer.CacheObject
{ {
@ -28,6 +30,8 @@ namespace UnityExplorer.CacheObject
{ {
try try
{ {
UnityCrashPrevention.CheckPropertyInfoEvaluation(this);
object ret; object ret;
if (HasArguments) if (HasArguments)
ret = PropertyInfo.GetValue(DeclaringInstance, this.Evaluator.TryParseArguments()); ret = PropertyInfo.GetValue(DeclaringInstance, this.Evaluator.TryParseArguments());

View File

@ -18,7 +18,7 @@ namespace UnityExplorer
{ {
public static class InspectorManager public static class InspectorManager
{ {
public static readonly List<InspectorBase> Inspectors = new List<InspectorBase>(); public static readonly List<InspectorBase> Inspectors = new();
public static InspectorBase ActiveInspector { get; private set; } public static InspectorBase ActiveInspector { get; private set; }
private static InspectorBase lastActiveInspector; private static InspectorBase lastActiveInspector;
@ -94,17 +94,17 @@ namespace UnityExplorer
} }
private static void CreateInspector<T>(object target, bool staticReflection = false, private static void CreateInspector<T>(object target, bool staticReflection = false,
CacheObjectBase sourceCache = null) where T : InspectorBase CacheObjectBase parentObject = null) where T : InspectorBase
{ {
var inspector = Pool<T>.Borrow(); var inspector = Pool<T>.Borrow();
Inspectors.Add(inspector); Inspectors.Add(inspector);
inspector.Target = target; inspector.Target = target;
if (sourceCache != null && sourceCache.CanWrite) if (parentObject != null && parentObject.CanWrite)
{ {
// only set parent cache object if we are inspecting a struct, otherwise there is no point. // only set parent cache object if we are inspecting a struct, otherwise there is no point.
if (target.GetType().IsValueType && inspector is ReflectionInspector ri) if (target.GetType().IsValueType && inspector is ReflectionInspector ri)
ri.ParentCacheObject = sourceCache; ri.ParentCacheObject = parentObject;
} }
UIManager.SetPanelActive(UIManager.Panels.Inspector, true); UIManager.SetPanelActive(UIManager.Panels.Inspector, true);

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityExplorer.CacheObject;
namespace UnityExplorer.Runtime
{
public static class UnityCrashPrevention
{
public static void CheckPropertyInfoEvaluation(CacheProperty cacheProp)
{
if (cacheProp.PropertyInfo.Name == "renderingDisplaySize"
&& cacheProp.Owner.Target is Canvas canvas
&& canvas.renderMode == RenderMode.WorldSpace
&& !canvas.worldCamera)
{
throw new Exception("Canvas is set to RenderMode.WorldSpace but has no worldCamera, cannot get value.");
}
}
}
}

View File

@ -259,6 +259,7 @@
<Compile Include="CacheObject\Views\CacheListEntryCell.cs" /> <Compile Include="CacheObject\Views\CacheListEntryCell.cs" />
<Compile Include="CacheObject\Views\CacheMemberCell.cs" /> <Compile Include="CacheObject\Views\CacheMemberCell.cs" />
<Compile Include="CacheObject\Views\CacheObjectCell.cs" /> <Compile Include="CacheObject\Views\CacheObjectCell.cs" />
<Compile Include="Runtime\UnityCrashPrevention.cs" />
<Compile Include="UI\DisplayManager.cs" /> <Compile Include="UI\DisplayManager.cs" />
<Compile Include="UI\Notification.cs" /> <Compile Include="UI\Notification.cs" />
<Compile Include="UI\Panels\ClipboardPanel.cs" /> <Compile Include="UI\Panels\ClipboardPanel.cs" />