Explorar o código

remove Reverse extension to avoid source-breaking change with .NET 10 (#1606)

* remove Reverse extension to avoid source-breaking change with .NET 10

* revert to ifdef in some places

to avoid extra array copy on lower targets
mus65 hai 7 meses
pai
achega
d1213cf751

+ 16 - 16
src/Renci.SshNet/Common/Extensions.cs

@@ -46,6 +46,17 @@ namespace Renci.SshNet.Common
             }
         }
 
+        internal static BigInteger ToBigInteger(this ReadOnlySpan<byte> data)
+        {
+#if NETSTANDARD2_1 || NET
+            return new BigInteger(data, isBigEndian: true);
+#else
+            var reversed = data.ToArray();
+            Array.Reverse(reversed);
+            return new BigInteger(reversed);
+#endif
+        }
+
         internal static BigInteger ToBigInteger(this byte[] data)
         {
 #if NETSTANDARD2_1 || NET
@@ -53,7 +64,8 @@ namespace Renci.SshNet.Common
 #else
             var reversed = new byte[data.Length];
             Buffer.BlockCopy(data, 0, reversed, 0, data.Length);
-            return new BigInteger(reversed.Reverse());
+            Array.Reverse(reversed);
+            return new BigInteger(reversed);
 #endif
         }
 
@@ -69,7 +81,8 @@ namespace Renci.SshNet.Common
             {
                 var buf = new byte[data.Length + 1];
                 Buffer.BlockCopy(data, 0, buf, 1, data.Length);
-                return new BigInteger(buf.Reverse());
+                Array.Reverse(buf);
+                return new BigInteger(buf);
             }
 
             return data.ToBigInteger();
@@ -88,7 +101,7 @@ namespace Renci.SshNet.Common
 
             if (isBigEndian)
             {
-                _ = data.Reverse();
+                Array.Reverse(data);
             }
 
             return data;
@@ -138,19 +151,6 @@ namespace Renci.SshNet.Common
             }
         }
 
-        /// <summary>
-        /// Reverses the sequence of the elements in the entire one-dimensional <see cref="Array"/>.
-        /// </summary>
-        /// <param name="array">The one-dimensional <see cref="Array"/> to reverse.</param>
-        /// <returns>
-        /// The <see cref="Array"/> with its elements reversed.
-        /// </returns>
-        internal static T[] Reverse<T>(this T[] array)
-        {
-            Array.Reverse(array);
-            return array;
-        }
-
         /// <summary>
         /// Prints out the specified bytes.
         /// </summary>

+ 2 - 1
src/Renci.SshNet/Common/SshDataStream.cs

@@ -210,7 +210,8 @@ namespace Renci.SshNet.Common
 #if NETSTANDARD2_1 || NET
             return new BigInteger(data, isBigEndian: true);
 #else
-            return new BigInteger(data.Reverse());
+            Array.Reverse(data);
+            return new BigInteger(data);
 #endif
         }
 

+ 5 - 4
src/Renci.SshNet/Security/Cryptography/EcdsaKey.cs

@@ -22,9 +22,9 @@ namespace Renci.SshNet.Security
         private const string ECDSA_P521_OID_VALUE = "1.3.132.0.35"; // Also called nistP521or secP521r1
 #pragma warning restore SA1310 // Field names should not contain underscore
 
-        private static readonly BigInteger Encoded256 = new BigInteger("nistp256"u8.ToArray().Reverse());
-        private static readonly BigInteger Encoded384 = new BigInteger("nistp384"u8.ToArray().Reverse());
-        private static readonly BigInteger Encoded521 = new BigInteger("nistp521"u8.ToArray().Reverse());
+        private static readonly BigInteger Encoded256 = "nistp256"u8.ToBigInteger();
+        private static readonly BigInteger Encoded384 = "nistp384"u8.ToBigInteger();
+        private static readonly BigInteger Encoded521 = "nistp521"u8.ToBigInteger();
 
         private EcdsaDigitalSignature? _digitalSignature;
 
@@ -150,7 +150,8 @@ namespace Renci.SshNet.Security
 #if NETSTANDARD2_1 || NET
                 return new[] { curve, new BigInteger(q, isBigEndian: true) };
 #else
-                return new[] { curve, new BigInteger(q.Reverse()) };
+                Array.Reverse(q);
+                return new[] { curve, new BigInteger(q) };
 #endif
             }
         }

+ 0 - 27
test/Renci.SshNet.Benchmarks/Common/ExtensionsBenchmarks.cs

@@ -1,27 +0,0 @@
-using BenchmarkDotNet.Attributes;
-
-using Renci.SshNet.Common;
-
-namespace Renci.SshNet.Benchmarks.Common
-{
-    public class ExtensionsBenchmarks
-    {
-        private byte[]? _data;
-
-        [Params(1000, 10000)]
-        public int N { get; set; }
-
-        [GlobalSetup]
-        public void Setup()
-        {
-            _data = new byte[N];
-            new Random(42).NextBytes(_data);
-        }
-
-        [Benchmark]
-        public byte[] Reverse()
-        {
-            return _data.Reverse();
-        }
-    }
-}

+ 0 - 65
test/Renci.SshNet.Tests/Classes/Common/ExtensionsTest_Reverse.cs

@@ -1,65 +0,0 @@
-using System;
-
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-using Renci.SshNet.Common;
-
-namespace Renci.SshNet.Tests.Classes.Common
-{
-    [TestClass]
-    public class ExtensionsTest_Reverse
-    {
-        [TestMethod]
-        public void Empty()
-        {
-            var value = new byte[0];
-
-            var actual = Extensions.Reverse(value);
-
-            Assert.IsNotNull(actual);
-            Assert.AreEqual(0, actual.Length);
-        }
-
-        [TestMethod]
-        public void Null()
-        {
-            const byte[] value = null;
-
-            try
-            {
-                Extensions.Reverse(value);
-                Assert.Fail();
-            }
-            catch (ArgumentNullException ex)
-            {
-                Assert.IsNull(ex.InnerException);
-                Assert.AreEqual("array", ex.ParamName);
-            }
-        }
-
-        [TestMethod]
-        public void Small()
-        {
-            var value = new[] { 0, 1, 4, 3, 7, 9 };
-
-            var actual = Extensions.Reverse(value);
-
-            Assert.IsNotNull(actual);
-            Assert.AreEqual(6, actual.Length);
-            Assert.AreEqual(9, actual[0]);
-            Assert.AreEqual(7, actual[1]);
-            Assert.AreEqual(3, actual[2]);
-            Assert.AreEqual(4, actual[3]);
-            Assert.AreEqual(1, actual[4]);
-            Assert.AreEqual(0, actual[5]);
-
-            Assert.AreEqual(9, value[0]);
-            Assert.AreEqual(7, value[1]);
-            Assert.AreEqual(3, value[2]);
-            Assert.AreEqual(4, value[3]);
-            Assert.AreEqual(1, value[4]);
-            Assert.AreEqual(0, value[5]);
-        }
-    }
-}
-

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Common/ExtensionsTest_ToBigInteger2.cs

@@ -12,7 +12,7 @@ namespace Renci.SshNet.Tests.Classes.Common
         {
             byte[] value = { 0x0a, 0x0d };
 
-            var actual = value.ToBigInteger2().ToByteArray().Reverse();
+            var actual = value.ToBigInteger2().ToByteArray(isBigEndian: true);
 
             Assert.IsNotNull(actual);
             Assert.AreEqual(2, actual.Length);
@@ -25,7 +25,7 @@ namespace Renci.SshNet.Tests.Classes.Common
         {
             byte[] value = { 0xff, 0x0a, 0x0d };
 
-            var actual = value.ToBigInteger2().ToByteArray().Reverse();
+            var actual = value.ToBigInteger2().ToByteArray(isBigEndian: true);
 
             Assert.IsNotNull(actual);
             Assert.AreEqual(4, actual.Length);

+ 1 - 1
test/Renci.SshNet.Tests/Classes/Security/KeyExchangeDiffieHellmanGroup14Sha1Test.cs

@@ -48,7 +48,7 @@ namespace Renci.SshNet.Tests.Classes.Security
         [TestMethod]
         public void GroupPrimeShouldBeSecondOakleyGroup()
         {
-            var bytes = _group14.GroupPrime.ToByteArray().Reverse();
+            var bytes = _group14.GroupPrime.ToByteArray(isBigEndian: true);
             Assert.IsTrue(SecondOkleyGroup.IsEqualTo(bytes));
         }
 

+ 1 - 1
test/Renci.SshNet.Tests/Classes/Security/KeyExchangeDiffieHellmanGroup14Sha256Test.cs

@@ -48,7 +48,7 @@ namespace Renci.SshNet.Tests.Classes.Security
         [TestMethod]
         public void GroupPrimeShouldBeSecondOakleyGroup()
         {
-            var bytes = _group14.GroupPrime.ToByteArray().Reverse();
+            var bytes = _group14.GroupPrime.ToByteArray(isBigEndian: true);
             Assert.IsTrue(SecondOkleyGroup.IsEqualTo(bytes));
         }
 

+ 1 - 1
test/Renci.SshNet.Tests/Classes/Security/KeyExchangeDiffieHellmanGroup16Sha512Test.cs

@@ -58,7 +58,7 @@ namespace Renci.SshNet.Tests.Classes.Security
         [TestMethod]
         public void GroupPrimeShouldBeMoreModularExponentialGroup16()
         {
-            var bytes = _group16.GroupPrime.ToByteArray().Reverse();
+            var bytes = _group16.GroupPrime.ToByteArray(isBigEndian: true);
             Assert.IsTrue(MoreModularExponentialGroup16.IsEqualTo(bytes));
         }
 

+ 4 - 2
test/Renci.SshNet.Tests/Classes/Security/KeyExchangeDiffieHellmanGroup1Sha1Test.cs

@@ -1,4 +1,6 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Linq;
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
 
 using Renci.SshNet.Common;
 using Renci.SshNet.Security;
@@ -37,7 +39,7 @@ namespace Renci.SshNet.Tests.Classes.Security
         [TestMethod]
         public void GroupPrimeShouldBeSecondOakleyGroup()
         {
-            var bytes = _group1.GroupPrime.ToByteArray().Reverse();
+            var bytes = _group1.GroupPrime.ToByteArray(isBigEndian: true);
             Assert.IsTrue(SecondOkleyGroup.IsEqualTo(bytes));
 
             SecondOkleyGroup.Reverse().DebugPrint();