diff --git a/.gitignore b/.gitignore
index 45ccb8c40a..16342efe06 100644
--- a/.gitignore
+++ b/.gitignore
@@ -257,6 +257,8 @@ paket-files/
PublishProfiles
/.vscode
launchSettings.json
+/coverages
+**/.DS_Store
# Benchmarks
-**/BenchmarkDotNet.Artifacts/
\ No newline at end of file
+**/BenchmarkDotNet.Artifacts/
diff --git a/src/Neo.VM/Types/ByteString.cs b/src/Neo.VM/Types/ByteString.cs
index 8869092b03..d2f1ebee65 100644
--- a/src/Neo.VM/Types/ByteString.cs
+++ b/src/Neo.VM/Types/ByteString.cs
@@ -80,7 +80,7 @@ internal bool Equals(StackItem? other, ref uint limits)
public override bool GetBoolean()
{
if (Size > Integer.MaxSize) throw new InvalidCastException();
- return Unsafe.NotZero(GetSpan());
+ return GetSpan().NotZero();
}
public override BigInteger GetInteger()
diff --git a/src/Neo.VM/Unsafe.cs b/src/Neo.VM/Unsafe.cs
index 86380722b6..fe4c974437 100644
--- a/src/Neo.VM/Unsafe.cs
+++ b/src/Neo.VM/Unsafe.cs
@@ -19,9 +19,17 @@ unsafe internal static class Unsafe
{
private const long DefaultXxHash3Seed = 40343;
+ ///
+ /// All bytes are zero or not in a byte array
+ ///
+ /// The byte array
+ /// false if all bytes are zero, true otherwise
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool NotZero(ReadOnlySpan x)
+ public static bool NotZero(this ReadOnlySpan x)
{
+#if NET7_0_OR_GREATER
+ return x.IndexOfAnyExcept((byte)0) >= 0;
+#else
int len = x.Length;
if (len == 0) return false;
fixed (byte* xp = x)
@@ -40,6 +48,7 @@ public static bool NotZero(ReadOnlySpan x)
}
}
return false;
+#endif
}
///
diff --git a/tests/Neo.VM.Tests/UT_Unsafe.cs b/tests/Neo.VM.Tests/UT_Unsafe.cs
index e3b4b8708f..f42903c3cc 100644
--- a/tests/Neo.VM.Tests/UT_Unsafe.cs
+++ b/tests/Neo.VM.Tests/UT_Unsafe.cs
@@ -11,6 +11,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.VM;
+using System;
namespace Neo.Test
{
@@ -20,14 +21,32 @@ public class UT_Unsafe
[TestMethod]
public void TestNotZero()
{
- Assert.IsFalse(Unsafe.NotZero(System.Array.Empty()));
- Assert.IsFalse(Unsafe.NotZero(new byte[4]));
- Assert.IsFalse(Unsafe.NotZero(new byte[8]));
- Assert.IsFalse(Unsafe.NotZero(new byte[11]));
+ Assert.IsFalse(new ReadOnlySpan(System.Array.Empty()).NotZero());
+ Assert.IsFalse(new ReadOnlySpan(new byte[4]).NotZero());
+ Assert.IsFalse(new ReadOnlySpan(new byte[7]).NotZero());
+ Assert.IsFalse(new ReadOnlySpan(new byte[8]).NotZero());
+ Assert.IsFalse(new ReadOnlySpan(new byte[9]).NotZero());
+ Assert.IsFalse(new ReadOnlySpan(new byte[11]).NotZero());
- Assert.IsTrue(Unsafe.NotZero(new byte[4] { 0x00, 0x00, 0x00, 0x01 }));
- Assert.IsTrue(Unsafe.NotZero(new byte[8] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }));
- Assert.IsTrue(Unsafe.NotZero(new byte[11] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }));
+ Assert.IsTrue(new ReadOnlySpan(new byte[4] { 0x00, 0x00, 0x00, 0x01 }).NotZero());
+ Assert.IsTrue(new ReadOnlySpan(new byte[7] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }).NotZero());
+ Assert.IsTrue(new ReadOnlySpan(new byte[8] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }).NotZero());
+ Assert.IsTrue(new ReadOnlySpan(new byte[9] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 }).NotZero());
+ Assert.IsTrue(new ReadOnlySpan(new byte[11] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }).NotZero());
+
+ var bytes = new byte[64];
+ for (int i = 0; i < bytes.Length; i++)
+ {
+ ReadOnlySpan span = bytes.AsSpan();
+ Assert.IsFalse(span[i..].NotZero());
+
+ for (int j = i; j < bytes.Length; j++)
+ {
+ bytes[j] = 0x01;
+ Assert.IsTrue(span[i..].NotZero());
+ bytes[j] = 0x00;
+ }
+ }
}
}
}