Skip to content

Commit d27b9f5

Browse files
authored
Merge pull request #34 from HMBSbige/fix/dotnet-bugs
fix: resolve 5 bugs in .NET managed layer
2 parents 1b17803 + 1f02e63 commit d27b9f5

5 files changed

Lines changed: 59 additions & 4 deletions

File tree

src/Blake3.Tests/Blake3StreamTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
using System;
12
using System.IO;
3+
using System.Threading.Tasks;
24
using NUnit.Framework;
35

46
namespace Blake3.Tests
@@ -56,5 +58,37 @@ public void TestHashWrite()
5658
blake3Stream.Write(HasherTests.BigData);
5759
AssertTextAreEqual(HasherTests.BigExpected, blake3Stream.ComputeHash().ToString());
5860
}
61+
62+
[Test]
63+
public void TestHashReadSpan_PartialRead()
64+
{
65+
var data = HasherTests.SimpleData;
66+
var expected = HasherTests.SimpleExpected;
67+
68+
var stream = new MemoryStream(data);
69+
using var blake3Stream = new Blake3Stream(stream);
70+
71+
var oversizedBuffer = new byte[data.Length + 1024];
72+
var bytesRead = blake3Stream.Read(oversizedBuffer.AsSpan());
73+
74+
Assert.AreEqual(data.Length, bytesRead);
75+
AssertTextAreEqual(expected, blake3Stream.ComputeHash().ToString());
76+
}
77+
78+
[Test]
79+
public async Task TestHashReadAsyncMemory_PartialRead()
80+
{
81+
var data = HasherTests.SimpleData;
82+
var expected = HasherTests.SimpleExpected;
83+
84+
var stream = new MemoryStream(data);
85+
await using var blake3Stream = new Blake3Stream(stream);
86+
87+
var oversizedBuffer = new byte[data.Length + 1024];
88+
var bytesRead = await blake3Stream.ReadAsync(oversizedBuffer.AsMemory());
89+
90+
Assert.AreEqual(data.Length, bytesRead);
91+
AssertTextAreEqual(expected, blake3Stream.ComputeHash().ToString());
92+
}
5993
}
6094
}

src/Blake3.Tests/HasherTests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,25 @@ public void TestFinalizeWithOffset()
110110

111111
Assert.True(bigHash.SequenceEqual(reconstructedHash.ToArray()));
112112
}
113+
114+
[Test]
115+
public void TestUpdateWithJoinEmptySpan()
116+
{
117+
using var hasher = Hasher.New();
118+
hasher.UpdateWithJoin(ReadOnlySpan<byte>.Empty);
119+
var hash = hasher.Finalize();
120+
using var hasher2 = Hasher.New();
121+
var expected = hasher2.Finalize();
122+
Assert.AreEqual(expected, hash);
123+
}
124+
125+
[Test]
126+
public void TestFinalizeWithNegativeOffset()
127+
{
128+
using var hasher = Hasher.New();
129+
hasher.Update(SimpleData);
130+
var output = new byte[32];
131+
Assert.Throws<ArgumentOutOfRangeException>(() => hasher.Finalize(-1L, output));
132+
}
113133
}
114134
}

src/Blake3/Blake3Stream.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public override async Task<int> ReadAsync(byte[] buffer, int offset, int count,
101101
var length = await _stream.ReadAsync(buffer, cancellationToken);
102102
if (length > 0)
103103
{
104-
_hasher.Update(buffer.Span);
104+
_hasher.Update(buffer.Span.Slice(0, length));
105105
}
106106
return length;
107107
}
@@ -111,7 +111,7 @@ public override int Read(Span<byte> buffer)
111111
var length = _stream.Read(buffer);
112112
if (length > 0)
113113
{
114-
_hasher.Update(buffer);
114+
_hasher.Update(buffer.Slice(0, length));
115115
}
116116
return length;
117117
}

src/Blake3/Hash.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Diagnostics.CodeAnalysis;
77
using System.Runtime.CompilerServices;
88
using System.Runtime.InteropServices;
9+
using System.Security.Cryptography;
910

1011
namespace Blake3;
1112

@@ -85,7 +86,7 @@ public static Hash FromBytes(ReadOnlySpan<byte> data)
8586

8687
public bool Equals(Hash other)
8788
{
88-
return this.AsSpan().SequenceCompareTo(other.AsSpan()) == 0;
89+
return CryptographicOperations.FixedTimeEquals(AsSpan(), other.AsSpan());
8990
}
9091

9192
public override bool Equals(object obj)

src/Blake3/Hasher.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ public void Update<T>(ReadOnlySpan<T> data) where T : unmanaged
183183
/// </remarks>
184184
public void UpdateWithJoin(ReadOnlySpan<byte> data)
185185
{
186-
if (data == null) ThrowArgumentNullException();
187186
if (_hasher == null) ThrowNullReferenceException();
188187
fixed (void* ptr = data)
189188
{
@@ -283,6 +282,7 @@ public void Finalize(ulong offset, Span<byte> hash)
283282
/// </remarks>
284283
public void Finalize(long offset, Span<byte> hash)
285284
{
285+
ArgumentOutOfRangeException.ThrowIfLessThan(offset, 0);
286286
Finalize((ulong)offset, hash);
287287
}
288288

0 commit comments

Comments
 (0)