Calling Pin on a 0-length memory shouldn't throw. Adding tests.
authorahsonkhan <ahson_ahmedk@yahoo.com>
Sat, 20 Jan 2018 02:30:08 +0000 (18:30 -0800)
committerahsonkhan <ahson_ahmedk@yahoo.com>
Sat, 20 Jan 2018 02:30:08 +0000 (18:30 -0800)
Commit migrated from https://github.com/dotnet/corefx/commit/c2055307117b2f89a76b2ffc16d93322530ffb62

src/libraries/Common/tests/System/Buffers/NativeOwnedMemory.cs
src/libraries/System.Memory/tests/Memory/CustomMemoryForTest.cs
src/libraries/System.Memory/tests/Memory/OwnedMemory.cs
src/libraries/System.Memory/tests/Memory/Retain.cs
src/libraries/System.Memory/tests/ReadOnlyMemory/Retain.cs

index 9ae39d8..b734ee6 100644 (file)
@@ -55,7 +55,7 @@ namespace System.Buffers
 
         public override unsafe MemoryHandle Pin(int offset = 0)
         {
-            if (offset < 0 || offset >= _length) throw new ArgumentOutOfRangeException(nameof(offset));
+            if (offset < 0 || (_length > 0 && offset >= _length)) throw new ArgumentOutOfRangeException(nameof(offset));
             void* pointer = (void*)((byte*)_ptr + offset);
             return new MemoryHandle(this, pointer);
         }
index c90c0ce..30ccfba 100644 (file)
@@ -44,7 +44,7 @@ namespace System.MemoryTests
             unsafe
             {
                 Retain();
-                if (offset < 0 || offset >= _array.Length) throw new ArgumentOutOfRangeException(nameof(offset));
+                if (offset < 0 || (_array.Length > 0 && offset >= _array.Length)) throw new ArgumentOutOfRangeException(nameof(offset));
                 var handle = GCHandle.Alloc(_array, GCHandleType.Pinned);
                 return new MemoryHandle(this, Unsafe.Add<byte>((void*)handle.AddrOfPinnedObject(), offset), handle);
             }
index 42c409f..e1249ed 100644 (file)
@@ -86,6 +86,36 @@ namespace System.MemoryTests
             owner.Dispose();
             Assert.True(owner.IsDisposed);
         }
+        
+        [Fact]
+        public static void OwnedMemoryPinEmptyArray()
+        {
+            int[] a = {};
+            OwnedMemory<int> owner = new CustomMemoryForTest<int>(a);
+            MemoryHandle handle = owner.Pin();
+            Assert.True(handle.HasPointer);
+        }
+
+        [Fact]
+        public static void OwnedMemoryPinArray()
+        {
+            int[] array = { 1, 2, 3, 4, 5 };
+            OwnedMemory<int> owner = new CustomMemoryForTest<int>(array);
+            MemoryHandle handle = owner.Pin();
+            Assert.True(handle.HasPointer);
+            unsafe
+            {
+                int* pointer = (int*)handle.Pointer;
+
+                GC.Collect();
+
+                for (int i = 0; i < owner.Memory.Length; i++)
+                {
+                    Assert.Equal(array[i], pointer[i]);
+                }
+            }
+            handle.Dispose();
+        }
 
         [Fact]
         public static void MemoryFromOwnedMemoryAfterDispose()
index c9bae90..4286685 100644 (file)
@@ -111,6 +111,23 @@ namespace System.MemoryTests
         }
 
         [Fact]
+        public static void MemoryFromEmptyArrayRetainWithPinning()
+        {
+            Memory<int> memory = new int[0];
+            MemoryHandle handle = memory.Retain(pin: true);
+            Assert.True(handle.HasPointer);
+            unsafe
+            {
+                int* pointer = (int*)handle.Pointer;
+
+                GC.Collect();
+
+                Assert.True(pointer != null);
+            }
+            handle.Dispose();
+        }
+
+        [Fact]
         public static void OwnedMemoryRetainWithPinningAndSlice()
         {
             int[] array = { 1, 2, 3, 4, 5 };
index e519e4a..3862111 100644 (file)
@@ -46,6 +46,23 @@ namespace System.MemoryTests
         }
 
         [Fact]
+        public static void MemoryFromEmptyArrayRetainWithPinning()
+        {
+            ReadOnlyMemory<int> memory = new int[0];
+            MemoryHandle handle = memory.Retain(pin: true);
+            Assert.True(handle.HasPointer);
+            unsafe
+            {
+                int* pointer = (int*)handle.Pointer;
+
+                GC.Collect();
+
+                Assert.True(pointer != null);
+            }
+            handle.Dispose();
+        }
+
+        [Fact]
         public static void MemoryRetainWithPinningAndSlice()
         {
             int[] array = { 1, 2, 3, 4, 5 };