Skip to content

Commit 8582925

Browse files
authored
Negative coverage when integer overflows (#1267)
Negative coverage when integer overflows
1 parent 8eaaecb commit 8582925

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

Documentation/Changelog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## Unreleased
88

9-
### Fixed
9+
### Fixed
10+
-Fix negative coverage exceeding int.MaxValue [#1266](https://github.com/coverlet-coverage/coverlet/issues/1266)
1011
-Fix summary output format for culture de-DE [#1263](https://github.com/coverlet-coverage/coverlet/issues/1263)
1112
-Fix branch coverage issue for finally block with await [#1233](https://github.com/coverlet-coverage/coverlet/issues/1233)
1213
-Fix threshold doesn't work when coverage empty [#1205](https://github.com/coverlet-coverage/coverlet/issues/1205)

src/coverlet.core/Coverage.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,10 +421,18 @@ private void CalculateCoverage()
421421
var document = documentsList[hitLocation.docIndex];
422422
int hits = br.ReadInt32();
423423

424+
if (hits == 0)
425+
continue;
426+
427+
hits = hits < 0 ? int.MaxValue : hits;
428+
424429
if (hitLocation.isBranch)
425430
{
426431
var branch = document.Branches[new BranchKey(hitLocation.start, hitLocation.end)];
427432
branch.Hits += hits;
433+
434+
if (branch.Hits < 0)
435+
branch.Hits = int.MaxValue;
428436
}
429437
else
430438
{
@@ -437,6 +445,9 @@ private void CalculateCoverage()
437445

438446
var line = document.Lines[j];
439447
line.Hits += hits;
448+
449+
if (line.Hits < 0)
450+
line.Hits = int.MaxValue;
440451
}
441452
}
442453
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System.IO;
2+
using Coverlet.Core.Abstractions;
3+
using Coverlet.Core.Instrumentation;
4+
using Moq;
5+
using Xunit;
6+
7+
namespace Coverlet.Core.Tests
8+
{
9+
public partial class CoverageTests
10+
{
11+
[Fact]
12+
public void CoverageResult_NegativeLineCoverage_TranslatedToMaxValueOfInt32()
13+
{
14+
InstrumenterResult instrumenterResult = new InstrumenterResult
15+
{
16+
HitsFilePath = "HitsFilePath",
17+
SourceLink = "SourceLink",
18+
ModulePath = "ModulePath"
19+
};
20+
21+
instrumenterResult.HitCandidates.Add(new HitCandidate(false, 0, 1, 1));
22+
23+
var document = new Document
24+
{
25+
Index = 0,
26+
Path = "Path0"
27+
};
28+
29+
document.Lines.Add(1, new Line
30+
{
31+
Class = "Class0",
32+
Hits = 0,
33+
Method = "Method0",
34+
Number = 1
35+
});
36+
37+
instrumenterResult.Documents.Add("document", document);
38+
39+
CoveragePrepareResult coveragePrepareResult = new CoveragePrepareResult
40+
{
41+
UseSourceLink = true,
42+
Results = new[] {instrumenterResult},
43+
Parameters = new CoverageParameters()
44+
};
45+
46+
Stream memoryStream = new MemoryStream();
47+
BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
48+
binaryWriter.Write(1);
49+
binaryWriter.Write(-1);
50+
memoryStream.Position = 0;
51+
52+
var fileSystemMock = new Mock<IFileSystem>();
53+
fileSystemMock.Setup(x => x.Exists(It.IsAny<string>())).Returns(true);
54+
fileSystemMock.Setup(x => x.NewFileStream(It.IsAny<string>(), FileMode.Open, FileAccess.Read))
55+
.Returns(memoryStream);
56+
57+
var coverage = new Coverage(coveragePrepareResult, new Mock<ILogger>().Object, new Mock<IInstrumentationHelper>().Object,
58+
fileSystemMock.Object, new Mock<ISourceRootTranslator>().Object);
59+
60+
var coverageResult = coverage.GetCoverageResult();
61+
coverageResult.Document("document").AssertLinesCovered(BuildConfiguration.Debug, (1, int.MaxValue));
62+
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)