QD-1812: add sarif representation for global inspection results

cherry-picked from

GitOrigin-RevId: f20835c6b070641548526cc9007457394d364d63
This commit is contained in:
Aleksander Movsesov
2022-03-28 21:10:15 +00:00
committed by intellij-monorepo-bot
parent 2f287c8a52
commit 58a34ce898
@@ -8,6 +8,7 @@ import com.intellij.codeInspection.DefaultInspectionToolResultExporter;
import com.intellij.codeInspection.InspectionsReportConverter;
import com.intellij.codeInspection.InspectionsResultUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
@@ -21,6 +22,8 @@ import java.io.IOException;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
@@ -61,6 +64,7 @@ public class JsonInspectionsReportConverter implements InspectionsReportConverte
@NonNls private static final String HIGHLIGHTED_ELEMENT = "highlighted_element";
@NonNls public static final String DUPLICATED_CODE = "DuplicatedCode";
@NonNls public static final String DUPLICATED_CODE_AGGREGATE = DUPLICATED_CODE + InspectionsResultUtil.AGGREGATE;
@NonNls public static final String PHP_VULNERABLE_PATHS_AGGREGATE = "PhpVulnerablePathsInspection" + InspectionsResultUtil.AGGREGATE;
@Override
public String getFormatName() {
@@ -100,6 +104,9 @@ public class JsonInspectionsReportConverter implements InspectionsReportConverte
else if (DUPLICATED_CODE_AGGREGATE.equals(fileNameWithoutExt)) {
convertDuplicatedCode(jsonWriter, doc);
}
else if (PHP_VULNERABLE_PATHS_AGGREGATE.equals(fileNameWithoutExt)) {
convertPhpVulnerablePaths(jsonWriter, doc);
}
else {
convertProblems(jsonWriter, doc);
}
@@ -131,19 +138,192 @@ public class JsonInspectionsReportConverter implements InspectionsReportConverte
private static void convertDuplicateFragment(@NotNull JsonWriter jsonWriter, Element fragment) throws IOException {
jsonWriter.beginObject();
jsonWriter.name(FILE).value(fragment.getAttributeValue(FILE));
String line = fragment.getAttributeValue(LINE);
String start = fragment.getAttributeValue("start");
String end = fragment.getAttributeValue("end");
writeFileSegmentAttributes(jsonWriter, fragment);
jsonWriter.endObject();
}
private static void writeFileSegmentAttributes(@NotNull JsonWriter jsonWriter, Element fileSegment) throws IOException {
writeFileAttribute(jsonWriter, fileSegment);
writeSegmentAttributes(jsonWriter, fileSegment);
}
private static void writeFileAttribute(@NotNull JsonWriter jsonWriter, Element fileSegment) throws IOException {
jsonWriter.name(FILE).value(fileSegment.getAttributeValue(FILE));
}
private static void writeSegmentAttributes(@NotNull JsonWriter jsonWriter, Element segment) throws IOException {
String line = segment.getAttributeValue(LINE);
String start = segment.getAttributeValue("start");
String end = segment.getAttributeValue("end");
assert line != null;
assert start != null;
assert end != null;
jsonWriter.name(LINE).value(Integer.parseInt(line));
jsonWriter.name("start").value(Integer.parseInt(start));
jsonWriter.name("end").value(Integer.parseInt(end));
}
public static void convertPhpVulnerablePaths(@NotNull JsonWriter jsonWriter, @NotNull Document problems) throws IOException {
jsonWriter.beginObject();
jsonWriter.name(PROBLEMS);
jsonWriter.beginArray();
for (Element problem : problems.getRootElement().getChildren(PROBLEM)) {
convertPhpVulnerablePath(jsonWriter, problem);
}
jsonWriter.endArray();
jsonWriter.endObject();
}
public static void convertPhpVulnerablePath(@NotNull JsonWriter jsonWriter, Element problem) throws IOException {
jsonWriter.beginObject();
jsonWriter.name(DESCRIPTION).value("Vulnerable code flow");
jsonWriter.name("fragments");
jsonWriter.beginArray();
Element fragmentsElement = problem.getChild("fragments");
assert fragmentsElement != null;
for (Element fragment : fragmentsElement.getChildren("fragment")) {
convertPhpVulnerableFragment(jsonWriter, fragment);
}
jsonWriter.endArray();
convertPhpSink(jsonWriter, problem);
jsonWriter.name("sources");
jsonWriter.beginArray();
Element sourcesElement = problem.getChild("sources");
assert sourcesElement != null;
for (Element source : sourcesElement.getChildren("source")) {
convertPhpTaintSource(jsonWriter, source);
}
jsonWriter.endArray();
jsonWriter.name(LANGUAGE).value(problem.getChildText(LANGUAGE));
Element problemClassElement = problem.getChild(DefaultInspectionToolResultExporter.INSPECTION_RESULTS_PROBLEM_CLASS_ELEMENT);
if (problemClassElement != null) {
convertProblemClass(jsonWriter, problemClassElement);
}
jsonWriter.endObject();
}
private static void convertPhpSink(@NotNull JsonWriter jsonWriter, @NotNull Element problem) throws IOException {
jsonWriter.name("sink");
Element sink = problem.getChild("sink");
assert sink != null;
jsonWriter.beginObject();
jsonWriter.name("text").value(sink.getAttributeValue("text"));
String sinkFqn = sink.getAttributeValue("fqn");
if (sinkFqn != null) {
jsonWriter.name("fqn").value(sinkFqn);
}
writeOrderAttribute(jsonWriter, sink);
jsonWriter.name("vulnerabilities");
jsonWriter.beginArray();
Collection<String> vulnerabilityValues = getVulnerabilityValues(sink, "vulnerabilities");
for (String vulnerability : vulnerabilityValues) {
jsonWriter.value(vulnerability);
}
jsonWriter.endArray();
jsonWriter.name("parameters");
jsonWriter.beginArray();
String parameterName = getParameterName(sink);
if (parameterName != null) {
jsonWriter.value(parameterName);
}
jsonWriter.endArray();
jsonWriter.endObject();
}
private static void convertPhpTaintSource(@NotNull JsonWriter jsonWriter, @NotNull Element source) throws IOException {
jsonWriter.beginObject();
jsonWriter.name("text").value(source.getAttributeValue("text"));
writeFileAttribute(jsonWriter, source);
writeOrderAttribute(jsonWriter, source);
writeSanitizedVulnerabilities(jsonWriter, source);
jsonWriter.endObject();
}
private static void convertPhpVulnerableFragment(@NotNull JsonWriter jsonWriter, Element fragment) throws IOException {
jsonWriter.beginObject();
writeFileSegmentAttributes(jsonWriter, fragment);
jsonWriter.name("markers");
jsonWriter.beginArray();
for (Element marker : fragment.getChildren("marker")) {
convertPhpTaintMarker(jsonWriter, marker);
}
jsonWriter.endArray();
jsonWriter.endObject();
}
private static void convertPhpTaintMarker(@NotNull JsonWriter jsonWriter, @NotNull Element marker) throws IOException {
jsonWriter.beginObject();
writeSegmentAttributes(jsonWriter, marker);
writeOrderAttribute(jsonWriter, marker);
jsonWriter.name("successors");
jsonWriter.beginArray();
Element successorsElement = marker.getChild("successors");
if (successorsElement != null) {
Collection<String> markerOrders = ContainerUtil.map(successorsElement.getChildren("marker"), Element::getText);
for (String markerOrder : markerOrders) {
jsonWriter.value(markerOrder);
}
}
jsonWriter.endArray();
jsonWriter.name("predecessors");
jsonWriter.beginArray();
Element predecessorsElement = marker.getChild("predecessors");
if (predecessorsElement != null) {
Collection<String> markerOrders = ContainerUtil.map(predecessorsElement.getChildren("marker"), Element::getText);
for (String markerOrder : markerOrders) {
jsonWriter.value(markerOrder);
}
}
jsonWriter.endArray();
writeSanitizedVulnerabilities(jsonWriter, marker);
jsonWriter.endObject();
}
private static void writeOrderAttribute(@NotNull JsonWriter jsonWriter, @NotNull Element marker) throws IOException {
jsonWriter.name("order").value(marker.getAttributeValue("order"));
}
private static void writeSanitizedVulnerabilities(@NotNull JsonWriter jsonWriter, @NotNull Element element) throws IOException {
jsonWriter.name("sanitized_vulnerabilities");
jsonWriter.beginArray();
Collection<String> vulnerabilityValues = getVulnerabilityValues(element, "sanitized_vulnerabilities");
for (String vulnerability : vulnerabilityValues) {
jsonWriter.value(vulnerability);
}
jsonWriter.endArray();
}
@Nullable
private static String getParameterName(@NotNull Element element) {
Element parameters = element.getChild("parameters");
Collection<? extends Element> parameterElements = parameters != null ? parameters.getChildren("parameter") : null;
Element parameter = ContainerUtil.getFirstItem(parameterElements);
return parameter != null ? parameter.getAttributeValue("name") : null;
}
@NotNull
private static Collection<String> getVulnerabilityValues(@NotNull Element element,
@NotNull String vulnerabilitiesTagName) {
Element vulnerabilities = element.getChild(vulnerabilitiesTagName);
if (vulnerabilities == null) {
return Collections.emptyList();
}
return ContainerUtil.map(vulnerabilities.getChildren("vulnerability"),
vulnerability -> vulnerability.getAttributeValue("name"));
}
private static void convertProblems(@NotNull JsonWriter jsonWriter, @NotNull Document problems) throws IOException {
jsonWriter.beginObject();
jsonWriter.name(PROBLEMS);