From 8ffb69cfbd8b633ecb706191ff41c8a8498e2bbd Mon Sep 17 00:00:00 2001 From: Mike Spertus Date: Sun, 22 Sep 2024 21:10:18 -0500 Subject: [PATCH 1/2] Address Interop having difficulty finding properties in derived types #1968 --- Jint.Tests/Runtime/InteropTests.cs | 41 +++++++++++++++++++++++++++ Jint/Runtime/Interop/ObjectWrapper.cs | 4 +++ 2 files changed, 45 insertions(+) diff --git a/Jint.Tests/Runtime/InteropTests.cs b/Jint.Tests/Runtime/InteropTests.cs index 8f383e985..3655bc3d0 100644 --- a/Jint.Tests/Runtime/InteropTests.cs +++ b/Jint.Tests/Runtime/InteropTests.cs @@ -3624,4 +3624,45 @@ public void StringifyShouldIncludeInheritedFieldsAndProperties() engine.SetValue("c", new Circle(12.34)); engine.Evaluate("JSON.stringify(c)").ToString().Should().Be("{\"Radius\":12.34,\"Color\":0,\"Id\":123}"); } + + public class Animal + { + public virtual string name { get; set; } = "animal"; + } + + public class Elephant : Animal + { + public override string name { get; set; } = "elephant"; + public int earSize = 5; + } + + public class Lion : Animal + { + public override string name { get; set; } = "lion"; + public int maneLength = 10; + } + + public class Zoo + { + public Animal king { get => (new Animal[] { new Lion() })[0]; } + public Animal[] animals { get => new Animal[] { new Lion(), new Elephant() }; } + } + + [Fact] + public void CanFindDerivedPropertiesFail() // Fails in 4.01 but success in 2.11 + { + var engine = new Engine(); + engine.SetValue("zoo", new Zoo()); + var kingManeLength = engine.Evaluate("zoo.King.maneLength"); + Assert.Equal(10, kingManeLength.AsNumber()); + } + + [Fact] + public void CanFindDerivedPropertiesSucceed() // Similar case that continues to succeed + { + var engine = new Engine(); + engine.SetValue("zoo", new Zoo()); + var lionManeLength = engine.Evaluate("zoo.animals[0].maneLength"); + Assert.Equal(10, lionManeLength.AsNumber()); + } } diff --git a/Jint/Runtime/Interop/ObjectWrapper.cs b/Jint/Runtime/Interop/ObjectWrapper.cs index 6a53056ff..f664cec07 100644 --- a/Jint/Runtime/Interop/ObjectWrapper.cs +++ b/Jint/Runtime/Interop/ObjectWrapper.cs @@ -364,6 +364,10 @@ private PropertyDescriptor GetOwnProperty(JsValue property, bool mustBeReadable, } var accessor = _engine.Options.Interop.TypeResolver.GetAccessor(_engine, ClrType, member, mustBeReadable, mustBeWritable); + if (accessor == ConstantValueAccessor.NullAccessor) + { + accessor = _engine.Options.Interop.TypeResolver.GetAccessor(_engine, Target.GetType(), member, mustBeReadable, mustBeWritable); + } var descriptor = accessor.CreatePropertyDescriptor(_engine, Target, member, enumerable: !isDictionary); if (!isDictionary && !ReferenceEquals(descriptor, PropertyDescriptor.Undefined) From c3ffe0572df9238754d8bf916be1c763e9746384 Mon Sep 17 00:00:00 2001 From: Mike Spertus Date: Mon, 23 Sep 2024 11:18:45 -0500 Subject: [PATCH 2/2] Made requested change --- Jint/Runtime/Interop/ObjectWrapper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jint/Runtime/Interop/ObjectWrapper.cs b/Jint/Runtime/Interop/ObjectWrapper.cs index f664cec07..adb0c50ab 100644 --- a/Jint/Runtime/Interop/ObjectWrapper.cs +++ b/Jint/Runtime/Interop/ObjectWrapper.cs @@ -364,7 +364,7 @@ private PropertyDescriptor GetOwnProperty(JsValue property, bool mustBeReadable, } var accessor = _engine.Options.Interop.TypeResolver.GetAccessor(_engine, ClrType, member, mustBeReadable, mustBeWritable); - if (accessor == ConstantValueAccessor.NullAccessor) + if (accessor == ConstantValueAccessor.NullAccessor && ClrType != Target.GetType()) { accessor = _engine.Options.Interop.TypeResolver.GetAccessor(_engine, Target.GetType(), member, mustBeReadable, mustBeWritable); }