• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

KSP-CKAN / CKAN / 25198663652

01 May 2026 01:58AM UTC coverage: 87.472% (+1.6%) from 85.851%
25198663652

push

github

HebaruSan
Merge #4594 Windows dark mode in .NET 10 build

1982 of 2112 branches covered (93.84%)

Branch coverage included in aggregate %.

35 of 36 new or added lines in 7 files covered. (97.22%)

33 existing lines in 24 files now uncovered.

8491 of 9861 relevant lines covered (86.11%)

2.69 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.27
/Core/Extensions/CryptoExtensions.cs
1
using System;
2
using System.IO;
3
using System.Threading;
4
using System.Security.Cryptography;
5

6
namespace CKAN.Extensions
7
{
8
    /// <summary>
9
    /// Extensions for cryptographic operations
10
    /// </summary>
11
    public static class CryptoExtensions
12
    {
13

14
        /// <summary>
15
        /// A version of ComputeHash with progress updates.
16
        /// Based on https://stackoverflow.com/a/53966139 with lots of cleaning up.
17
        /// </summary>
18
        /// <param name="hashAlgo">The crypto object to use for the operation, like SHA1, SHA256, etc.</param>
19
        /// <param name="stream">Input stream to hash</param>
20
        /// <param name="progress">Callback to notify as we traverse the input, called with percentages from 0 to 100</param>
21
        /// <param name="cancelToken">A cancellation token that can be used to abort the hash</param>
22
        /// <returns>The requested hash of the input stream</returns>
23
        public static byte[] ComputeHash(this HashAlgorithm hashAlgo,
24
                                         Stream             stream,
25
                                         IProgress<int>?    progress,
26
                                         CancellationToken? cancelToken = default)
27
        {
28
            PartialHash(hashAlgo, stream, progress, cancelToken);
3✔
29
            var buffer = new byte[16];
3✔
30
            hashAlgo.TransformFinalBlock(buffer, 0, 0);
3✔
31
            return hashAlgo.Hash ?? Array.Empty<byte>();
3✔
32
        }
33

34
        public static void PartialHash(this HashAlgorithm hashAlgo,
35
                                       Stream             stream,
36
                                       IProgress<int>?    progress,
37
                                       CancellationToken? cancelToken = default)
38
        {
39
            const int bufSize = 1024 * 1024;
40
            var buffer = new byte[bufSize];
3✔
41
            long totalBytesRead = 0;
3✔
UNCOV
42
            while (true)
×
43
            {
44
                var bytesRead = stream.Read(buffer, 0, bufSize);
3✔
45
                cancelToken?.ThrowIfCancellationRequested();
3✔
46

47
                if (bytesRead < bufSize)
3✔
48
                {
49
                    // Done!
50
                    hashAlgo.TransformBlock(buffer, 0, bytesRead, buffer, 0);
3✔
51
                    progress?.Report(100);
3✔
52
                    break;
3✔
53
                }
54
                else
55
                {
56
                    hashAlgo.TransformBlock(buffer, 0, bytesRead, buffer, 0);
×
57
                }
58

59
                totalBytesRead += bytesRead;
×
60
                progress?.Report((int)(100 * totalBytesRead / stream.Length));
×
61
            }
62
        }
3✔
63
    }
64
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc