From 9f76c516989b8cdb2f81f5cfb698d1ae94c32a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Thu, 11 May 2023 08:17:24 +0200 Subject: [PATCH 1/5] Fix SetSnapShot CopyTo variance failure --- .../UtilityTest/SetSnapShotFixture.cs | 14 +++++++++++++- .../Collection/Generic/SetHelpers/SetSnapShot.cs | 16 +++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs b/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs index e00af722111..fa668aeb68e 100644 --- a/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs +++ b/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections; +using System.Collections.Generic; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using NHibernate.Collection.Generic.SetHelpers; @@ -70,6 +71,17 @@ public void TestCopyTo() Assert.That(list, Is.EquivalentTo(array)); } + [Test] + public void TestCopyToObjectArray() + { + var list = new List { "test1", null, "test2" }; + ICollection sn = new SetSnapShot(list); + + var array = new object[3]; + sn.CopyTo(array, 0); + Assert.That(list, Is.EquivalentTo(array)); + } + [Test] public void TestSerialization() { diff --git a/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs b/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs index 0c052a67ba8..34f3b5882dd 100644 --- a/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs +++ b/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs @@ -114,12 +114,22 @@ IEnumerator IEnumerable.GetEnumerator() void ICollection.CopyTo(Array array, int index) { - if (!(array is T[] typedArray)) + if (array is T[] typedArray) { - throw new ArgumentException($"Array must be of type {typeof(T[])}.", nameof(array)); + CopyTo(typedArray, index); + return; } - CopyTo(typedArray, index); + if (array.GetType().GetElementType().IsAssignableFrom(typeof(T))) + { + if (_hasNull) + array.SetValue(default(T), index); + ICollection keysCollection = _values.Keys; + keysCollection.CopyTo(array, index + (_hasNull ? 1 : 0)); + return; + } + + throw new ArgumentException($"Array must be of type {typeof(T[])}.", nameof(array)); } public int Count => _values.Count + (_hasNull ? 1 : 0); From 4537486dbb529675815e2899fec35ff1d3889f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericdelaporte@users.noreply.github.com> Date: Sun, 14 May 2023 17:22:51 +0200 Subject: [PATCH 2/5] Simplify code --- .../Collection/Generic/SetHelpers/SetSnapShot.cs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs b/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs index 34f3b5882dd..9dcdb2fa30e 100644 --- a/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs +++ b/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs @@ -120,16 +120,10 @@ void ICollection.CopyTo(Array array, int index) return; } - if (array.GetType().GetElementType().IsAssignableFrom(typeof(T))) - { - if (_hasNull) - array.SetValue(default(T), index); - ICollection keysCollection = _values.Keys; - keysCollection.CopyTo(array, index + (_hasNull ? 1 : 0)); - return; - } - - throw new ArgumentException($"Array must be of type {typeof(T[])}.", nameof(array)); + if (_hasNull) + array.SetValue(default(T), index); + ICollection keysCollection = _values.Keys; + keysCollection.CopyTo(array, index + (_hasNull ? 1 : 0)); } public int Count => _values.Count + (_hasNull ? 1 : 0); From 401653c5afbd76b2e7adf9c82e027748de369650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericdelaporte@users.noreply.github.com> Date: Sun, 14 May 2023 17:24:05 +0200 Subject: [PATCH 3/5] Implement Core support --- .../Generic/SetHelpers/SetSnapShot.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs b/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs index 9dcdb2fa30e..edafec312ea 100644 --- a/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs +++ b/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs @@ -157,12 +157,26 @@ protected SetSnapShot(SerializationInfo info, StreamingContext context) : base(i void ICollection.CopyTo(Array array, int index) { - if (!(array is T[] typedArray)) + if (array is T[] typedArray) { - throw new ArgumentException($"Array must be of type {typeof(T[])}.", nameof(array)); + CopyTo(typedArray, index); + return; } - CopyTo(typedArray, index); + if (array == null) + throw new ArgumentNullException(nameof(array)); + + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index), index, "Array index cannot be negative"); + + if (index > array.Length || Count > array.Length - index) + throw new ArgumentException("Provided array is too small", nameof(array)); + + foreach (var value in this) + { + array.SetValue(value, index); + index++; + } } bool ICollection.IsSynchronized => false; From 38400a203b2d89de1aae8628041477fd50853153 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Mon, 15 May 2023 22:23:13 +1000 Subject: [PATCH 4/5] Add test for argument exception --- .../UtilityTest/SetSnapShotFixture.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs b/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs index fa668aeb68e..c05237671a7 100644 --- a/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs +++ b/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs @@ -82,6 +82,18 @@ public void TestCopyToObjectArray() Assert.That(list, Is.EquivalentTo(array)); } + [Test] + public void WhenCopyToIsCalledWithIncompatibleArrayTypeThenThrowArgumentException() + { + var list = new List { "test1", null, "test2" }; + ICollection sn = new SetSnapShot(list); + + var array = new int[3]; + Assert.That( + () => sn.CopyTo(array, 0), + Throws.ArgumentException); + } + [Test] public void TestSerialization() { From f3e759bd33f22f61f32958a29fc3e50233f8a94f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericdelaporte@users.noreply.github.com> Date: Tue, 16 May 2023 18:08:10 +0200 Subject: [PATCH 5/5] Support InvalidCastException for incompatible arrays --- src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs b/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs index c05237671a7..47b03b50ec9 100644 --- a/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs +++ b/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs @@ -1,8 +1,10 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using NHibernate.Collection.Generic.SetHelpers; +using NSubstitute.ExceptionExtensions; using NUnit.Framework; namespace NHibernate.Test.UtilityTest @@ -83,7 +85,7 @@ public void TestCopyToObjectArray() } [Test] - public void WhenCopyToIsCalledWithIncompatibleArrayTypeThenThrowArgumentException() + public void WhenCopyToIsCalledWithIncompatibleArrayTypeThenThrowArgumentOrInvalidCastException() { var list = new List { "test1", null, "test2" }; ICollection sn = new SetSnapShot(list); @@ -91,7 +93,7 @@ public void WhenCopyToIsCalledWithIncompatibleArrayTypeThenThrowArgumentExceptio var array = new int[3]; Assert.That( () => sn.CopyTo(array, 0), - Throws.ArgumentException); + Throws.ArgumentException.Or.TypeOf()); } [Test]