Browse Source

fix StringDictionarySlim enumeration after first item delete (#677)

Marko Lahma 5 years ago
parent
commit
47fff2e5a5
2 changed files with 32 additions and 1 deletions
  1. 22 0
      Jint.Tests/Runtime/ObjectInstanceTests.cs
  2. 10 1
      Jint/Collections/StringDictionarySlim.cs

+ 22 - 0
Jint.Tests/Runtime/ObjectInstanceTests.cs

@@ -0,0 +1,22 @@
+using System.Linq;
+using Jint.Native;
+using Jint.Native.Object;
+using Xunit;
+
+namespace Jint.Tests.Runtime
+{
+    public class ObjectInstanceTests
+    {
+        [Fact]
+        public void RemovingFirstPropertyFromObjectInstancePropertiesBucketAndEnumerating()
+        {
+            var engine = new Engine();
+            var instance = new ObjectInstance(engine);
+            instance.FastAddProperty("bare", JsValue.Null, true, true, true);
+            instance.FastAddProperty("scope", JsValue.Null, true, true, true);
+            instance.RemoveOwnProperty("bare");
+            var propertyNames = instance.GetOwnProperties().Select(x => x.Key).ToList();
+            Assert.Equal(new [] { "scope" }, propertyNames);
+        }
+    }
+}

+ 10 - 1
Jint/Collections/StringDictionarySlim.cs

@@ -240,23 +240,30 @@ namespace Jint.Collections
         {
             private readonly StringDictionarySlim<TValue> _dictionary;
             private int _index;
+            private int _count;
             private KeyValuePair<string, TValue> _current;
 
             internal Enumerator(StringDictionarySlim<TValue> dictionary)
             {
                 _dictionary = dictionary;
                 _index = 0;
+                _count = _dictionary._count;
                 _current = default;
             }
 
             public bool MoveNext()
             {
-                if (_index == _dictionary._count)
+                if (_count == 0)
                 {
                     _current = default;
                     return false;
                 }
 
+                _count--;
+
+                while (_dictionary._entries[_index].next < -1)
+                    _index++;
+
                 _current = new KeyValuePair<string, TValue>(
                     _dictionary._entries[_index].key,
                     _dictionary._entries[_index++].value);
@@ -270,6 +277,8 @@ namespace Jint.Collections
             void IEnumerator.Reset()
             {
                 _index = 0;
+                _count = _dictionary._count;
+                _current = default;
             }
 
             public void Dispose() { }