Skip to content

Commit 2d7d1cd

Browse files
committed
Update Torrent.Pieces property with null-check and multiple of 20 check
1 parent 97fd37a commit 2d7d1cd

5 files changed

Lines changed: 84 additions & 5 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using System.Reflection;
3+
using AutoFixture;
4+
using AutoFixture.Xunit2;
5+
6+
namespace BencodeNET.Tests.AutoFixture
7+
{
8+
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
9+
public class RepeatCountAttribute : CustomizeAttribute
10+
{
11+
private int Count { get; }
12+
13+
public RepeatCountAttribute(int count)
14+
{
15+
Count = count;
16+
}
17+
18+
public override ICustomization GetCustomization(ParameterInfo parameter)
19+
{
20+
return new RepeatCountCustomization(Count);
21+
}
22+
}
23+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using AutoFixture;
2+
3+
namespace BencodeNET.Tests.AutoFixture
4+
{
5+
public class RepeatCountCustomization : ICustomization
6+
{
7+
private int Count { get; }
8+
9+
public RepeatCountCustomization(int count)
10+
{
11+
Count = count;
12+
}
13+
14+
public void Customize(IFixture fixture)
15+
{
16+
fixture.RepeatCount = Count;
17+
}
18+
}
19+
}

BencodeNET.Tests/Torrents/TorrentParserTests.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using BencodeNET.IO;
55
using BencodeNET.Objects;
66
using BencodeNET.Parsing;
7+
using BencodeNET.Tests.AutoFixture;
78
using BencodeNET.Torrents;
89
using FluentAssertions;
910
using NSubstitute;
@@ -202,16 +203,17 @@ public void Info_PieceLength_IsParsed(long pieceSize)
202203

203204
[Theory]
204205
[AutoMockedData]
205-
public void Info_Pieces_IsParsed(byte[] pieces)
206+
public void Info_Pieces_IsParsed([RepeatCount(20)] byte[] pieces)
206207
{
207208
// Arrange
208209
ParsedData = ValidSingleFileTorrentData;
209210
var info = ParsedData.Get<BDictionary>(TorrentFields.Info);
210211
info[TorrentInfoFields.Pieces] = new BString(pieces);
212+
pieces.Should().HaveCount(20);
211213

212214
// Act
213215
var parser = new TorrentParser(BencodeParser);
214-
var torrent = parser.Parse((BencodeReader)null);
216+
var torrent = parser.Parse((BencodeReader) null);
215217

216218
// Assert
217219
torrent.Pieces.Should().Equal(pieces);

BencodeNET.Tests/Torrents/TorrentTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Text;
4+
using AutoFixture.Xunit2;
45
using BencodeNET.Exceptions;
56
using BencodeNET.Objects;
67
using BencodeNET.Torrents;
@@ -135,6 +136,27 @@ public void DisplayNameUtf8_UnknownFileMode_ThrowsBencodeException()
135136
act.Should().Throw<BencodeException>();
136137
}
137138

139+
[Theory]
140+
[AutoMockedData]
141+
public void Pieces_Setter_NullValue_ThrowsArgumentNullException([NoAutoProperties] Torrent torrent)
142+
{
143+
Action act = () => torrent.Pieces = null;
144+
145+
act.Should().ThrowExactly<ArgumentNullException>();
146+
}
147+
148+
[Theory]
149+
[AutoMockedData]
150+
public void Pieces_Setter_NotMultipleOf20_ThrowsArgumentException([NoAutoProperties] Torrent torrent)
151+
{
152+
var pieces = new byte[] { 66, 115, 135, 19, 149, 125, 229, 85, 68, 117, 252, 185, 243, 247, 139, 38, 11, 37, 60 };
153+
pieces.Should().NotHaveCount(20);
154+
155+
Action act = () => torrent.Pieces = pieces;
156+
157+
act.Should().ThrowExactly<ArgumentException>();
158+
}
159+
138160
[Fact]
139161
public void PiecesAsHexString_Get_ReturnsHexUppercaseWithoutDashes()
140162
{

BencodeNET/Torrents/Torrent.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,26 @@ public virtual string DisplayNameUtf8
177177
/// </summary>
178178
public virtual long PieceSize { get; set; }
179179

180-
// TODO: Split into list of 20-byte hashes and rename to something appropriate?
181-
182180
/// <summary>
183181
/// A concatenation of all 20-byte SHA1 hash values (one for each piece).
184182
/// Use <see cref="PiecesAsHexString"/> to get/set this value as a hex string instead.
185183
/// </summary>
186-
public virtual byte[] Pieces { get; set; } = Array.Empty<byte>();
184+
public virtual byte[] Pieces
185+
{
186+
get => _pieces;
187+
set
188+
{
189+
if (value is null)
190+
throw new ArgumentNullException(nameof(value), "Pieces array cannot be null.");
191+
192+
var remainder = value.Length % 20;
193+
if (remainder is not 0)
194+
throw new ArgumentException($"Array size has to be a multiple of 20, but length was {value.Length}");
195+
196+
_pieces = value;
197+
}
198+
}
199+
private byte[] _pieces = Array.Empty<byte>();
187200

188201
/// <summary>
189202
/// Gets or sets <see cref="Pieces"/> from/to a hex string (without dashes), e.g. 1C115D26444AEF2A5E936133DCF8789A552BBE9F[...].

0 commit comments

Comments
 (0)