Skip to content

Commit 73e10ce

Browse files
authored
fix: combine SrcDir with sourcepath in FindbugsParser to produce complete file paths (refs #197)
1 parent 5cb81d8 commit 73e10ce

3 files changed

Lines changed: 77 additions & 4 deletions

File tree

violations-lib/src/main/java/se/bjurr/violations/lib/parsers/FindbugsParser.java

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ private Map<String, String> getMessagesPerType(
8484
private void parseBugInstance(
8585
final XMLStreamReader xmlr,
8686
final Set<Violation> violations,
87-
final Map<String, String> messagesPerType)
87+
final Map<String, String> messagesPerType,
88+
final List<String> srcDirs)
8889
throws XMLStreamException {
8990
final String type = getAttribute(xmlr, "type");
9091
final Integer rank = getIntegerAttribute(xmlr, "rank");
@@ -105,7 +106,8 @@ private void parseBugInstance(
105106
if (!startLine.isPresent() || !endLine.isPresent()) {
106107
continue;
107108
}
108-
final String filename = getAttribute(xmlr, "sourcepath");
109+
final String sourcepath = getAttribute(xmlr, "sourcepath");
110+
final String filename = resolveFilePath(sourcepath, srcDirs);
109111
final String classname = getAttribute(xmlr, "classname");
110112
candidates.add( //
111113
violationBuilder() //
@@ -152,20 +154,50 @@ public Set<Violation> parseReportOutput(
152154
violationsLogger,
153155
this.getMessagesXml(findSecurityBugsMessagesXml, "/findbugs/fsb-messages.xml")));
154156

157+
final List<String> srcDirs = new ArrayList<>();
158+
155159
try (InputStream input = new ByteArrayInputStream(string.getBytes(StandardCharsets.UTF_8))) {
156160
final XMLStreamReader xmlr = ViolationParserUtils.createXmlReader(input);
161+
boolean inProject = false;
157162
while (xmlr.hasNext()) {
158163
final int eventType = xmlr.next();
159164
if (eventType == XMLStreamConstants.START_ELEMENT) {
160-
if (xmlr.getLocalName().equalsIgnoreCase("BugInstance")) {
161-
this.parseBugInstance(xmlr, violations, messagesPerType);
165+
if (xmlr.getLocalName().equalsIgnoreCase("Project")) {
166+
inProject = true;
167+
} else if (inProject && xmlr.getLocalName().equalsIgnoreCase("SrcDir")) {
168+
srcDirs.add(xmlr.getElementText());
169+
} else if (xmlr.getLocalName().equalsIgnoreCase("BugInstance")) {
170+
this.parseBugInstance(xmlr, violations, messagesPerType, srcDirs);
171+
}
172+
}
173+
if (eventType == XMLStreamConstants.END_ELEMENT) {
174+
if (xmlr.getLocalName().equalsIgnoreCase("Project")) {
175+
inProject = false;
162176
}
163177
}
164178
}
165179
}
166180
return violations;
167181
}
168182

183+
/**
184+
* Resolves the complete file path by combining the single {@code SrcDir} with the {@code
185+
* sourcepath}. Only applies if there is exactly one {@code SrcDir} entry in total and it is a
186+
* directory (i.e. not ending with {@code .java}); otherwise returns {@code sourcepath} unchanged.
187+
*/
188+
private String resolveFilePath(final String sourcepath, final List<String> srcDirs) {
189+
if (sourcepath == null || sourcepath.isEmpty() || srcDirs.size() != 1) {
190+
return sourcepath;
191+
}
192+
final String normalized = srcDirs.get(0).replace("\\", "/").trim();
193+
if (normalized.endsWith(".java")) {
194+
return sourcepath;
195+
}
196+
final String trimmed =
197+
normalized.endsWith("/") ? normalized.substring(0, normalized.length() - 1) : normalized;
198+
return trimmed + "/" + sourcepath;
199+
}
200+
169201
private String getMessagesXml(final String staticValue, final String messagesResourceFilename)
170202
throws IOException {
171203
String messagesXml;

violations-lib/src/test/java/se/bjurr/violations/lib/FindbugsTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,23 @@ public void testThatViolationsCanBeParsedFromSpotbugs() {
117117
.isEqualTo("20");
118118
}
119119

120+
@Test
121+
public void testThatSrcDirIsCombinedWithSourcepathWhenExactlyOneSrcDir() {
122+
final String rootFolder = getRootFolder();
123+
final Set<Violation> actual =
124+
violationsApi() //
125+
.withPattern(".*/findbugs/spotbugs-one-srcdir\\.xml$") //
126+
.inFolder(rootFolder) //
127+
.findAll(FINDBUGS) //
128+
.violations();
129+
130+
assertThat(actual) //
131+
.hasSize(1);
132+
final Violation violation0 = new ArrayList<>(actual).get(0);
133+
assertThat(violation0.getFile()) //
134+
.isEqualTo("/builds/my-project/module-a/src/main/java/com/example/Foo.java");
135+
}
136+
120137
@Test
121138
public void testThatViolationsCanBeParsedFromSpotbugs2() {
122139
final String rootFolder = getRootFolder();
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<BugCollection version="4.0.0" sequence="0" timestamp="1570255404454" analysisTimestamp="1570255404481" release="">
4+
<Project projectName="module-a">
5+
<SrcDir>/builds/my-project/module-a/src/main/java</SrcDir>
6+
</Project>
7+
<BugInstance type="MS_EXPOSE_REP" priority="1" rank="7" abbrev="MS" category="MALICIOUS_CODE">
8+
<Class classname="com.example.Foo">
9+
<SourceLine classname="com.example.Foo" start="1" end="50" sourcefile="Foo.java" sourcepath="com/example/Foo.java"/>
10+
</Class>
11+
<Method classname="com.example.Foo" name="getValues" signature="()[Ljava/lang/Object;" isStatic="false">
12+
<SourceLine classname="com.example.Foo" start="42" end="42" sourcefile="Foo.java" sourcepath="com/example/Foo.java"/>
13+
</Method>
14+
<SourceLine classname="com.example.Foo" start="42" end="42" sourcefile="Foo.java" sourcepath="com/example/Foo.java"/>
15+
</BugInstance>
16+
<Errors errors="0" missingClasses="0"></Errors>
17+
<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">
18+
<PackageStats package="com.example" total_bugs="1" total_types="1" total_size="50">
19+
<ClassStats class="com.example.Foo" sourceFile="Foo.java" interface="false" size="50" bugs="1"/>
20+
</PackageStats>
21+
</FindBugsSummary>
22+
<ClassFeatures></ClassFeatures>
23+
<History></History>
24+
</BugCollection>

0 commit comments

Comments
 (0)