Skip to content

Commit

Permalink
Improve JSON validation (#317)
Browse files Browse the repository at this point in the history
Improve JSON validation, in particular if you don't specify the
specification version.

This helps to address
#221.

On the given example, it will result in:
```
cyclonedx.exe validate --input-file badType_log4j_2.17.2_cyclonedx_1.3_sbom.json
Validation failed: Value is "boolean" but should be "string"
#/properties/dependencies/items/$ref/properties/ref/type
On instance: #/dependencies/0/ref:
True
Unable to validate against any JSON schemas.
BOM is not valid.
```

Signed-off-by: andreas hilti <andreas.hilti@bluewin.ch>
Co-authored-by: Michael Tsfoni <80639729+mtsfoni@users.noreply.github.com>
  • Loading branch information
andreas-hilti and mtsfoni authored Aug 11, 2024
1 parent 91cf6c6 commit 4f578ad
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 15 deletions.
23 changes: 8 additions & 15 deletions src/cyclonedx/Commands/ValidateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using System.CommandLine.Invocation;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CycloneDX.Models;
Expand Down Expand Up @@ -106,25 +107,17 @@ public static async Task<int> Validate(ValidateCommandOptions options)
}
else if (options.InputFormat == ValidationBomFormat.json)
{
validationResult = Json.Validator.Validate(inputBom, SpecificationVersion.v1_5);
if (!validationResult.Valid)
{
validationResult = Json.Validator.Validate(inputBom, SpecificationVersion.v1_4);
}
if (!validationResult.Valid)
{
validationResult = Json.Validator.Validate(inputBom, SpecificationVersion.v1_3);
}
if (!validationResult.Valid)
{
validationResult = Json.Validator.Validate(inputBom, SpecificationVersion.v1_2);
}
validationResult = Json.Validator.Validate(inputBom);

if (!validationResult.Valid)
{
validationResult.Messages = new List<string>
if (validationResult.Messages == null)
{
validationResult.Messages = new List<string>();
}
validationResult.Messages = validationResult.Messages.Append(
"Unable to validate against any JSON schemas."
};
);
}
}

Expand Down
178 changes: 178 additions & 0 deletions tests/cyclonedx.tests/Resources/bom-1.4-invalid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"version": 1,
"invalidAttribute": 2,
"metadata": {
"timestamp": "2020-04-13T20:20:39+00:00",
"tools": [
{
"vendor": "Awesome Vendor",
"name": "Awesome Tool",
"version": "9.1.2",
"hashes": [
{
"alg": "SHA-1",
"content": "25ed8e31b995bb927966616df2a42b979a2717f0"
},
{
"alg": "SHA-256",
"content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df"
}
]
}
],
"authors": [
{
"name": "Samantha Wright",
"email": "samantha.wright@example.com",
"phone": "800-555-1212"
}
],
"component": {
"type": "application",
"author": "Acme Super Heros",
"name": "Acme Application",
"version": "9.1.1",
"swid": {
"tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1",
"name": "Acme Application",
"version": "9.1.1",
"text": {
"contentType": "text/xml",
"encoding": "base64",
"content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg=="
}
}
},
"manufacture": {
"name": "Acme, Inc.",
"url": [
"https://example.com"
],
"contact": [
{
"name": "Acme Professional Services",
"email": "professional.services@example.com"
}
]
},
"supplier": {
"name": "Acme, Inc.",
"url": [
"https://example.com"
],
"contact": [
{
"name": "Acme Distribution",
"email": "distribution@example.com"
}
]
}
},
"components": [
{
"bom-ref": "pkg:npm/acme/component@1.0.0",
"type": "library",
"publisher": "Acme Inc",
"group": "com.acme",
"name": "tomcat-catalina",
"version": "9.0.14",
"hashes": [
{
"alg": "MD5",
"content": "3942447fac867ae5cdb3229b658f4d48"
},
{
"alg": "SHA-1",
"content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a"
},
{
"alg": "SHA-256",
"content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b"
},
{
"alg": "SHA-512",
"content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282"
}
],
"licenses": [
{
"license": {
"id": "Apache-2.0",
"text": {
"contentType": "text/plain",
"encoding": "base64",
"content": "License text here"
},
"url": "https://www.apache.org/licenses/LICENSE-2.0.txt"
}
}
],
"purl": "pkg:npm/acme/component@1.0.0",
"pedigree": {
"ancestors": [
{
"type": "library",
"publisher": "Acme Inc",
"group": "com.acme",
"name": "tomcat-catalina",
"version": "9.0.14"
},
{
"type": "library",
"publisher": "Acme Inc",
"group": "com.acme",
"name": "tomcat-catalina",
"version": "9.0.14"
}
],
"commits": [
{
"uid": "123",
"url": "",
"author": {
"timestamp": "2018-11-13T20:20:39+00:00",
"name": "",
"email": "example@example.com"
}
}
]
}
},
{
"type": "library",
"supplier": {
"name": "Example, Inc.",
"url": [
"https://example.com",
"https://example.net"
],
"contact": [
{
"name": "Example Support AMER Distribution",
"email": "support@example.com",
"phone": "800-555-1212"
},
{
"name": "Example Support APAC",
"email": "support@apac.example.com"
}
]
},
"author": "Example Super Heros",
"group": "org.example",
"name": "mylibrary",
"version": "1.0.0"
}
],
"dependencies": [
{
"ref": "pkg:npm/acme/component@1.0.0",
"dependsOn": [
"pkg:npm/acme/component@1.0.0"
]
}
]
}
3 changes: 3 additions & 0 deletions tests/cyclonedx.tests/ValidateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ public class ValidateTests

[InlineData("bom-1.4.json", ValidationBomFormat.autodetect, null, true)]
[InlineData("bom-1.4.json", ValidationBomFormat.json, SpecificationVersion.v1_4, true)]

[InlineData("bom-1.4-invalid.json", ValidationBomFormat.autodetect, null, false)]
[InlineData("bom-1.4-invalid.json", ValidationBomFormat.json, SpecificationVersion.v1_4, false)]

[InlineData("bom-1.5.json", ValidationBomFormat.autodetect, null, true)]
[InlineData("bom-1.5.json", ValidationBomFormat.json, SpecificationVersion.v1_5, true)]
Expand Down

0 comments on commit 4f578ad

Please sign in to comment.