From d41b8c80d5d5f43a3b7c719ebacbe6383982a435 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Wed, 17 Jul 2024 03:46:40 +0100 Subject: [PATCH 1/6] Make SpecVersion enum exhaustive Signed-off-by: Sergey "Shnatsel" Davidoff --- cyclonedx-bom/src/models/bom.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/cyclonedx-bom/src/models/bom.rs b/cyclonedx-bom/src/models/bom.rs index c05b0993..23c7d3f9 100644 --- a/cyclonedx-bom/src/models/bom.rs +++ b/cyclonedx-bom/src/models/bom.rs @@ -46,8 +46,6 @@ use super::vulnerability::Vulnerability; /// Represents the spec version of a BOM. #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy, PartialOrd, strum::Display)] -#[repr(u16)] -#[non_exhaustive] pub enum SpecVersion { #[strum(to_string = "1.3")] #[serde(rename = "1.3")] From 607a43fcb7f85d3b4d6376fc009ea70786c305fd Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Wed, 17 Jul 2024 04:25:26 +0100 Subject: [PATCH 2/6] Drop obsolete comments Signed-off-by: Sergey "Shnatsel" Davidoff --- cyclonedx-bom/src/models/bom.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/cyclonedx-bom/src/models/bom.rs b/cyclonedx-bom/src/models/bom.rs index 23c7d3f9..c1071eda 100644 --- a/cyclonedx-bom/src/models/bom.rs +++ b/cyclonedx-bom/src/models/bom.rs @@ -153,11 +153,6 @@ impl Bom { reader: R, version: SpecVersion, ) -> Result { - // While the SpecVersion enum is non-exhaustive in the public API - // (and it probably shouldn't be!), we can match exhaustively here - // which avoids issues which crop up when the API user has to match: - // https://github.com/CycloneDX/cyclonedx-rust-cargo/pull/722 - // https://github.com/CycloneDX/cyclonedx-rust-cargo/pull/723 match version { SpecVersion::V1_3 => Self::parse_from_json_v1_3(reader), SpecVersion::V1_4 => Self::parse_from_json_v1_4(reader), @@ -171,8 +166,6 @@ impl Bom { writer: &mut W, version: SpecVersion, ) -> Result<(), crate::errors::JsonWriteError> { - // See `parse_from_json_with_version` for an explanation - // why we do this match here and why API users shouldn't do it match version { SpecVersion::V1_3 => self.output_as_json_v1_3(writer), SpecVersion::V1_4 => self.output_as_json_v1_4(writer), @@ -185,8 +178,6 @@ impl Bom { reader: R, version: SpecVersion, ) -> Result { - // See `parse_from_json_with_version` for an explanation - // why we do this match here and why API users shouldn't do it match version { SpecVersion::V1_3 => Self::parse_from_xml_v1_3(reader), SpecVersion::V1_4 => Self::parse_from_xml_v1_4(reader), @@ -200,8 +191,6 @@ impl Bom { writer: &mut W, version: SpecVersion, ) -> Result<(), crate::errors::XmlWriteError> { - // See `parse_from_json_with_version` for an explanation - // why we do this match here and why API users shouldn't do it match version { SpecVersion::V1_3 => self.output_as_xml_v1_3(writer), SpecVersion::V1_4 => self.output_as_xml_v1_4(writer), From 46cdbb1bcc5e44cd73ad8be2ce847d1af368d813 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Wed, 17 Jul 2024 05:07:26 +0100 Subject: [PATCH 3/6] Move test-only schema stuff to a separate crate, which is only included as a dev-dependency Signed-off-by: Sergey "Shnatsel" Davidoff --- Cargo.lock | 596 +++--------------- cyclonedx-bom/Cargo.toml | 2 +- cyclonedx-bom/src/lib.rs | 1 - cyclonedx-bom/src/schema.rs | 157 ----- cyclonedx-bom/test-utils/Cargo.toml | 10 + .../schema/bom-1.3.schema.json | 0 .../schema/bom-1.4.schema.json | 0 .../schema/bom-1.5.schema.json | 0 .../schema/jsf-0.82.schema.json | 0 .../{ => test-utils}/schema/spdx.schema.json | 0 cyclonedx-bom/test-utils/src/lib.rs | 159 +++++ 11 files changed, 248 insertions(+), 677 deletions(-) delete mode 100644 cyclonedx-bom/src/schema.rs create mode 100644 cyclonedx-bom/test-utils/Cargo.toml rename cyclonedx-bom/{ => test-utils}/schema/bom-1.3.schema.json (100%) rename cyclonedx-bom/{ => test-utils}/schema/bom-1.4.schema.json (100%) rename cyclonedx-bom/{ => test-utils}/schema/bom-1.5.schema.json (100%) rename cyclonedx-bom/{ => test-utils}/schema/jsf-0.82.schema.json (100%) rename cyclonedx-bom/{ => test-utils}/schema/spdx.schema.json (100%) create mode 100644 cyclonedx-bom/test-utils/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index bce3ca73..4dae9421 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,21 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "ahash" version = "0.8.11" @@ -130,21 +115,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "backtrace" -version = "0.3.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - [[package]] name = "base64" version = "0.21.5" @@ -200,21 +170,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecount" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" - -[[package]] -name = "bytes" -version = "1.6.0" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "camino" @@ -285,12 +249,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cc" -version = "1.0.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" - [[package]] name = "cfg-if" version = "1.0.0" @@ -355,22 +313,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - [[package]] name = "cyclonedx-bom" version = "0.6.1" @@ -380,7 +322,6 @@ dependencies = [ "fluent-uri", "indexmap", "insta", - "jsonschema", "once_cell", "ordered-float", "packageurl", @@ -390,6 +331,7 @@ dependencies = [ "serde_json", "spdx", "strum", + "test-utils", "thiserror", "time", "uuid", @@ -445,15 +387,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" -[[package]] -name = "encoding_rs" -version = "0.8.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" -dependencies = [ - "cfg-if", -] - [[package]] name = "env_logger" version = "0.10.1" @@ -542,54 +475,6 @@ dependencies = [ "num", ] -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-core", - "futures-io", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - [[package]] name = "getrandom" version = "0.2.11" @@ -603,12 +488,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - [[package]] name = "glob" version = "0.3.1" @@ -639,25 +518,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "h2" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "hashbrown" version = "0.14.3" @@ -682,70 +542,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "hyper" -version = "0.14.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "idna" version = "0.4.0" @@ -809,12 +611,6 @@ dependencies = [ "yaml-rust", ] -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - [[package]] name = "is-terminal" version = "0.4.9" @@ -869,7 +665,6 @@ dependencies = [ "anyhow", "base64", "bytecount", - "clap", "fancy-regex", "fraction", "getrandom", @@ -881,7 +676,6 @@ dependencies = [ "parking_lot", "percent-encoding", "regex", - "reqwest", "serde", "serde_json", "time", @@ -915,9 +709,9 @@ checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -935,38 +729,12 @@ version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "minimal-lexical" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", -] - [[package]] name = "nom" version = "7.1.3" @@ -985,9 +753,9 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "num" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ "num-bigint", "num-complex", @@ -999,11 +767,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -1016,9 +783,9 @@ checksum = "63335b2e2c34fae2fb0aa2cecfd9f0832a1e24b3b32ecec612c3426d46dc8aaa" [[package]] name = "num-complex" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] @@ -1040,9 +807,9 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -1051,11 +818,10 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", "num-bigint", "num-integer", "num-traits", @@ -1063,22 +829,13 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.18.0" @@ -1106,9 +863,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1116,15 +873,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -1186,18 +943,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "pin-project-lite" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "powerfmt" version = "0.2.0" @@ -1300,6 +1045,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.4.1", +] + [[package]] name = "regex" version = "1.10.2" @@ -1329,48 +1083,6 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustix" version = "0.38.21" @@ -1460,18 +1172,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - [[package]] name = "similar" version = "2.3.0" @@ -1484,31 +1184,12 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - [[package]] name = "smallvec" version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" -[[package]] -name = "socket2" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "spdx" version = "0.10.6" @@ -1557,33 +1238,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tempfile" version = "3.8.1" @@ -1592,7 +1246,7 @@ checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", + "redox_syscall 0.4.1", "rustix", "windows-sys 0.48.0", ] @@ -1612,6 +1266,15 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" +[[package]] +name = "test-utils" +version = "0.1.0" +dependencies = [ + "cyclonedx-bom", + "jsonschema", + "serde_json", +] + [[package]] name = "thiserror" version = "1.0.57" @@ -1688,35 +1351,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" -[[package]] -name = "tokio" -version = "1.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-util" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - [[package]] name = "toml" version = "0.7.8" @@ -1751,37 +1385,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - [[package]] name = "trybuild" version = "1.0.86" @@ -1893,15 +1496,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1933,18 +1527,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.92" @@ -1974,16 +1556,6 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" -[[package]] -name = "web-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "winapi" version = "0.3.9" @@ -2033,15 +1605,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.4", -] - [[package]] name = "windows-targets" version = "0.42.2" @@ -2074,17 +1637,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2101,9 +1665,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -2119,9 +1683,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -2137,9 +1701,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -2155,9 +1725,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -2173,9 +1743,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -2191,9 +1761,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -2209,9 +1779,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -2222,16 +1792,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "xml-rs" version = "0.8.19" @@ -2255,18 +1815,18 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", diff --git a/cyclonedx-bom/Cargo.toml b/cyclonedx-bom/Cargo.toml index 26a51624..f3582ca0 100644 --- a/cyclonedx-bom/Cargo.toml +++ b/cyclonedx-bom/Cargo.toml @@ -17,7 +17,6 @@ rust-version.workspace = true base64 = "0.21.2" fluent-uri = "0.1.4" indexmap = "2.2.2" -jsonschema = "0.17.1" once_cell = "1.18.0" ordered-float = { version = "4.2.0", default-features = false } packageurl = "0.3.0" @@ -35,3 +34,4 @@ strum = { version = "0.26.2", features = ["derive"] } [dev-dependencies] insta = { version = "1.33.0", features = ["glob", "json"] } pretty_assertions = "1.4.0" +test-utils = {path = "test-utils"} diff --git a/cyclonedx-bom/src/lib.rs b/cyclonedx-bom/src/lib.rs index 2640ead3..d57b8cef 100644 --- a/cyclonedx-bom/src/lib.rs +++ b/cyclonedx-bom/src/lib.rs @@ -126,7 +126,6 @@ pub mod errors; pub mod external_models; pub mod models; pub mod prelude; -pub mod schema; pub mod validation; mod specs; diff --git a/cyclonedx-bom/src/schema.rs b/cyclonedx-bom/src/schema.rs deleted file mode 100644 index b4ec2cbb..00000000 --- a/cyclonedx-bom/src/schema.rs +++ /dev/null @@ -1,157 +0,0 @@ -/* - * This file is part of CycloneDX Rust Cargo. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -use jsonschema::{error::ValidationErrorKind, paths::JSONPointer, JSONSchema}; - -use crate::models::bom::SpecVersion; - -#[derive(Debug)] -pub struct ValidationError { - pub instance: String, - pub kind: ValidationErrorKind, - pub hierarchy: Vec, -} - -impl ValidationError { - pub fn new(instance: String, kind: ValidationErrorKind, hierarchy: JSONPointer) -> Self { - let hierarchy = hierarchy - .iter() - .map(|chunk| format!("{:?}", chunk)) - .collect::>(); - dbg!(&hierarchy); - - Self { - instance, - kind, - hierarchy, - } - } -} - -/// Validates a [`serde_json::Value`] against a JSON schema defined by the given [`SpecVersion`]. -/// -/// This function returns the list of validation errors if something fails. -/// -/// ## Example -/// -/// ```rust -/// use cyclonedx_bom::prelude::*; -/// use cyclonedx_bom::schema::validate_json_with_schema; -/// -/// let bom_json = r#"{ -/// "bomFormat": "CycloneDX", -/// "specVersion": "1.3", -/// "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", -/// "version": 1 -/// }"#; -/// let json: serde_json::Value = serde_json::from_str(bom_json).expect("Failed to parse JSON"); -/// let result = validate_json_with_schema(&json, SpecVersion::V1_3); -/// assert!(result.is_ok()); -/// ``` -/// -pub fn validate_json_with_schema( - json: &serde_json::Value, - version: SpecVersion, -) -> Result<(), Vec> { - let spdx_schema = include_str!("../schema/spdx.schema.json"); - let spdx_schema: serde_json::Value = - serde_json::from_str(spdx_schema).expect("Failed to read spdx.schema.json"); - let jsf_schema = include_str!("../schema/jsf-0.82.schema.json"); - let jsf_schema: serde_json::Value = - serde_json::from_str(jsf_schema).expect("Failed to load jsf-0.82.schema.json"); - - let schema = match version { - SpecVersion::V1_3 => include_str!("../schema/bom-1.3.schema.json"), - SpecVersion::V1_4 => include_str!("../schema/bom-1.4.schema.json"), - SpecVersion::V1_5 => include_str!("../schema/bom-1.5.schema.json"), - }; - let schema: serde_json::Value = - serde_json::from_str(schema).expect("Failed to parse JSON schema file"); - - // Fill in external schema files, handle unknown format(s) - let compiled_schema = JSONSchema::options() - .with_draft(jsonschema::Draft::Draft7) - .with_document( - "http://cyclonedx.org/schema/spdx.schema.json".to_string(), - spdx_schema, - ) - .with_document( - "http://cyclonedx.org/schema/jsf-0.82.schema.json".to_string(), - jsf_schema, - ) - .with_format("idn-email", with_idn_email) - .compile(&schema) - .expect("Failed to compile JSON schema file"); - - let result = compiled_schema.validate(json); - if let Err(errors) = result { - let errors = errors.collect::>(); - dbg!(&errors); - } - compiled_schema.validate(json).map_err(|iter| { - iter.map(|err| ValidationError::new(err.instance.to_string(), err.kind, err.instance_path)) - .collect::>() - }) -} - -/// For now ignore the content of the given email string. -fn with_idn_email(_s: &str) -> bool { - true -} - -#[cfg(test)] -mod test { - use crate::{models::bom::SpecVersion, schema::validate_json_with_schema}; - - #[test] - fn it_should_validate_version_13() { - let input = r#" -{ - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "version": 1, - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "components": [ - { - "type": "library", - "name": "acme-library-a", - "version": "1.0.0", - "components": [ - { - "type": "library", - "name": "acme-library-b", - "version": "2.0.0" - } - ] - } - ], - "services": [ - { - "name": "acme-service-a", - "services": [ - { - "name": "acme-service-b" - } - ] - } - ] -}"#; - let json = serde_json::from_str(input).expect("Failed to parse JSON"); - assert!(validate_json_with_schema(&json, SpecVersion::V1_3).is_ok()); - } -} diff --git a/cyclonedx-bom/test-utils/Cargo.toml b/cyclonedx-bom/test-utils/Cargo.toml new file mode 100644 index 00000000..adf06c9e --- /dev/null +++ b/cyclonedx-bom/test-utils/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "test-utils" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +jsonschema = { version = "0.17.1", default-features = false } +cyclonedx-bom = { path = ".." } +serde_json = "1.0.108" \ No newline at end of file diff --git a/cyclonedx-bom/schema/bom-1.3.schema.json b/cyclonedx-bom/test-utils/schema/bom-1.3.schema.json similarity index 100% rename from cyclonedx-bom/schema/bom-1.3.schema.json rename to cyclonedx-bom/test-utils/schema/bom-1.3.schema.json diff --git a/cyclonedx-bom/schema/bom-1.4.schema.json b/cyclonedx-bom/test-utils/schema/bom-1.4.schema.json similarity index 100% rename from cyclonedx-bom/schema/bom-1.4.schema.json rename to cyclonedx-bom/test-utils/schema/bom-1.4.schema.json diff --git a/cyclonedx-bom/schema/bom-1.5.schema.json b/cyclonedx-bom/test-utils/schema/bom-1.5.schema.json similarity index 100% rename from cyclonedx-bom/schema/bom-1.5.schema.json rename to cyclonedx-bom/test-utils/schema/bom-1.5.schema.json diff --git a/cyclonedx-bom/schema/jsf-0.82.schema.json b/cyclonedx-bom/test-utils/schema/jsf-0.82.schema.json similarity index 100% rename from cyclonedx-bom/schema/jsf-0.82.schema.json rename to cyclonedx-bom/test-utils/schema/jsf-0.82.schema.json diff --git a/cyclonedx-bom/schema/spdx.schema.json b/cyclonedx-bom/test-utils/schema/spdx.schema.json similarity index 100% rename from cyclonedx-bom/schema/spdx.schema.json rename to cyclonedx-bom/test-utils/schema/spdx.schema.json diff --git a/cyclonedx-bom/test-utils/src/lib.rs b/cyclonedx-bom/test-utils/src/lib.rs new file mode 100644 index 00000000..9ba49da1 --- /dev/null +++ b/cyclonedx-bom/test-utils/src/lib.rs @@ -0,0 +1,159 @@ +/* + * This file is part of CycloneDX Rust Cargo. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + use jsonschema::{error::ValidationErrorKind, paths::JSONPointer, JSONSchema}; + + use cyclonedx_bom::models::bom::SpecVersion; + + #[derive(Debug)] + pub struct ValidationError { + pub instance: String, + pub kind: ValidationErrorKind, + pub hierarchy: Vec, + } + + impl ValidationError { + pub fn new(instance: String, kind: ValidationErrorKind, hierarchy: JSONPointer) -> Self { + let hierarchy = hierarchy + .iter() + .map(|chunk| format!("{:?}", chunk)) + .collect::>(); + dbg!(&hierarchy); + + Self { + instance, + kind, + hierarchy, + } + } + } + + /// Validates a [`serde_json::Value`] against a JSON schema defined by the given [`SpecVersion`]. + /// + /// This function returns the list of validation errors if something fails. + /// + /// ## Example + /// + /// ```rust + /// use cyclonedx_bom::prelude::*; + /// use cyclonedx_bom::schema::validate_json_with_schema; + /// + /// let bom_json = r#"{ + /// "bomFormat": "CycloneDX", + /// "specVersion": "1.3", + /// "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + /// "version": 1 + /// }"#; + /// let json: serde_json::Value = serde_json::from_str(bom_json).expect("Failed to parse JSON"); + /// let result = validate_json_with_schema(&json, SpecVersion::V1_3); + /// assert!(result.is_ok()); + /// ``` + /// + pub fn validate_json_with_schema( + json: &serde_json::Value, + version: SpecVersion, + ) -> Result<(), Vec> { + let spdx_schema = include_str!("../schema/spdx.schema.json"); + let spdx_schema: serde_json::Value = + serde_json::from_str(spdx_schema).expect("Failed to read spdx.schema.json"); + let jsf_schema = include_str!("../schema/jsf-0.82.schema.json"); + let jsf_schema: serde_json::Value = + serde_json::from_str(jsf_schema).expect("Failed to load jsf-0.82.schema.json"); + + let schema = match version { + SpecVersion::V1_3 => include_str!("../schema/bom-1.3.schema.json"), + SpecVersion::V1_4 => include_str!("../schema/bom-1.4.schema.json"), + SpecVersion::V1_5 => include_str!("../schema/bom-1.5.schema.json"), + }; + let schema: serde_json::Value = + serde_json::from_str(schema).expect("Failed to parse JSON schema file"); + + // Fill in external schema files, handle unknown format(s) + let compiled_schema = JSONSchema::options() + .with_draft(jsonschema::Draft::Draft7) + .with_document( + "http://cyclonedx.org/schema/spdx.schema.json".to_string(), + spdx_schema, + ) + .with_document( + "http://cyclonedx.org/schema/jsf-0.82.schema.json".to_string(), + jsf_schema, + ) + .with_format("idn-email", with_idn_email) + .compile(&schema) + .expect("Failed to compile JSON schema file"); + + let result = compiled_schema.validate(json); + if let Err(errors) = result { + let errors = errors.collect::>(); + dbg!(&errors); + } + compiled_schema.validate(json).map_err(|iter| { + iter.map(|err| ValidationError::new(err.instance.to_string(), err.kind, err.instance_path)) + .collect::>() + }) + } + + /// For now ignore the content of the given email string. + fn with_idn_email(_s: &str) -> bool { + true + } + + #[cfg(test)] + mod test { + use super::validate_json_with_schema; + use cyclonedx_bom::models::bom::SpecVersion; + + #[test] + fn it_should_validate_version_13() { + let input = r#" + { + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "version": 1, + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "components": [ + { + "type": "library", + "name": "acme-library-a", + "version": "1.0.0", + "components": [ + { + "type": "library", + "name": "acme-library-b", + "version": "2.0.0" + } + ] + } + ], + "services": [ + { + "name": "acme-service-a", + "services": [ + { + "name": "acme-service-b" + } + ] + } + ] + }"#; + let json = serde_json::from_str(input).expect("Failed to parse JSON"); + assert!(validate_json_with_schema(&json, SpecVersion::V1_3).is_ok()); + } + } + \ No newline at end of file From 6d2b9f407c3f497e88155494d41679a4ef7db860 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Wed, 17 Jul 2024 05:11:31 +0100 Subject: [PATCH 4/6] Convert integration tests to using the test crate Signed-off-by: Sergey "Shnatsel" Davidoff --- cyclonedx-bom/test-utils/src/lib.rs | 2 +- cyclonedx-bom/tests/specification_tests_v1_3.rs | 2 +- cyclonedx-bom/tests/specification_tests_v1_4.rs | 2 +- cyclonedx-bom/tests/specification_tests_v1_5.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cyclonedx-bom/test-utils/src/lib.rs b/cyclonedx-bom/test-utils/src/lib.rs index 9ba49da1..9ddab640 100644 --- a/cyclonedx-bom/test-utils/src/lib.rs +++ b/cyclonedx-bom/test-utils/src/lib.rs @@ -51,7 +51,7 @@ /// /// ```rust /// use cyclonedx_bom::prelude::*; - /// use cyclonedx_bom::schema::validate_json_with_schema; + /// use test_utils::validate_json_with_schema; /// /// let bom_json = r#"{ /// "bomFormat": "CycloneDX", diff --git a/cyclonedx-bom/tests/specification_tests_v1_3.rs b/cyclonedx-bom/tests/specification_tests_v1_3.rs index 58a017b9..0eba0fd1 100644 --- a/cyclonedx-bom/tests/specification_tests_v1_3.rs +++ b/cyclonedx-bom/tests/specification_tests_v1_3.rs @@ -1,6 +1,6 @@ mod v1_3 { use cyclonedx_bom::models::bom::{Bom, SpecVersion}; - use cyclonedx_bom::schema::validate_json_with_schema; + use test_utils::validate_json_with_schema; use cyclonedx_bom::validation::Validate; #[test] diff --git a/cyclonedx-bom/tests/specification_tests_v1_4.rs b/cyclonedx-bom/tests/specification_tests_v1_4.rs index dddef408..57b77e0b 100644 --- a/cyclonedx-bom/tests/specification_tests_v1_4.rs +++ b/cyclonedx-bom/tests/specification_tests_v1_4.rs @@ -1,6 +1,6 @@ mod v1_4 { use cyclonedx_bom::models::bom::{Bom, SpecVersion}; - use cyclonedx_bom::schema::validate_json_with_schema; + use test_utils::validate_json_with_schema; use cyclonedx_bom::validation::Validate; #[test] diff --git a/cyclonedx-bom/tests/specification_tests_v1_5.rs b/cyclonedx-bom/tests/specification_tests_v1_5.rs index a928d014..fc3d2d7c 100644 --- a/cyclonedx-bom/tests/specification_tests_v1_5.rs +++ b/cyclonedx-bom/tests/specification_tests_v1_5.rs @@ -1,6 +1,6 @@ mod v1_5 { use cyclonedx_bom::models::bom::{Bom, SpecVersion}; - use cyclonedx_bom::schema::validate_json_with_schema; + use test_utils::validate_json_with_schema; use cyclonedx_bom::validation::Validate; #[test] From 4e4a8fd9f4fa6480959ecc090c28a9b968130842 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Wed, 17 Jul 2024 05:13:25 +0100 Subject: [PATCH 5/6] Do not publish all our test data to crates.io. It is useless when cyclonedx-bom is fetched as a dependency. Brings down the tarball size from 3MB to somethig sane. Signed-off-by: Sergey "Shnatsel" Davidoff --- cyclonedx-bom/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/cyclonedx-bom/Cargo.toml b/cyclonedx-bom/Cargo.toml index f3582ca0..1be06bf1 100644 --- a/cyclonedx-bom/Cargo.toml +++ b/cyclonedx-bom/Cargo.toml @@ -5,6 +5,7 @@ description = "CycloneDX Software Bill of Materials Library" categories = ["encoding", "parser-implementations"] keywords = ["sbom", "bom", "components", "dependencies", "owasp"] readme = "README.md" +exclude = ["tests/", "test-utils/"] authors.workspace = true edition.workspace = true From edee7b6cd66e1c526af01e7a6c3b54345cf730f4 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Wed, 17 Jul 2024 05:24:06 +0100 Subject: [PATCH 6/6] cargo fmt Signed-off-by: Sergey "Shnatsel" Davidoff --- cyclonedx-bom/test-utils/src/lib.rs | 215 +++++++++--------- .../tests/specification_tests_v1_3.rs | 2 +- .../tests/specification_tests_v1_4.rs | 2 +- .../tests/specification_tests_v1_5.rs | 2 +- 4 files changed, 110 insertions(+), 111 deletions(-) diff --git a/cyclonedx-bom/test-utils/src/lib.rs b/cyclonedx-bom/test-utils/src/lib.rs index 9ddab640..02149693 100644 --- a/cyclonedx-bom/test-utils/src/lib.rs +++ b/cyclonedx-bom/test-utils/src/lib.rs @@ -16,112 +16,112 @@ * SPDX-License-Identifier: Apache-2.0 */ - use jsonschema::{error::ValidationErrorKind, paths::JSONPointer, JSONSchema}; +use jsonschema::{error::ValidationErrorKind, paths::JSONPointer, JSONSchema}; - use cyclonedx_bom::models::bom::SpecVersion; - - #[derive(Debug)] - pub struct ValidationError { - pub instance: String, - pub kind: ValidationErrorKind, - pub hierarchy: Vec, - } - - impl ValidationError { - pub fn new(instance: String, kind: ValidationErrorKind, hierarchy: JSONPointer) -> Self { - let hierarchy = hierarchy - .iter() - .map(|chunk| format!("{:?}", chunk)) - .collect::>(); - dbg!(&hierarchy); - - Self { - instance, - kind, - hierarchy, - } - } - } - - /// Validates a [`serde_json::Value`] against a JSON schema defined by the given [`SpecVersion`]. - /// - /// This function returns the list of validation errors if something fails. - /// - /// ## Example - /// - /// ```rust - /// use cyclonedx_bom::prelude::*; - /// use test_utils::validate_json_with_schema; - /// - /// let bom_json = r#"{ - /// "bomFormat": "CycloneDX", - /// "specVersion": "1.3", - /// "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - /// "version": 1 - /// }"#; - /// let json: serde_json::Value = serde_json::from_str(bom_json).expect("Failed to parse JSON"); - /// let result = validate_json_with_schema(&json, SpecVersion::V1_3); - /// assert!(result.is_ok()); - /// ``` - /// - pub fn validate_json_with_schema( - json: &serde_json::Value, - version: SpecVersion, - ) -> Result<(), Vec> { - let spdx_schema = include_str!("../schema/spdx.schema.json"); - let spdx_schema: serde_json::Value = - serde_json::from_str(spdx_schema).expect("Failed to read spdx.schema.json"); - let jsf_schema = include_str!("../schema/jsf-0.82.schema.json"); - let jsf_schema: serde_json::Value = - serde_json::from_str(jsf_schema).expect("Failed to load jsf-0.82.schema.json"); - - let schema = match version { - SpecVersion::V1_3 => include_str!("../schema/bom-1.3.schema.json"), - SpecVersion::V1_4 => include_str!("../schema/bom-1.4.schema.json"), - SpecVersion::V1_5 => include_str!("../schema/bom-1.5.schema.json"), - }; - let schema: serde_json::Value = - serde_json::from_str(schema).expect("Failed to parse JSON schema file"); - - // Fill in external schema files, handle unknown format(s) - let compiled_schema = JSONSchema::options() - .with_draft(jsonschema::Draft::Draft7) - .with_document( - "http://cyclonedx.org/schema/spdx.schema.json".to_string(), - spdx_schema, - ) - .with_document( - "http://cyclonedx.org/schema/jsf-0.82.schema.json".to_string(), - jsf_schema, - ) - .with_format("idn-email", with_idn_email) - .compile(&schema) - .expect("Failed to compile JSON schema file"); - - let result = compiled_schema.validate(json); - if let Err(errors) = result { - let errors = errors.collect::>(); - dbg!(&errors); - } - compiled_schema.validate(json).map_err(|iter| { - iter.map(|err| ValidationError::new(err.instance.to_string(), err.kind, err.instance_path)) - .collect::>() - }) - } - - /// For now ignore the content of the given email string. - fn with_idn_email(_s: &str) -> bool { - true - } - - #[cfg(test)] - mod test { +use cyclonedx_bom::models::bom::SpecVersion; + +#[derive(Debug)] +pub struct ValidationError { + pub instance: String, + pub kind: ValidationErrorKind, + pub hierarchy: Vec, +} + +impl ValidationError { + pub fn new(instance: String, kind: ValidationErrorKind, hierarchy: JSONPointer) -> Self { + let hierarchy = hierarchy + .iter() + .map(|chunk| format!("{:?}", chunk)) + .collect::>(); + dbg!(&hierarchy); + + Self { + instance, + kind, + hierarchy, + } + } +} + +/// Validates a [`serde_json::Value`] against a JSON schema defined by the given [`SpecVersion`]. +/// +/// This function returns the list of validation errors if something fails. +/// +/// ## Example +/// +/// ```rust +/// use cyclonedx_bom::prelude::*; +/// use test_utils::validate_json_with_schema; +/// +/// let bom_json = r#"{ +/// "bomFormat": "CycloneDX", +/// "specVersion": "1.3", +/// "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", +/// "version": 1 +/// }"#; +/// let json: serde_json::Value = serde_json::from_str(bom_json).expect("Failed to parse JSON"); +/// let result = validate_json_with_schema(&json, SpecVersion::V1_3); +/// assert!(result.is_ok()); +/// ``` +/// +pub fn validate_json_with_schema( + json: &serde_json::Value, + version: SpecVersion, +) -> Result<(), Vec> { + let spdx_schema = include_str!("../schema/spdx.schema.json"); + let spdx_schema: serde_json::Value = + serde_json::from_str(spdx_schema).expect("Failed to read spdx.schema.json"); + let jsf_schema = include_str!("../schema/jsf-0.82.schema.json"); + let jsf_schema: serde_json::Value = + serde_json::from_str(jsf_schema).expect("Failed to load jsf-0.82.schema.json"); + + let schema = match version { + SpecVersion::V1_3 => include_str!("../schema/bom-1.3.schema.json"), + SpecVersion::V1_4 => include_str!("../schema/bom-1.4.schema.json"), + SpecVersion::V1_5 => include_str!("../schema/bom-1.5.schema.json"), + }; + let schema: serde_json::Value = + serde_json::from_str(schema).expect("Failed to parse JSON schema file"); + + // Fill in external schema files, handle unknown format(s) + let compiled_schema = JSONSchema::options() + .with_draft(jsonschema::Draft::Draft7) + .with_document( + "http://cyclonedx.org/schema/spdx.schema.json".to_string(), + spdx_schema, + ) + .with_document( + "http://cyclonedx.org/schema/jsf-0.82.schema.json".to_string(), + jsf_schema, + ) + .with_format("idn-email", with_idn_email) + .compile(&schema) + .expect("Failed to compile JSON schema file"); + + let result = compiled_schema.validate(json); + if let Err(errors) = result { + let errors = errors.collect::>(); + dbg!(&errors); + } + compiled_schema.validate(json).map_err(|iter| { + iter.map(|err| ValidationError::new(err.instance.to_string(), err.kind, err.instance_path)) + .collect::>() + }) +} + +/// For now ignore the content of the given email string. +fn with_idn_email(_s: &str) -> bool { + true +} + +#[cfg(test)] +mod test { use super::validate_json_with_schema; use cyclonedx_bom::models::bom::SpecVersion; - - #[test] - fn it_should_validate_version_13() { - let input = r#" + + #[test] + fn it_should_validate_version_13() { + let input = r#" { "bomFormat": "CycloneDX", "specVersion": "1.3", @@ -152,8 +152,7 @@ } ] }"#; - let json = serde_json::from_str(input).expect("Failed to parse JSON"); - assert!(validate_json_with_schema(&json, SpecVersion::V1_3).is_ok()); - } - } - \ No newline at end of file + let json = serde_json::from_str(input).expect("Failed to parse JSON"); + assert!(validate_json_with_schema(&json, SpecVersion::V1_3).is_ok()); + } +} diff --git a/cyclonedx-bom/tests/specification_tests_v1_3.rs b/cyclonedx-bom/tests/specification_tests_v1_3.rs index 0eba0fd1..3ca17aa1 100644 --- a/cyclonedx-bom/tests/specification_tests_v1_3.rs +++ b/cyclonedx-bom/tests/specification_tests_v1_3.rs @@ -1,7 +1,7 @@ mod v1_3 { use cyclonedx_bom::models::bom::{Bom, SpecVersion}; - use test_utils::validate_json_with_schema; use cyclonedx_bom::validation::Validate; + use test_utils::validate_json_with_schema; #[test] fn it_should_parse_all_of_the_valid_xml_specifications() { diff --git a/cyclonedx-bom/tests/specification_tests_v1_4.rs b/cyclonedx-bom/tests/specification_tests_v1_4.rs index 57b77e0b..83d15331 100644 --- a/cyclonedx-bom/tests/specification_tests_v1_4.rs +++ b/cyclonedx-bom/tests/specification_tests_v1_4.rs @@ -1,7 +1,7 @@ mod v1_4 { use cyclonedx_bom::models::bom::{Bom, SpecVersion}; - use test_utils::validate_json_with_schema; use cyclonedx_bom::validation::Validate; + use test_utils::validate_json_with_schema; #[test] fn it_should_parse_all_of_the_valid_xml_specifications() { diff --git a/cyclonedx-bom/tests/specification_tests_v1_5.rs b/cyclonedx-bom/tests/specification_tests_v1_5.rs index fc3d2d7c..0f1f57d5 100644 --- a/cyclonedx-bom/tests/specification_tests_v1_5.rs +++ b/cyclonedx-bom/tests/specification_tests_v1_5.rs @@ -1,7 +1,7 @@ mod v1_5 { use cyclonedx_bom::models::bom::{Bom, SpecVersion}; - use test_utils::validate_json_with_schema; use cyclonedx_bom::validation::Validate; + use test_utils::validate_json_with_schema; #[test] fn it_should_parse_all_of_the_valid_xml_specifications() {