Browse Source

Fix iterating a CLR list proxy and length property under interop (#2151)

Co-authored-by: Martin Burtscher <[email protected]>
Martin Burtscher 3 days ago
parent
commit
c83b62931f
2 changed files with 47 additions and 1 deletions
  1. 41 1
      Jint.Tests/Runtime/ProxyTests.cs
  2. 6 0
      Jint/Runtime/Interop/ObjectWrapper.cs

+ 41 - 1
Jint.Tests/Runtime/ProxyTests.cs

@@ -234,6 +234,8 @@ public class ProxyTests
         public int IntValue => 42424242; // avoid small numbers cache
         public TestClass ObjectWrapper => Instance;
 
+        public List<int> IntList { get; } = [1, 2, 3];
+
         private int x = 1;
         public int PropertySideEffect => x++;
 
@@ -455,7 +457,7 @@ public class ProxyTests
         Assert.Equal(2, TestClass.Instance.PropertySideEffect); // second call to PropertySideEffect
     }
 
-   [Fact]
+    [Fact]
     public void ToObjectReturnsProxiedToObject()
     {
         _engine
@@ -482,4 +484,42 @@ public class ProxyTests
              """);
 
     }
+
+    [Fact]
+    public void ProxyIterateClrList()
+    {
+        var res = _engine
+            .SetValue("obj", TestClass.Instance)
+            .Evaluate("""
+                //const obj = {
+                //    IntList: [1, 2, 3]
+                //};
+
+                const objProxy = new Proxy(obj, {
+                  get(target, prop, receiver) {
+                    const targetValue = Reflect.get(target, prop, receiver);
+                    if (prop == 'IntList') {
+                        return new Proxy(targetValue, {
+                            get(target, prop, receiver) {
+                                return Reflect.get(target, prop, receiver);            
+                            }
+                        });
+                    }
+
+                    return targetValue;
+                  }
+                });
+
+                const arr = []
+                for (const item of objProxy.IntList)
+                {
+                    arr.push(item);
+                }
+                arr.push(objProxy.IntList.length)
+
+                return arr;
+            """);
+
+        Assert.Equal([1, 2, 3, 3], res.AsArray());
+    }
 }

+ 6 - 0
Jint/Runtime/Interop/ObjectWrapper.cs

@@ -464,6 +464,9 @@ public class ObjectWrapper : ObjectInstance, IObjectWrapper, IEquatable<ObjectWr
 
     private static JsValue Iterator(JsValue thisObject, JsCallArguments arguments)
     {
+        if (thisObject is JsProxy proxy)
+            return Iterator(proxy._target, arguments);
+
         var wrapper = (ObjectWrapper) thisObject;
 
         return wrapper._typeDescriptor.IsDictionary
@@ -473,6 +476,9 @@ public class ObjectWrapper : ObjectInstance, IObjectWrapper, IEquatable<ObjectWr
 
     private static JsNumber GetLength(JsValue thisObject, JsCallArguments arguments)
     {
+        if (thisObject is JsProxy proxy)
+            return GetLength(proxy._target, arguments);
+
         var wrapper = (ObjectWrapper) thisObject;
         return JsNumber.Create((int) (wrapper._typeDescriptor.LengthProperty?.GetValue(wrapper.Target) ?? 0));
     }