|
22 | 22 | import com.fasterxml.jackson.core.JsonParseException;
|
23 | 23 | import com.fasterxml.jackson.core.JsonToken;
|
24 | 24 | import com.fasterxml.jackson.databind.json.JsonMapper;
|
| 25 | +import com.google.protobuf.InvalidProtocolBufferException; |
| 26 | +import jakarta.ws.rs.core.MediaType; |
25 | 27 | import org.cyclonedx.Version;
|
26 | 28 | import org.cyclonedx.exception.ParseException;
|
27 | 29 | import org.cyclonedx.parsers.JsonParser;
|
28 | 30 | import org.cyclonedx.parsers.Parser;
|
29 | 31 | import org.cyclonedx.parsers.XmlParser;
|
| 32 | +import org.cyclonedx.proto.v1_6.Bom; |
30 | 33 |
|
31 | 34 | import javax.xml.XMLConstants;
|
32 | 35 | import javax.xml.stream.XMLInputFactory;
|
@@ -72,24 +75,42 @@ public static CycloneDxValidator getInstance() {
|
72 | 75 | }
|
73 | 76 |
|
74 | 77 | 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 | + } |
88 | 80 |
|
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 | + } |
93 | 114 | }
|
94 | 115 | }
|
95 | 116 |
|
|
0 commit comments