Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ private Map<String, String> getMessagesPerType(
private void parseBugInstance(
final XMLStreamReader xmlr,
final Set<Violation> violations,
final Map<String, String> messagesPerType)
final Map<String, String> messagesPerType,
final List<String> srcDirs)
throws XMLStreamException {
final String type = getAttribute(xmlr, "type");
final Integer rank = getIntegerAttribute(xmlr, "rank");
Expand All @@ -105,7 +106,8 @@ private void parseBugInstance(
if (!startLine.isPresent() || !endLine.isPresent()) {
continue;
}
final String filename = getAttribute(xmlr, "sourcepath");
final String sourcepath = getAttribute(xmlr, "sourcepath");
final String filename = resolveFilePath(sourcepath, srcDirs);
final String classname = getAttribute(xmlr, "classname");
candidates.add( //
violationBuilder() //
Expand Down Expand Up @@ -152,20 +154,50 @@ public Set<Violation> parseReportOutput(
violationsLogger,
this.getMessagesXml(findSecurityBugsMessagesXml, "/findbugs/fsb-messages.xml")));

final List<String> srcDirs = new ArrayList<>();

try (InputStream input = new ByteArrayInputStream(string.getBytes(StandardCharsets.UTF_8))) {
final XMLStreamReader xmlr = ViolationParserUtils.createXmlReader(input);
boolean inProject = false;
while (xmlr.hasNext()) {
final int eventType = xmlr.next();
if (eventType == XMLStreamConstants.START_ELEMENT) {
if (xmlr.getLocalName().equalsIgnoreCase("BugInstance")) {
this.parseBugInstance(xmlr, violations, messagesPerType);
if (xmlr.getLocalName().equalsIgnoreCase("Project")) {
inProject = true;
} else if (inProject && xmlr.getLocalName().equalsIgnoreCase("SrcDir")) {
srcDirs.add(xmlr.getElementText());
} else if (xmlr.getLocalName().equalsIgnoreCase("BugInstance")) {
this.parseBugInstance(xmlr, violations, messagesPerType, srcDirs);
}
}
if (eventType == XMLStreamConstants.END_ELEMENT) {
if (xmlr.getLocalName().equalsIgnoreCase("Project")) {
inProject = false;
}
}
}
}
return violations;
}

/**
* Resolves the complete file path by combining the single {@code SrcDir} with the {@code
* sourcepath}. Only applies if there is exactly one {@code SrcDir} entry in total and it is a
* directory (i.e. not ending with {@code .java}); otherwise returns {@code sourcepath} unchanged.
*/
private String resolveFilePath(final String sourcepath, final List<String> srcDirs) {
if (sourcepath == null || sourcepath.isEmpty() || srcDirs.size() != 1) {
return sourcepath;
}
final String normalized = srcDirs.get(0).replace("\\", "/").trim();
if (normalized.endsWith(".java")) {
return sourcepath;
}
final String trimmed =
normalized.endsWith("/") ? normalized.substring(0, normalized.length() - 1) : normalized;
return trimmed + "/" + sourcepath;
}

private String getMessagesXml(final String staticValue, final String messagesResourceFilename)
throws IOException {
String messagesXml;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,23 @@ public void testThatViolationsCanBeParsedFromSpotbugs() {
.isEqualTo("20");
}

@Test
public void testThatSrcDirIsCombinedWithSourcepathWhenExactlyOneSrcDir() {
final String rootFolder = getRootFolder();
final Set<Violation> actual =
violationsApi() //
.withPattern(".*/findbugs/spotbugs-one-srcdir\\.xml$") //
.inFolder(rootFolder) //
.findAll(FINDBUGS) //
.violations();

assertThat(actual) //
.hasSize(1);
final Violation violation0 = new ArrayList<>(actual).get(0);
assertThat(violation0.getFile()) //
.isEqualTo("/builds/my-project/module-a/src/main/java/com/example/Foo.java");
}

@Test
public void testThatViolationsCanBeParsedFromSpotbugs2() {
final String rootFolder = getRootFolder();
Expand Down
24 changes: 24 additions & 0 deletions violations-lib/src/test/resources/findbugs/spotbugs-one-srcdir.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>

<BugCollection version="4.0.0" sequence="0" timestamp="1570255404454" analysisTimestamp="1570255404481" release="">
<Project projectName="module-a">
<SrcDir>/builds/my-project/module-a/src/main/java</SrcDir>
</Project>
<BugInstance type="MS_EXPOSE_REP" priority="1" rank="7" abbrev="MS" category="MALICIOUS_CODE">
<Class classname="com.example.Foo">
<SourceLine classname="com.example.Foo" start="1" end="50" sourcefile="Foo.java" sourcepath="com/example/Foo.java"/>
</Class>
<Method classname="com.example.Foo" name="getValues" signature="()[Ljava/lang/Object;" isStatic="false">
<SourceLine classname="com.example.Foo" start="42" end="42" sourcefile="Foo.java" sourcepath="com/example/Foo.java"/>
</Method>
<SourceLine classname="com.example.Foo" start="42" end="42" sourcefile="Foo.java" sourcepath="com/example/Foo.java"/>
</BugInstance>
<Errors errors="0" missingClasses="0"></Errors>
<FindBugsSummary timestamp="Wed, 12 Sep 2018 18:19:36 +0200" total_classes="1" referenced_classes="1" total_bugs="1" total_size="50" num_packages="1" java_version="1.8.0" vm_version="25.0" cpu_seconds="1.00" clock_seconds="1.00" peak_mbytes="100.00" alloc_mbytes="512.00" gc_seconds="0.01" priority_1="1">
<PackageStats package="com.example" total_bugs="1" total_types="1" total_size="50">
<ClassStats class="com.example.Foo" sourceFile="Foo.java" interface="false" size="50" bugs="1"/>
</PackageStats>
</FindBugsSummary>
<ClassFeatures></ClassFeatures>
<History></History>
</BugCollection>