Skip to content

Commit 184cfea

Browse files
authored
Merge pull request #1071 from DependencyTrack/issue-1684-support-protobuf-format-bom-upload
Accept BOM uploads in Protobuf format
2 parents cf2744a + 816c5c1 commit 184cfea

File tree

8 files changed

+1162
-31
lines changed

8 files changed

+1162
-31
lines changed

src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidator.java

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222
import com.fasterxml.jackson.core.JsonParseException;
2323
import com.fasterxml.jackson.core.JsonToken;
2424
import com.fasterxml.jackson.databind.json.JsonMapper;
25+
import com.google.protobuf.InvalidProtocolBufferException;
26+
import jakarta.ws.rs.core.MediaType;
2527
import org.cyclonedx.Version;
2628
import org.cyclonedx.exception.ParseException;
2729
import org.cyclonedx.parsers.JsonParser;
2830
import org.cyclonedx.parsers.Parser;
2931
import org.cyclonedx.parsers.XmlParser;
32+
import org.cyclonedx.proto.v1_6.Bom;
3033

3134
import javax.xml.XMLConstants;
3235
import javax.xml.stream.XMLInputFactory;
@@ -72,24 +75,42 @@ public static CycloneDxValidator getInstance() {
7275
}
7376

7477
public void validate(final byte[] bomBytes) {
75-
final FormatAndVersion formatAndVersion = detectFormatAndSchemaVersion(bomBytes);
76-
77-
final Parser bomParser = switch (formatAndVersion.format()) {
78-
case JSON -> new JsonParser();
79-
case XML -> new XmlParser();
80-
};
81-
82-
final List<ParseException> validationErrors;
83-
try {
84-
validationErrors = bomParser.validate(bomBytes, formatAndVersion.version());
85-
} catch (IOException e) {
86-
throw new RuntimeException("Failed to validate BOM", e);
87-
}
78+
validate(bomBytes, null);
79+
}
8880

89-
if (!validationErrors.isEmpty()) {
90-
throw new InvalidBomException("Schema validation failed", validationErrors.stream()
91-
.map(ParseException::getMessage)
92-
.toList());
81+
public void validate(final byte[] bomBytes, MediaType mediaType) {
82+
// Validating protobuf format
83+
if (mediaType != null && mediaType.toString().equalsIgnoreCase("application/x.vnd.cyclonedx+protobuf")) {
84+
try {
85+
final var bom = Bom.parseFrom(bomBytes);
86+
switch (bom.getSpecVersion()) {
87+
case "1.0", "1.1", "1.2", "1.3", "1.4" ->
88+
throw new InvalidBomException("Protobuf is not supported for specVersion %s".formatted(bom.getSpecVersion()));
89+
case "1.5", "1.6" -> {}
90+
default ->
91+
throw new InvalidBomException("Unrecognized specVersion %s".formatted(bom.getSpecVersion()));
92+
}
93+
} catch (InvalidProtocolBufferException e) {
94+
throw new InvalidBomException("Protobuf Schema validation failed", e);
95+
}
96+
} else {
97+
// Validating JSON/XML format
98+
final FormatAndVersion formatAndVersion = detectFormatAndSchemaVersion(bomBytes);
99+
final Parser bomParser = switch (formatAndVersion.format()) {
100+
case JSON -> new JsonParser();
101+
case XML -> new XmlParser();
102+
};
103+
final List<ParseException> validationErrors;
104+
try {
105+
validationErrors = bomParser.validate(bomBytes, formatAndVersion.version());
106+
} catch (IOException e) {
107+
throw new RuntimeException("Failed to validate BOM", e);
108+
}
109+
if (!validationErrors.isEmpty()) {
110+
throw new InvalidBomException("Schema validation failed", validationErrors.stream()
111+
.map(ParseException::getMessage)
112+
.toList());
113+
}
93114
}
94115
}
95116

0 commit comments

Comments
 (0)