diff --git a/bin/genhtml b/bin/genhtml
index a510917c..7a4f4891 100755
--- a/bin/genhtml
+++ b/bin/genhtml
@@ -2494,22 +2494,25 @@ sub _categorizeBranchCov
# a high probability event?
foreach my $line ($branchCurrent->keylist()) {
my $type = $linemap->type($filename, $linemap->NEW, $line);
- lcovutil::ignorable_error($lcovutil::ERROR_INCONSISTENT_DATA,
- "'current' line $filename:$line should not be marked 'delete'")
- if $type eq 'delete';
- #next if $type eq 'delete';
-
- $branchCovLines{$line} = 1;
+ if ($type eq 'delete') {
+ lcovutil::ignorable_error($lcovutil::ERROR_INCONSISTENT_DATA,
+ "'current' line $filename:$line should not be marked 'delete'");
+ delete($branchCurrent->{$line});
+ next;
+ }
my $data;
if (!exists($lineDataMap->{$line})) {
- $data = LineData->new($type);
- $lineDataMap->{$line} = $data;
# we expect the associated line to also have line coverage data
lcovutil::ignorable_error($lcovutil::ERROR_UNKNOWN_CATEGORY,
"line $line of $filename has branchcov but no linecov data");
+ # maybe should skip this branch if no line data - rather
+ # than building fake data.
+ $data = LineData->new($type);
+ $lineDataMap->{$line} = $data;
} else {
$data = $lineDataMap->{$line};
}
+ $branchCovLines{$line} = 1;
# we expect that the line number matches...
$data->lineNo("current", $line);
# append this branch data for the line
diff --git a/lib/lcovutil.pm b/lib/lcovutil.pm
index 757120f2..bc93a831 100644
--- a/lib/lcovutil.pm
+++ b/lib/lcovutil.pm
@@ -6513,6 +6513,13 @@ sub _read_info
/^DA:(\d+),([^,]+)(,([^,\s]+))?/ && do {
my ($line, $count, $checksum) = ($1, $2, $4);
+ if ($line <= 0) {
+ lcovutil::ignorable_error(
+ $lcovutil::ERROR_INCONSISTENT_DATA,
+ "\"$tracefile\":$.: unexpected line number '$line' in .info file record '$_'"
+ );
+ last;
+ }
if ($readSourceCallback->notEmpty()) {
# does the source checksum match the recorded checksum?
if ($verify_checksum) {
@@ -6567,6 +6574,13 @@ sub _read_info
my $lineNo = $1;
my $fnName = $4;
my $end_line = $3;
+ if ($lineNo <= 0) {
+ lcovutil::ignorable_error(
+ $lcovutil::ERROR_INCONSISTENT_DATA,
+ "\"$tracefile\":$.: unexpected line number '$lineNo' in .info file record '$_'"
+ );
+ last;
+ }
# the function may already be defined by another testcase
# (for the same file)
$functionMap->define_function($fnName, $filename, $lineNo,
@@ -6597,6 +6611,24 @@ sub _read_info
my ($line, $is_exception, $block, $d) =
($1, defined($2) && 'e' eq $2, $3, $4);
+ if ($line <= 0) {
+ # Python coverage.py emits line number 0 (zero) for branches
+ # - which is bogus, as there is no line number zero,
+ # and the corresponding branch expression is not there in
+ # any case.
+ # Meantime: this confuses the lcov DB - so we simply skip
+ # such data.
+ # Note that we only need to check while reading .info files.
+ # - if we wrote one from geninfo, then we will not have
+ # produced bogus data - so no need to check.
+ # - only some (broken) external tool could have the issue
+ lcovutil::ignorable_error(
+ $lcovutil::ERROR_INCONSISTENT_DATA,
+ "\"$tracefile\":$.: unexpected line number '$line' in .info file record '$_'"
+ );
+ last;
+ }
+
last if $is_exception && $lcovutil::exclude_exception_branch;
my $comma = rindex($d, ',');
my $taken = substr($d, $comma + 1);
@@ -6866,6 +6898,14 @@ sub write_info($$$)
defined($data->end_line()) ?
',' . $data->end_line() :
'';
+ if ($line <= 0) {
+ my $alias = (sort keys %$aliases)[0];
+ lcovutil::ignorable_error(
+ $lcovutil::ERROR_INCONSISTENT_DATA,
+ "\"$source_file\": unexpected line number '$line' for function $alias"
+ );
+ next;
+ }
foreach my $alias (sort keys %$aliases) {
print(INFO_HANDLE "FN:$line$endLine,$alias\n");
}
@@ -6873,8 +6913,9 @@ sub write_info($$$)
my $f_found = 0;
my $f_hit = 0;
foreach my $key (@functionOrder) {
- my $data = $functionMap->findKey($key);
- my $line = $data->line();
+ my $data = $functionMap->findKey($key);
+ my $line = $data->line();
+ next unless $line > 0;
my $aliases = $data->aliases();
foreach my $alias (sort keys %$aliases) {
my $hit = $aliases->{$alias};
@@ -6895,6 +6936,13 @@ sub write_info($$$)
foreach my $line (sort({ $a <=> $b } $testbrcount->keylist())) {
+ if ($line <= 0) {
+ lcovutil::ignorable_error(
+ $lcovutil::ERROR_INCONSISTENT_DATA,
+ "\"$source_file\": unexpected line number '$line' in branch data record record '$_'"
+ );
+ last;
+ }
my $brdata = $testbrcount->value($line);
# want the block_id to be treated as 32-bit unsigned integer
# (need masking to match regression tests)