Skip to content

Commit c49a2a9

Browse files
Fix SetSnapShot CopyTo variance failure (#3304)
Co-authored-by: Alex Zaytsev <hazzik@gmail.com>
1 parent 169b0d4 commit c49a2a9

File tree

2 files changed

+51
-7
lines changed

2 files changed

+51
-7
lines changed

src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
24
using System.IO;
35
using System.Runtime.Serialization.Formatters.Binary;
46
using NHibernate.Collection.Generic.SetHelpers;
7+
using NSubstitute.ExceptionExtensions;
58
using NUnit.Framework;
69

710
namespace NHibernate.Test.UtilityTest
@@ -70,6 +73,29 @@ public void TestCopyTo()
7073
Assert.That(list, Is.EquivalentTo(array));
7174
}
7275

76+
[Test]
77+
public void TestCopyToObjectArray()
78+
{
79+
var list = new List<string> { "test1", null, "test2" };
80+
ICollection sn = new SetSnapShot<string>(list);
81+
82+
var array = new object[3];
83+
sn.CopyTo(array, 0);
84+
Assert.That(list, Is.EquivalentTo(array));
85+
}
86+
87+
[Test]
88+
public void WhenCopyToIsCalledWithIncompatibleArrayTypeThenThrowArgumentOrInvalidCastException()
89+
{
90+
var list = new List<string> { "test1", null, "test2" };
91+
ICollection sn = new SetSnapShot<string>(list);
92+
93+
var array = new int[3];
94+
Assert.That(
95+
() => sn.CopyTo(array, 0),
96+
Throws.ArgumentException.Or.TypeOf<InvalidCastException>());
97+
}
98+
7399
[Test]
74100
public void TestSerialization()
75101
{

src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs

+24-6
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,16 @@ IEnumerator IEnumerable.GetEnumerator()
114114

115115
void ICollection.CopyTo(Array array, int index)
116116
{
117-
if (!(array is T[] typedArray))
117+
if (array is T[] typedArray)
118118
{
119-
throw new ArgumentException($"Array must be of type {typeof(T[])}.", nameof(array));
119+
CopyTo(typedArray, index);
120+
return;
120121
}
121122

122-
CopyTo(typedArray, index);
123+
if (_hasNull)
124+
array.SetValue(default(T), index);
125+
ICollection keysCollection = _values.Keys;
126+
keysCollection.CopyTo(array, index + (_hasNull ? 1 : 0));
123127
}
124128

125129
public int Count => _values.Count + (_hasNull ? 1 : 0);
@@ -153,12 +157,26 @@ protected SetSnapShot(SerializationInfo info, StreamingContext context) : base(i
153157

154158
void ICollection.CopyTo(Array array, int index)
155159
{
156-
if (!(array is T[] typedArray))
160+
if (array is T[] typedArray)
157161
{
158-
throw new ArgumentException($"Array must be of type {typeof(T[])}.", nameof(array));
162+
CopyTo(typedArray, index);
163+
return;
159164
}
160165

161-
CopyTo(typedArray, index);
166+
if (array == null)
167+
throw new ArgumentNullException(nameof(array));
168+
169+
if (index < 0)
170+
throw new ArgumentOutOfRangeException(nameof(index), index, "Array index cannot be negative");
171+
172+
if (index > array.Length || Count > array.Length - index)
173+
throw new ArgumentException("Provided array is too small", nameof(array));
174+
175+
foreach (var value in this)
176+
{
177+
array.SetValue(value, index);
178+
index++;
179+
}
162180
}
163181

164182
bool ICollection.IsSynchronized => false;

0 commit comments

Comments
 (0)