Skip to content

Commit e9203aa

Browse files
authored
Use IncrementalHash instead of CryptoStream (#255)
Fix #253
1 parent 472837a commit e9203aa

File tree

1 file changed

+11
-19
lines changed

1 file changed

+11
-19
lines changed

Microsoft.NET.Build.Containers/Layer.cs

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Formats.Tar;
1+
using System.Diagnostics;
2+
using System.Formats.Tar;
23
using System.IO.Compression;
34
using System.Security.Cryptography;
45

@@ -36,7 +37,7 @@ public static Layer FromFiles(IEnumerable<(string path, string containerPath)> f
3637
{
3738
long fileSize;
3839
Span<byte> hash = stackalloc byte[SHA256.HashSizeInBytes];
39-
byte[] uncompressedHash;
40+
Span<byte> uncompressedHash = stackalloc byte[SHA256.HashSizeInBytes];
4041

4142
string tempTarballPath = ContentStore.GetTempFile();
4243
using (FileStream fs = File.Create(tempTarballPath))
@@ -55,7 +56,8 @@ public static Layer FromFiles(IEnumerable<(string path, string containerPath)> f
5556
}
5657
} // Dispose of the TarWriter before getting the hash so the final data get written to the tar stream
5758

58-
uncompressedHash = gz.GetHash();
59+
int bytesWritten = gz.GetCurrentUncompressedHash(uncompressedHash);
60+
Debug.Assert(bytesWritten == uncompressedHash.Length);
5961
}
6062

6163
fileSize = fs.Length;
@@ -98,51 +100,41 @@ public static Layer FromFiles(IEnumerable<(string path, string containerPath)> f
98100
/// </summary>
99101
private sealed class HashDigestGZipStream : Stream
100102
{
101-
private readonly SHA256 hashAlgorithm;
102-
private readonly CryptoStream sha256Stream;
103+
private readonly IncrementalHash sha256Hash;
103104
private readonly Stream compressionStream;
104105

105106
public HashDigestGZipStream(Stream writeStream, bool leaveOpen)
106107
{
107-
hashAlgorithm = SHA256.Create();
108-
sha256Stream = new CryptoStream(Stream.Null, hashAlgorithm, CryptoStreamMode.Write);
108+
sha256Hash = IncrementalHash.CreateHash(HashAlgorithmName.SHA256);
109109
compressionStream = new GZipStream(writeStream, CompressionMode.Compress, leaveOpen);
110110
}
111111

112112
public override bool CanWrite => true;
113113

114114
public override void Write(byte[] buffer, int offset, int count)
115115
{
116-
sha256Stream.Write(buffer, offset, count);
116+
sha256Hash.AppendData(buffer, offset, count);
117117
compressionStream.Write(buffer, offset, count);
118118
}
119119

120120
public override void Write(ReadOnlySpan<byte> buffer)
121121
{
122-
sha256Stream.Write(buffer);
122+
sha256Hash.AppendData(buffer);
123123
compressionStream.Write(buffer);
124124
}
125125

126126
public override void Flush()
127127
{
128-
sha256Stream.Flush();
129128
compressionStream.Flush();
130129
}
131130

132-
internal byte[] GetHash()
133-
{
134-
sha256Stream.FlushFinalBlock();
135-
return hashAlgorithm.Hash!;
136-
}
131+
internal int GetCurrentUncompressedHash(Span<byte> buffer) => sha256Hash.GetCurrentHash(buffer);
137132

138133
protected override void Dispose(bool disposing)
139134
{
140135
try
141136
{
142-
// dispose hashAlgorithm after sha256Stream since sha256Stream references/uses it
143-
sha256Stream.Dispose();
144-
hashAlgorithm.Dispose();
145-
137+
sha256Hash.Dispose();
146138
compressionStream.Dispose();
147139
}
148140
finally

0 commit comments

Comments
 (0)