Browse Source

Fixed: Calling Array.prototype.toString() with anything other than a real Array object throws a NullReferenceException (#641)

miroslav22 6 years ago
parent
commit
531037ab61
2 changed files with 54 additions and 0 deletions
  1. 50 0
      Jint.Tests/Runtime/ArrayTests.cs
  2. 4 0
      Jint/Native/Array/ArrayPrototype.cs

+ 50 - 0
Jint.Tests/Runtime/ArrayTests.cs

@@ -0,0 +1,50 @@
+using System;
+using Jint.Runtime;
+using Xunit;
+
+namespace Jint.Tests.Runtime
+{
+    public class ArrayTests
+    {
+        private readonly Engine _engine;
+
+        public ArrayTests()
+        {
+            _engine = new Engine()
+                    .SetValue("log", new Action<object>(Console.WriteLine))
+                    .SetValue("assert", new Action<bool>(Assert.True))
+                    .SetValue("equal", new Action<object, object>(Assert.Equal));
+        }
+
+        private void RunTest(string source)
+        {
+            _engine.Execute(source);
+        }
+
+
+        [Fact]
+        public void ArrayPrototypeToStringWithArray()
+        {
+            var result = _engine.Execute("Array.prototype.toString.call([1,2,3]);").GetCompletionValue().AsString();
+
+            Assert.Equal("1,2,3", result);
+        }
+
+        [Fact]
+        public void ArrayPrototypeToStringWithNumber()
+        {
+            var result = _engine.Execute("Array.prototype.toString.call(1);").GetCompletionValue().AsString();
+
+            Assert.Equal("[object Number]", result);
+        }
+
+        [Fact]
+        public void ArrayPrototypeToStringWithObject()
+        {
+            var result = _engine.Execute("Array.prototype.toString.call({});").GetCompletionValue().AsString();
+
+            Assert.Equal("[object Object]", result);
+        }
+
+    }
+}

+ 4 - 0
Jint/Native/Array/ArrayPrototype.cs

@@ -1141,12 +1141,16 @@ namespace Jint.Native.Array
         private JsValue ToString(JsValue thisObj, JsValue[] arguments)
         {
             var array = TypeConverter.ToObject(Engine, thisObj);
+
             ICallable func;
             func = array.Get("join").TryCast<ICallable>(x =>
             {
                 func = Engine.Object.PrototypeObject.Get("toString").TryCast<ICallable>(y => ExceptionHelper.ThrowArgumentException());
             });
 
+            if (array.IsArrayLike == false || func == null)
+                return _engine.Object.PrototypeObject.ToObjectString(array, Arguments.Empty);
+
             return func.Call(array, Arguments.Empty);
         }