Skip to content

Commit 3280b0c

Browse files
committed
fixes and improvements (see nuspec file for detailed info)
1 parent efed99b commit 3280b0c

15 files changed

+313
-49
lines changed

Blazer.Net.Tests/Blazer.Net.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
<Compile Include="Properties\AssemblyInfo.cs" />
5858
<Compile Include="PatternedCompressionTests.cs" />
5959
<Compile Include="StreamEncoderTests.cs" />
60+
<Compile Include="TcpStreamTests.cs" />
6061
</ItemGroup>
6162
<ItemGroup>
6263
<None Include="packages.config" />

Blazer.Net.Tests/EncryptionTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,24 @@ public void Simple_Data_Should_Be_Encoded_Decoded(BlazerAlgorithm algorithm)
2121
var blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
2222
blazerCompressionOptions.SetEncoderByAlgorithm(algorithm);
2323
blazerCompressionOptions.Password = "123";
24+
blazerCompressionOptions.FlushMode = BlazerFlushMode.AutoFlush;
2425
IntegrityHelper.CheckCompressDecompress(data, blazerCompressionOptions, s => new BlazerOutputStream(s, new BlazerDecompressionOptions("123")));
2526
}
2627

28+
[Test]
29+
[TestCase(BlazerAlgorithm.NoCompress)]
30+
[TestCase(BlazerAlgorithm.Stream)]
31+
[TestCase(BlazerAlgorithm.Block)]
32+
public void Simple_Data_Should_Be_Encoded_Decoded_Small_Block(BlazerAlgorithm algorithm)
33+
{
34+
var data = Encoding.UTF8.GetBytes("some compressible not very long string. some some some.");
35+
var blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
36+
blazerCompressionOptions.SetEncoderByAlgorithm(algorithm);
37+
blazerCompressionOptions.Password = "123";
38+
blazerCompressionOptions.FlushMode = BlazerFlushMode.AutoFlush;
39+
IntegrityHelper.CheckCompressDecompress(data, blazerCompressionOptions, s => new BlazerOutputStream(s, new BlazerDecompressionOptions("123")), 2);
40+
}
41+
2742
[Test]
2843
public void Invalid_Password_Should_Throw_Error()
2944
{
@@ -66,6 +81,16 @@ public void EncyptFull_Should_Work()
6681
IntegrityHelper.CheckCompressDecompress(data, blazerCompressionOptions, s => new BlazerOutputStream(s, new BlazerDecompressionOptions("123") { EncyptFull = true }));
6782
}
6883

84+
[Test]
85+
public void EncyptFull_Should_Work_Small_Buffer()
86+
{
87+
var data = Encoding.UTF8.GetBytes("some compressible not very long string. some some some.");
88+
var blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
89+
blazerCompressionOptions.Password = "123";
90+
blazerCompressionOptions.EncryptFull = true;
91+
IntegrityHelper.CheckCompressDecompress(data, blazerCompressionOptions, s => new BlazerOutputStream(s, new BlazerDecompressionOptions("123") { EncyptFull = true }), 2);
92+
}
93+
6994
[Test]
7095
public void Invalid_Archive_If_Missing_EncyptFull()
7196
{

Blazer.Net.Tests/IntegrityHelper.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,30 @@ namespace Blazer.Net.Tests
1010
{
1111
public static class IntegrityHelper
1212
{
13-
public static void CheckCompressDecompress(byte[] inData, BlazerCompressionOptions options, Func<Stream, Stream> decoderCreator = null)
13+
public static void CheckCompressDecompress(byte[] inData, BlazerCompressionOptions options, Func<Stream, Stream> decoderCreator = null, int bufferSize = 81920)
1414
{
15-
var compressed = CompressData(inData, options);
16-
var decompressed = DecompressData(compressed, decoderCreator);
15+
var compressed = CompressData(inData, options, bufferSize);
16+
var decompressed = DecompressData(compressed, decoderCreator, bufferSize);
1717

1818
CollectionAssert.AreEqual(inData, decompressed);
1919
}
2020

21-
public static byte[] CompressData(byte[] inData, BlazerCompressionOptions options)
21+
public static byte[] CompressData(byte[] inData, BlazerCompressionOptions options, int bufferSize = 81920)
2222
{
2323
var ms1 = new MemoryStream();
2424
var input = new BlazerInputStream(ms1, options);
2525

26-
new MemoryStream(inData).CopyTo(input);
26+
new MemoryStream(inData).CopyTo(input, bufferSize);
2727
input.Close();
2828
return ms1.ToArray();
2929
}
3030

31-
public static byte[] DecompressData(byte[] inData, Func<Stream, Stream> decoderCreator = null)
31+
public static byte[] DecompressData(byte[] inData, Func<Stream, Stream> decoderCreator = null, int bufferSize = 81920)
3232
{
3333
var ms3 = new MemoryStream(inData);
3434
var output = decoderCreator != null ? decoderCreator(ms3) : new BlazerOutputStream(ms3);
3535
var ms2 = new MemoryStream();
36-
output.CopyTo(ms2);
36+
output.CopyTo(ms2, bufferSize);
3737
output.Close();
3838
return ms2.ToArray();
3939
}

Blazer.Net.Tests/IntegrityTests.cs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ public void Invalid_Header_Should_Throw_Errors()
6565
compressed[3]--;
6666

6767
// invalid flags
68-
compressed[6]++;
68+
compressed[6] = 0xff;
6969
Assert.That(Assert.Throws<InvalidOperationException>(() => IntegrityHelper.DecompressData(compressed)).Message, Is.EqualTo("Invalid flag combination. Try to use newer version of Blazer"));
70-
compressed[6]--;
70+
// compressed[6]--;
7171
}
7272

7373
[Test]
@@ -122,7 +122,7 @@ public void Small_Block_Sizes_ShouldBe_Handled_WithFlush(int blockSize, BlazerAl
122122
data[0] = (byte)blockSize;
123123
var blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
124124
blazerCompressionOptions.SetEncoderByAlgorithm(algorithm);
125-
blazerCompressionOptions.RespectFlush = true;
125+
blazerCompressionOptions.FlushMode = BlazerFlushMode.RespectFlush;
126126

127127
var memoryStream = new MemoryStream();
128128
const int Count = 10;
@@ -166,5 +166,48 @@ public void Zero_Block_Sizes_Should_Not_Cause_Error(BlazerAlgorithm algorithm)
166166
var decompressed = IntegrityHelper.DecompressData(compressed);
167167
Assert.That(decompressed.Length, Is.EqualTo(0));
168168
}
169+
170+
[Test]
171+
public void FailData_Should_Not_Cause_StackOverflow()
172+
{
173+
var ss = new MemoryStream();
174+
var blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
175+
blazerCompressionOptions.IncludeFooter = false;
176+
var os = new BlazerInputStream(ss, blazerCompressionOptions);
177+
os.WriteControlData(new byte[0], 0, 0);
178+
179+
new BlazerOutputStream(new MemoryStream(ss.ToArray()), new BlazerDecompressionOptions { NoSeek = true }).Read(new byte[100], 0, 100);
180+
}
181+
182+
[Test]
183+
public void MissingFooter_With_No_Seec_Should_Cause_Error()
184+
{
185+
var ss = new MemoryStream();
186+
var blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
187+
var os = new BlazerInputStream(ss, blazerCompressionOptions);
188+
os.WriteControlData(new byte[0], 0, 0);
189+
190+
var ex = Assert.Throws<InvalidOperationException>(() => new BlazerOutputStream(new MemoryStream(ss.ToArray()), new BlazerDecompressionOptions { NoSeek = true }).Read(new byte[100], 0, 100));
191+
Assert.That(ex.Message, Is.EqualTo("Stream was finished, but footer is missing. It seems, stream is incomplete"));
192+
}
193+
194+
[Test]
195+
public void After_Footer_Read_Should_Be_Zero()
196+
{
197+
var ss = new MemoryStream();
198+
var blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
199+
blazerCompressionOptions.LeaveStreamOpen = true;
200+
var os = new BlazerInputStream(ss, blazerCompressionOptions);
201+
os.Write(new byte[100], 0, 100);
202+
os.Close();
203+
ss.Write(new byte[] { 1, 2, 3, 4 }, 0, 4);
204+
ss.Close();
205+
206+
var oos = new BlazerOutputStream(new MemoryStream(ss.ToArray()), new BlazerDecompressionOptions { NoSeek = true });
207+
var read = oos.Read(new byte[100], 0, 100);
208+
Assert.That(read, Is.EqualTo(100));
209+
Assert.That(oos.Read(new byte[100], 0, 100), Is.EqualTo(0));
210+
Assert.That(oos.Read(new byte[100], 0, 100), Is.EqualTo(0));
211+
}
169212
}
170213
}

Blazer.Net.Tests/OptionsTests.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ public void Flush_Should_Be_Respected()
172172

173173
// turn off flush
174174
blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
175-
blazerCompressionOptions.RespectFlush = false;
175+
blazerCompressionOptions.FlushMode = BlazerFlushMode.IgnoreFlush;
176176
ms1 = new MemoryStream();
177177
// default flush respected
178178
using (var b = new BlazerInputStream(ms1, blazerCompressionOptions))
@@ -217,5 +217,18 @@ public void NoSeek_Should_Be_Respected()
217217

218218
Assert.DoesNotThrow(() => new BlazerOutputStream(new MemoryStream(arr), new BlazerDecompressionOptions() { NoSeek = true }));
219219
}
220+
221+
[Test]
222+
public void Header_Should_Be_Flushed()
223+
{
224+
var blazerCompressionOptions = BlazerCompressionOptions.CreateStream();
225+
var ms1 = new MemoryStream();
226+
// default flush respected
227+
using (var b = new BlazerInputStream(ms1, blazerCompressionOptions))
228+
{
229+
b.Flush();
230+
Assert.That(ms1.Length, Is.GreaterThan(0));
231+
}
232+
}
220233
}
221234
}

Blazer.Net.Tests/TcpStreamTests.cs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
using System.Net;
2+
using System.Net.Sockets;
3+
using System.Threading.Tasks;
4+
5+
using Force.Blazer;
6+
7+
using NUnit.Framework;
8+
9+
namespace Blazer.Net.Tests
10+
{
11+
// in these test we ensure that all data is correctly processed with live network streams
12+
[TestFixture]
13+
public class TcpStreamTests
14+
{
15+
[Test]
16+
public void EnsureUsualStreamWriteFull()
17+
{
18+
var l = new TcpListener(new IPEndPoint(IPAddress.Loopback, 9990));
19+
l.Start();
20+
try
21+
{
22+
Task.Factory.StartNew(
23+
() =>
24+
{
25+
var cl = l.AcceptTcpClient();
26+
cl.GetStream().Write(new byte[] { 0x1, 0x2, 0x3 }, 0, 3);
27+
cl.Close();
28+
});
29+
30+
var c = new TcpClient();
31+
c.Connect(new IPEndPoint(IPAddress.Loopback, 9990));
32+
var stream = c.GetStream();
33+
var buf = new byte[100];
34+
Assert.That(stream.Read(buf, 0, buf.Length), Is.EqualTo(3));
35+
Assert.That(buf[1], Is.EqualTo(2));
36+
}
37+
finally
38+
{
39+
l.Stop();
40+
}
41+
}
42+
43+
[Test]
44+
public void EnsureBlazerStreamWriteFull()
45+
{
46+
var l = new TcpListener(new IPEndPoint(IPAddress.Loopback, 9990));
47+
l.Start();
48+
try
49+
{
50+
Task.Factory.StartNew(
51+
() =>
52+
{
53+
var cl = l.AcceptTcpClient();
54+
var networkStream = new BlazerInputStream(cl.GetStream(), BlazerCompressionOptions.CreateStream());
55+
networkStream.Write(new byte[] { 0x1, 0x2, 0x3 }, 0, 3);
56+
networkStream.Close();
57+
cl.Close();
58+
});
59+
60+
var c = new TcpClient();
61+
c.Connect(new IPEndPoint(IPAddress.Loopback, 9990));
62+
var stream = new BlazerOutputStream(c.GetStream());
63+
var buf = new byte[100];
64+
Assert.That(stream.Read(buf, 0, buf.Length), Is.EqualTo(3));
65+
Assert.That(buf[1], Is.EqualTo(2));
66+
}
67+
finally
68+
{
69+
l.Stop();
70+
}
71+
}
72+
73+
[Test]
74+
public void EnsureBlazerStreamWriteFull_ControlBlock()
75+
{
76+
var l = new TcpListener(new IPEndPoint(IPAddress.Loopback, 9990));
77+
l.Start();
78+
try
79+
{
80+
Task.Factory.StartNew(
81+
() =>
82+
{
83+
var cl = l.AcceptTcpClient();
84+
var str = cl.GetStream();
85+
var networkStream = new BlazerInputStream(str, BlazerCompressionOptions.CreateStream());
86+
var b = new byte[80];
87+
b[1] = 0x2;
88+
networkStream.WriteControlData(b, 0, b.Length);
89+
networkStream.Flush();
90+
networkStream.Close();
91+
cl.Close();
92+
});
93+
94+
var c = new TcpClient();
95+
c.Connect(new IPEndPoint(IPAddress.Loopback, 9990));
96+
var readedCnt = 0;
97+
var stream = new BlazerOutputStream(c.GetStream(), new BlazerDecompressionOptions() { ControlDataCallback = (bytes, i, arg3) => readedCnt = arg3 });
98+
var buf = new byte[100];
99+
Assert.That(stream.Read(buf, 0, buf.Length), Is.EqualTo(0));
100+
Assert.That(readedCnt, Is.EqualTo(80));
101+
}
102+
finally
103+
{
104+
l.Stop();
105+
}
106+
}
107+
108+
[Test]
109+
public void EnsureBlazerStreamWriteFull_EncryptFull()
110+
{
111+
var l = new TcpListener(new IPEndPoint(IPAddress.Loopback, 9990));
112+
l.Start();
113+
try
114+
{
115+
Task.Factory.StartNew(
116+
() =>
117+
{
118+
var cl = l.AcceptTcpClient();
119+
var opt = BlazerCompressionOptions.CreateStream();
120+
opt.Comment = "test";
121+
var networkStream = new BlazerInputStream(cl.GetStream(), opt);
122+
networkStream.WriteControlData(new byte[0], 0, 0);
123+
networkStream.Close();
124+
cl.Close();
125+
});
126+
127+
var c = new TcpClient();
128+
c.Connect(new IPEndPoint(IPAddress.Loopback, 9990));
129+
var stream = new BlazerOutputStream(c.GetStream(), new BlazerDecompressionOptions());
130+
var buf = new byte[100];
131+
Assert.That(stream.Read(buf, 0, buf.Length), Is.EqualTo(0));
132+
Assert.That(stream.Comment, Is.EqualTo("test"));
133+
}
134+
finally
135+
{
136+
l.Stop();
137+
}
138+
}
139+
}
140+
}

Blazer.Net/Algorithms/StreamDecoder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ public BufferInfo Decode(byte[] buffer, int offset, int length, bool isCompresse
4646
_innerBufferLen = DecompressBlock(buffer, offset, length, _innerBuffer, _innerBufferLen, _innerBufferMaxLen);
4747
else
4848
{
49-
Buffer.BlockCopy(buffer, 0, _innerBuffer, _innerBufferLen, length);
50-
_innerBufferLen += length;
49+
Buffer.BlockCopy(buffer, offset, _innerBuffer, _innerBufferLen, length - offset);
50+
_innerBufferLen += length - offset;
5151
}
5252

5353
return new BufferInfo(_innerBuffer, outOffset, _innerBufferLen);

Blazer.Net/Blazer.Net.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
<Compile Include="BlazerBlockType.cs" />
6464
<Compile Include="BlazerDecompressionOptions.cs" />
6565
<Compile Include="Algorithms\BufferInfo.cs" />
66+
<Compile Include="BlazerFlushMode.cs" />
6667
<Compile Include="BlazerPatternedHelper.cs" />
6768
<Compile Include="Helpers\FileHeaderHelper.cs" />
6869
<Compile Include="Algorithms\StreamEncoderHigh.cs" />

Blazer.Net/Blazer.Net.nuspec

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<metadata>
44
<id>Blazer.Net</id>
55
<title>Blazer.Net</title>
6-
<version>0.9.3</version>
6+
<version>0.9.4</version>
77
<authors>force</authors>
88
<owners>force</owners>
99
<licenseUrl>https://github.com/force-net/blazer/blob/develop/LICENSE</licenseUrl>
@@ -20,7 +20,14 @@
2020
See project site for detailed information.
2121
</description>
2222
<releaseNotes>
23-
Fixed compression for files greater 1Gb in stream and streamhigh mode
23+
Lot of small fixes and some improvements:
24+
- improved variants for flush mode
25+
- fixed flushing only header
26+
- fixed encryption with flush
27+
- improved integrity for incompleted streams
28+
- fixed stackoverflow with last empty control block and missing footer
29+
- fixed possible stackoverflow for rare situations
30+
- fixed possible error in decrypt with EncryptFull mode
2431
</releaseNotes>
2532
<copyright>Copyright by Force 2016-2017</copyright>
2633
<tags>.NET fast compression archive crc32c archiver</tags>

0 commit comments

Comments
 (0)