From ed50beb4282bfd4240bbb44042d9d3e17c937607 Mon Sep 17 00:00:00 2001 From: Jochen Hoenle <173445474+hoe-jo@users.noreply.github.com> Date: Tue, 21 Jul 2026 11:00:06 +0200 Subject: [PATCH] [validator] check correct diagram schema before opening --- .../component/component_diagram.fbs | 3 +++ .../component/component_serializer.rs | 2 +- .../core/src/readers/class_diagram_reader.rs | 8 +++++++ .../src/readers/component_diagram_reader.rs | 22 ++++++------------- .../src/readers/sequence_diagram_reader.rs | 8 +++++++ 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/tools/serialization/flatbuffers/component/component_diagram.fbs b/tools/serialization/flatbuffers/component/component_diagram.fbs index ce0afae8..e320b426 100644 --- a/tools/serialization/flatbuffers/component/component_diagram.fbs +++ b/tools/serialization/flatbuffers/component/component_diagram.fbs @@ -84,3 +84,6 @@ table ComponentGraph { } root_type ComponentGraph; + +file_identifier "COMD"; +file_extension "comd"; diff --git a/tools/serialization/flatbuffers/component/component_serializer.rs b/tools/serialization/flatbuffers/component/component_serializer.rs index 85d9dafc..526cdaee 100644 --- a/tools/serialization/flatbuffers/component/component_serializer.rs +++ b/tools/serialization/flatbuffers/component/component_serializer.rs @@ -123,7 +123,7 @@ impl ComponentSerializer { // -------------------------- // 4) finish // -------------------------- - builder.finish(root, None); + builder.finish(root, Some("COMD")); builder.finished_data().to_vec() } diff --git a/validation/core/src/readers/class_diagram_reader.rs b/validation/core/src/readers/class_diagram_reader.rs index b93b29c4..af6f9c42 100644 --- a/validation/core/src/readers/class_diagram_reader.rs +++ b/validation/core/src/readers/class_diagram_reader.rs @@ -304,6 +304,14 @@ impl Reader for ClassDiagramReader { for path in input { let data = fs::read(path).map_err(|e| format!("Failed to read {path}: {e}"))?; + // The PlantUML parser auto-detects diagram kind; a `.puml` may end up parsed + // as a different type (e.g. Component). Skip mismatched buffers instead of + // letting the verifier fail on misaligned data. + if !fb_class::class_diagram_buffer_has_identifier(&data) { + log::warn!("{path}: not a class-diagram, skipping validation"); + continue; + } + let diagram = flatbuffers::root::(&data) .map_err(|e| format!("Failed to parse class FlatBuffer {path}: {e}"))?; diff --git a/validation/core/src/readers/component_diagram_reader.rs b/validation/core/src/readers/component_diagram_reader.rs index 357c0b2b..239329bd 100644 --- a/validation/core/src/readers/component_diagram_reader.rs +++ b/validation/core/src/readers/component_diagram_reader.rs @@ -90,27 +90,19 @@ impl ComponentDiagramReader { /// Read all `Component` and `Package` entities from the given FlatBuffers /// binary files. /// - /// Files that carry a known non-component file identifier (e.g. `CLSD` for - /// class diagrams or `SEQD` for sequence diagrams) are silently skipped so - /// that callers can pass all architectural-design FlatBuffers without - /// pre-filtering by diagram type. + /// Files that don't carry the component-diagram file identifier (`COMD`) — + /// e.g. because the PlantUML source was auto-detected as a class, sequence, + /// or other diagram type — are silently skipped so that callers can pass + /// all architectural-design FlatBuffers without pre-filtering by diagram type. pub fn read(paths: &[String]) -> Result { let mut out = Vec::new(); for path in paths { let data = fs::read(path).map_err(|e| format!("Failed to read {path}: {e}"))?; - // FlatBuffers stores the file identifier at bytes 4-7 when one is - // present. Component diagrams are written without an identifier - // (builder.finish(root, None)), so bytes 4-7 are regular data. - // Class diagrams ("CLSD") and sequence diagrams ("SEQD") carry an - // explicit identifier. Skip such files here; they are not - // component diagrams and must not be parsed with the component schema. - if data.len() >= 8 { - let file_id = &data[4..8]; - if file_id == b"CLSD" || file_id == b"SEQD" { - continue; - } + if !fb_component::component_graph_buffer_has_identifier(&data) { + log::warn!("{path}: not a component-diagram, skipping validation"); + continue; } let graph = flatbuffers::root::(&data) diff --git a/validation/core/src/readers/sequence_diagram_reader.rs b/validation/core/src/readers/sequence_diagram_reader.rs index 68400ae8..aa4f24da 100644 --- a/validation/core/src/readers/sequence_diagram_reader.rs +++ b/validation/core/src/readers/sequence_diagram_reader.rs @@ -36,6 +36,14 @@ impl Reader for SequenceDiagramReader { for path in input { let data = fs::read(path).map_err(|e| format!("Failed to read {path}: {e}"))?; + // See the analogous check in class_diagram_reader.rs: skip a buffer that + // doesn't match this schema instead of letting the verifier fail on + // misaligned data. + if !fb_sequence::sequence_diagram_buffer_has_identifier(&data) { + log::warn!("{path}: not a sequence-diagram, skipping validation"); + continue; + } + let diagram = flatbuffers::root::(&data) .map_err(|e| format!("Failed to parse sequence FlatBuffer {path}: {e}"))?;