Skip to content

Commit

Permalink
SONARCS-608 NPE if there are no locations in SARIF report
Browse files Browse the repository at this point in the history
  • Loading branch information
dbmeneses committed Jul 11, 2016
1 parent f9e17c4 commit 7c9f617
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 12 deletions.
35 changes: 24 additions & 11 deletions src/main/java/org/sonar/plugins/csharp/sarif/SarifParser10.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

/**
* Parser for SARIF report v1.0 (introduced in VS 2015 update 3)
*/
public class SarifParser10 implements SarifParser {
private static final String FILE_PROTOCOL = "file:///";
private String contents;
Expand All @@ -41,6 +44,9 @@ public void parse(SarifParserCallback callback) {
JsonObject root = parser.parse(contents).getAsJsonObject();
JsonElement runLogs = root.get("runs");

if (runLogs == null) {
return;
}
for (JsonElement runElement : runLogs.getAsJsonArray()) {
JsonObject run = runElement.getAsJsonObject();
JsonArray results = run.getAsJsonArray("results");
Expand All @@ -66,17 +72,24 @@ private static void handleIssue(JsonObject resultObj, SarifParserCallback callba
String message = resultObj.get("message").getAsString();

boolean hasLocation = false;
for (JsonElement locationEl : resultObj.get("locations").getAsJsonArray()) {
JsonObject locationObj = locationEl.getAsJsonObject();
if (locationObj.has("resultFile")) {
JsonObject resultFileObj = locationObj.get("resultFile").getAsJsonObject();
hasLocation = true;
String uri = resultFileObj.get("uri").getAsString();
String absolutePath = uriToAbsolutePath(uri);
JsonObject region = resultFileObj.get("region").getAsJsonObject();
int startLine = region.get("startLine").getAsInt();

callback.onIssue(ruleId, absolutePath, message, startLine);
if (resultObj.has("locations")) {
for (JsonElement locationEl : resultObj.get("locations").getAsJsonArray()) {
JsonObject locationObj = locationEl.getAsJsonObject();
if (locationObj.has("resultFile")) {
JsonObject resultFileObj = locationObj.get("resultFile").getAsJsonObject();

if (!resultFileObj.has("uri") || !resultFileObj.has("region")) {
continue;
}

String uri = resultFileObj.get("uri").getAsString();
String absolutePath = uriToAbsolutePath(uri);
JsonObject region = resultFileObj.get("region").getAsJsonObject();
int startLine = region.get("startLine").getAsInt();

callback.onIssue(ruleId, absolutePath, message, startLine);
hasLocation = true;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void sarif_version_1_0() throws IOException {
verify(callback, Mockito.times(2)).onIssue(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyInt());
}
}

@Test
public void sarif_version_1_0_no_location() throws IOException {
SarifParserCallback callback = mock(SarifParserCallback.class);
Expand All @@ -66,6 +66,19 @@ public void sarif_version_1_0_no_location() throws IOException {
}
}

@Test
public void sarif_version_1_0_empty_location() throws IOException {
SarifParserCallback callback = mock(SarifParserCallback.class);
new SarifParser10(getContents("v1_0_empty_location.json")).parse(callback);

if (SystemUtils.IS_OS_WINDOWS) {
InOrder inOrder = inOrder(callback);
inOrder.verify(callback).onProjectIssue("S1234", "One issue per line");
verify(callback, Mockito.times(1)).onProjectIssue(anyString(), anyString());
verifyNoMoreInteractions(callback);
}
}

@Test
public void sarif_version_1_0_more_rules() throws IOException {
SarifParserCallback callback = mock(SarifParserCallback.class);
Expand Down
37 changes: 37 additions & 0 deletions src/test/resources/SarifParserTest/v1_0_empty_location.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"$schema": "http://json.schemastore.org/sarif-1.0.0",
"version": "1.0.0",
"runs": [
{
"tool": {
"name": "Microsoft (R) Visual C# Compiler",
"version": "1.3.1.0",
"fileVersion": "1.3.1.60616",
"semanticVersion": "1.3.1",
"language": "en-US"
},
"results": [
{
"ruleId": "S1234",
"level": "warning",
"message": "One issue per line",
"properties": {
"warningLevel": 1
}
}
],
"rules": {
"S1234": {
"id": "S1234",
"shortDescription": "One issue per line",
"fullDescription": "This rule will create an issue for every source code line",
"defaultLevel": "warning",
"properties": {
"category": "Test",
"isEnabledByDefault": true
}
}
}
}
]
}

0 comments on commit 7c9f617

Please sign in to comment.