Skip to content

Commit 33844c5

Browse files
authored
Handle conflicting SARIF results (#473)
If a user accidentally feeds multiple identical SARIFs, we should gracefully handle the situation.
1 parent 9fe0a17 commit 33844c5

File tree

11 files changed

+166855
-24
lines changed

11 files changed

+166855
-24
lines changed

framework/codemodder-base/src/main/java/io/codemodder/CLI.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -366,14 +366,14 @@ public Integer call() throws IOException {
366366
log.debug("excluding paths: {}", pathExcludes);
367367

368368
// get all files that match
369-
log.debug("Listing source directories");
369+
log.trace("Listing source directories");
370370
List<SourceDirectory> sourceDirectories =
371371
sourceDirectoryLister.listJavaSourceDirectories(List.of(projectDirectory));
372372

373-
log.debug("Listing files");
373+
log.trace("Listing files");
374374
List<Path> filePaths = fileFinder.findFiles(projectPath, includesExcludes);
375375

376-
log.debug("Creating codemod regulator");
376+
log.trace("Creating codemod regulator");
377377

378378
// get codemod includes/excludes
379379
final CodemodRegulator regulator;

framework/codemodder-base/src/main/java/io/codemodder/DefaultSarifParser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ private Optional<Map.Entry<String, RuleSarif>> tryToBuild(
4646
}
4747
}
4848

49-
log.info("Found SARIF from unsupported tool: {}", toolName);
49+
log.info("Found SARIF rule entries from unsupported tool: {}", toolName);
5050
return Optional.empty();
5151
}
5252

plugins/codemodder-plugin-codeql/src/main/java/io/codemodder/providers/sarif/codeql/CodeQLModule.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44
import io.codemodder.CodeChanger;
55
import io.codemodder.RuleSarif;
66
import java.lang.reflect.Constructor;
7-
import java.util.List;
8-
import java.util.Map;
9-
import java.util.Objects;
10-
import java.util.Optional;
11-
import java.util.stream.Collectors;
7+
import java.util.*;
128
import java.util.stream.Stream;
9+
import org.slf4j.Logger;
10+
import org.slf4j.LoggerFactory;
1311

1412
/** Responsible for distributing the SARIFS to CodeQL based codemods based on rules. */
1513
public final class CodeQLModule extends AbstractModule {
@@ -27,9 +25,16 @@ public final class CodeQLModule extends AbstractModule {
2725
protected void configure() {
2826
// What if there are multiple sarif files with a given rule?
2927
// We can safely ignore this case for now.
30-
final Map<String, RuleSarif> map =
31-
allCodeqlRuleSarifs.stream()
32-
.collect(Collectors.toUnmodifiableMap(RuleSarif::getRule, rs -> rs));
28+
final Map<String, RuleSarif> map = new HashMap<>();
29+
allCodeqlRuleSarifs.forEach(
30+
rs -> {
31+
if (!map.containsKey(rs.getRule())) {
32+
map.put(rs.getRule(), rs);
33+
} else {
34+
log.warn(
35+
"Multiple SARIFs found for rule: {}, ignoring results after first", rs.getRule());
36+
}
37+
});
3338

3439
for (final Class<? extends CodeChanger> codemodType : codemodTypes) {
3540
final Constructor<?>[] constructors = codemodType.getDeclaredConstructors();
@@ -49,4 +54,6 @@ protected void configure() {
4954
.toInstance(map.getOrDefault(providedCodeQLScan.ruleId(), RuleSarif.EMPTY)));
5055
}
5156
}
57+
58+
private static final Logger log = LoggerFactory.getLogger(CodeQLModule.class);
5259
}

plugins/codemodder-plugin-codeql/src/main/java/io/codemodder/providers/sarif/codeql/CodeQLRuleSarif.java

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
package io.codemodder.providers.sarif.codeql;
22

3-
import com.contrastsecurity.sarif.Region;
4-
import com.contrastsecurity.sarif.Result;
5-
import com.contrastsecurity.sarif.Run;
6-
import com.contrastsecurity.sarif.SarifSchema210;
3+
import com.contrastsecurity.sarif.*;
74
import io.codemodder.CodeDirectory;
85
import io.codemodder.RuleSarif;
96
import java.io.IOException;
107
import java.nio.file.Files;
118
import java.nio.file.Path;
129
import java.util.*;
13-
import java.util.stream.Collectors;
1410
import org.slf4j.Logger;
1511
import org.slf4j.LoggerFactory;
1612

@@ -39,12 +35,8 @@ private String extractRuleId(final Result result, final Run run) {
3935
.skip(toolIndex)
4036
.findFirst()
4137
.flatMap(tool -> tool.getRules().stream().skip(ruleIndex).findFirst())
42-
.map(rd -> rd.getId());
43-
if (maybeRule.isPresent()) {
44-
return maybeRule.get();
45-
} else {
46-
return null;
47-
}
38+
.map(ReportingDescriptor::getId);
39+
return maybeRule.orElse(null);
4840
}
4941
return result.getRuleId();
5042
}
@@ -53,7 +45,7 @@ private String extractRuleId(final Result result, final Run run) {
5345
public List<Region> getRegionsFromResultsByRule(final Path path) {
5446
return getResultsByLocationPath(path).stream()
5547
.map(result -> result.getLocations().get(0).getPhysicalLocation().getRegion())
56-
.collect(Collectors.toUnmodifiableList());
48+
.toList();
5749
}
5850

5951
@Override
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package io.codemodder.providers.sarif.codeql;
2+
3+
import io.codemodder.*;
4+
import java.nio.file.Path;
5+
import java.util.List;
6+
import java.util.Map;
7+
import org.junit.jupiter.api.Test;
8+
import org.junit.jupiter.api.io.TempDir;
9+
10+
final class ConflictingSarifTest {
11+
12+
/**
13+
* Test that conflicting SARIFs can be combined, and will fail gracefully, only honoring the first
14+
* set of results found.
15+
*/
16+
@Test
17+
void it_combines_sarifs_with_overlapping_keys(@TempDir Path tempDir) {
18+
List<Path> sarifFiles =
19+
List.of(
20+
Path.of("src/test/resources/conflicting-sarifs/codeql-0.sarif"),
21+
Path.of("src/test/resources/conflicting-sarifs/codeql-1.sarif"),
22+
Path.of("src/test/resources/conflicting-sarifs/codeql-2.sarif"),
23+
Path.of("src/test/resources/conflicting-sarifs/codeql-3.sarif"),
24+
Path.of("src/test/resources/conflicting-sarifs/codeql-4.sarif"),
25+
Path.of("src/test/resources/conflicting-sarifs/codeql-5.sarif"));
26+
27+
Map<String, List<RuleSarif>> pathSarifMap =
28+
SarifParser.create().parseIntoMap(sarifFiles, CodeDirectory.from(tempDir));
29+
30+
new CodemodLoader(
31+
List.of(),
32+
CodemodRegulator.of(DefaultRuleSetting.ENABLED, List.of()),
33+
tempDir,
34+
List.of(),
35+
List.of(),
36+
List.of(),
37+
pathSarifMap,
38+
List.of(),
39+
List.of(),
40+
List.of(),
41+
null,
42+
null);
43+
}
44+
}

plugins/codemodder-plugin-codeql/src/test/resources/conflicting-sarifs/codeql-0.sarif

Lines changed: 51061 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)