Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/target
**/target
.idea
*.iml
19 changes: 19 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[workspace]
members = ["csaf-validator", "csaf-rs"]
members = ["csaf-validator", "csaf-rs", "type-generator"]
resolver = "2"
1 change: 1 addition & 0 deletions csaf-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ prettyplease = "0.2"
thiserror = "2"
json_dotpath = "1"
quote = "1"
proc-macro2 = "1"
60 changes: 1 addition & 59 deletions csaf-rs/build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use json_dotpath::DotPaths;
use quote::quote;
use serde_json::{Value, json};
use serde_json::Value;
use std::path::Path;
use std::string::ToString;
use std::{fs, io};
Expand All @@ -26,16 +25,6 @@ fn main() -> Result<(), BuildError> {

// All schema files for change watching
let schema_configs = [
(
"assets/csaf_2.0_json_schema.json",
"csaf2_0/schema.generated.rs",
Some(&fix_2_0_schema as &dyn Fn(&mut Value)),
),
(
"assets/csaf_2.1_json_schema.json",
"csaf2_1/schema.generated.rs",
Some(&fix_2_1_schema),
),
(
"assets/decision_point_json_schema.json",
"csaf2_1/ssvc_dp.generated.rs",
Expand Down Expand Up @@ -112,53 +101,6 @@ fn build(input: &str, output: &str, schema_patch: &Option<&dyn Fn(&mut Value)>)
Ok(fs::write(out_file, content)?)
}

/// Patches (unsupported) external schemas to the plain object type for CSAF 2.0.
fn fix_2_0_schema(value: &mut Value) {
let prefix = "properties.vulnerabilities.items.properties.scores.items.properties";
let fix_paths = [format!("{}.cvss_v2", prefix), format!("{}.cvss_v3", prefix)];
for path in fix_paths {
value.dot_set(path.as_str(), json!({"type": "object"})).unwrap();
}
remove_datetime_formats(value);
}

/// Patches (unsupported) external schemas to the plain object type for CSAF 2.1.
fn fix_2_1_schema(value: &mut Value) {
let prefix = "properties.vulnerabilities.items.properties.metrics.items.properties.content.properties";
let fix_paths = [
format!("{}.cvss_v2", prefix),
format!("{}.cvss_v3", prefix),
format!("{}.cvss_v4", prefix),
format!("{}.ssvc_v1", prefix),
format!("{}.ssvc_v2", prefix),
];
for path in fix_paths {
value.dot_set(path.as_str(), json!({"type": "object"})).unwrap();
}
remove_datetime_formats(value);
}

/// Recursively searches for "format": "date-time" and removes this format.
fn remove_datetime_formats(value: &mut Value) {
if let Value::Object(map) = value {
if let Some(format) = map.get("format") {
if format.as_str() == Some("date-time") {
// Remove the format property entirely
map.remove("format");
}
}

// Recursively process all values in the object
for (_, v) in map.iter_mut() {
remove_datetime_formats(v);
}
} else if let Value::Array(arr) = value {
for item in arr.iter_mut() {
remove_datetime_formats(item);
}
}
}

/// Compile-time-embedded language-subtag-registry.txt
const LANGUAGE_REGISTRY: &str = include_str!("assets/language-subtag-registry.txt");

Expand Down
6 changes: 3 additions & 3 deletions csaf-rs/src/csaf2_0/csaf_implementations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ use crate::csaf_traits::{
ThreatTrait, TlpTrait, TrackingTrait, VulnerabilityIdTrait, VulnerabilityTrait, WithOptionalGroupIds,
WithOptionalProductIds,
};
use crate::csaf2_0::schema::{
use crate::csaf2_1::ssvc_dp_selection_list::SelectionList;
use crate::schema::csaf2_0::schema::{
Branch, CategoryOfPublisher, CategoryOfReference, CategoryOfTheRemediation, CategoryOfTheThreat,
CommonSecurityAdvisoryFramework, CryptographicHashes, CsafVersion as CsafVersion20, DocumentGenerator,
DocumentLevelMetaData, DocumentStatus, FileHash, Flag, FullProductNameT, HelperToIdentifyTheProduct, Id,
Involvement, LabelOfTheFlag, LabelOfTlp, Note, NoteCategory, PartyCategory, ProductGroup, ProductStatus,
ProductTree, Publisher, Reference, Relationship, Remediation, Revision, RulesForSharingDocument, Score, Threat,
Tracking, TrafficLightProtocolTlp, Vulnerability,
};
use crate::csaf2_1::schema::{
use crate::schema::csaf2_1::schema::{
CategoryOfPublisher as CategoryOfPublisher21, CategoryOfReference as CategoryOfReference21,
CategoryOfTheRemediation as Remediation21, CategoryOfTheThreat as CategoryOfTheThreat21,
DocumentStatus as Status21, Epss, LabelOfTheFlag as LabelOfTheFlag21, LabelOfTlp as Tlp21,
NoteCategory as NoteCategory21, PartyCategory as PartyCategory21,
};
use crate::csaf2_1::ssvc_dp_selection_list::SelectionList;
use crate::validation::ValidationError;
use serde::de::Error;
use serde_json::{Map, Value};
Expand Down
4 changes: 2 additions & 2 deletions csaf-rs/src/csaf2_0/loader.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::schema::CommonSecurityAdvisoryFramework;
use crate::schema::csaf2_0::schema::CommonSecurityAdvisoryFramework;
use std::{fs::File, io::BufReader};

pub fn load_document(path: &str) -> std::io::Result<CommonSecurityAdvisoryFramework> {
Expand All @@ -20,7 +20,7 @@ pub fn load_document_from_str(json_str: &str) -> std::io::Result<CommonSecurityA

#[cfg(test)]
mod tests {
use crate::csaf2_0::schema::{
use crate::schema::csaf2_0::schema::{
CategoryOfPublisher, CommonSecurityAdvisoryFramework, DocumentLevelMetaData, Publisher, Revision, Tracking,
};

Expand Down
5 changes: 3 additions & 2 deletions csaf-rs/src/csaf2_0/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod csaf_implementations;
pub mod loader;
#[path = "schema.generated.rs"]
pub mod schema;
pub mod test_structure_impl;
#[path = "testcases.generated.rs"]
pub mod testcases;
pub mod validation;
35 changes: 35 additions & 0 deletions csaf-rs/src/csaf2_0/test_structure_impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use crate::test_structure::{TestCase, TestCasesSchemaDocument, TestDocument, TestGroup};

impl TestCasesSchemaDocument for crate::schema::csaf2_0::testcases_schema::TestCasesForCsaf {
type TestCase = crate::schema::csaf2_0::testcases_schema::TestT;
fn tests(&self) -> Vec<Self::TestCase> {
self.tests.clone()
}
}
impl TestCase for crate::schema::csaf2_0::testcases_schema::TestT {
type Document = crate::schema::csaf2_0::testcases_schema::FileT;
fn id(&self) -> &str {
&self.id
}
fn group(&self) -> TestGroup {
match self.group {
crate::schema::csaf2_0::testcases_schema::TestGroup::Mandatory => TestGroup::Mandatory,
crate::schema::csaf2_0::testcases_schema::TestGroup::Optional => TestGroup::Recommended,
crate::schema::csaf2_0::testcases_schema::TestGroup::Informative => TestGroup::Informative,
}
}
fn failures(&self) -> Vec<Self::Document> {
self.failures.clone()
}
fn valid(&self) -> Option<Vec<Self::Document>> {
self.valid.clone()
}
}
impl TestDocument for crate::schema::csaf2_0::testcases_schema::FileT {
fn name(&self) -> &str {
&self.name
}
fn valid(&self) -> bool {
self.valid
}
}
Loading