Skip to content

Commit

Permalink
improve validation of references
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielT committed May 18, 2024
1 parent a84646b commit 393ebfd
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 20 deletions.
9 changes: 9 additions & 0 deletions autosar-data-specification/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,14 @@ impl ElementType {
None
}

/// verify that the given `dest_value` is a valid enum item that can be used to refer to this element type
#[must_use]
pub fn verify_reference_dest(&self, dest_value: EnumItem) -> bool {
let (start, end) = DATATYPES[self.typ as usize].ref_info;
let values = &REF_ITEMS[start as usize..end as usize];
values.contains(&dest_value)
}

#[cfg(feature = "docstrings")]
#[must_use]
pub const fn docstring(&self) -> &'static str {
Expand Down Expand Up @@ -1199,6 +1207,7 @@ mod test {

let ref_value = physical_request_ref_type.reference_dest_value(&ident_type).unwrap();
assert_eq!(ref_value, EnumItem::TpConnectionIdent);
assert!(ident_type.verify_reference_dest(ref_value));
let invalid_ref = physical_request_ref_type.reference_dest_value(&tp_connections_type);
assert!(invalid_ref.is_none());
}
Expand Down
12 changes: 3 additions & 9 deletions autosar-data/src/autosarmodel.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashMap, hash::Hash, str::FromStr};
use std::{collections::HashMap, hash::Hash};

use crate::*;

Expand Down Expand Up @@ -780,18 +780,12 @@ impl AutosarModel {
if let Some(target_elem) = target_elem_weak.upgrade() {
// the target of the reference exists, but the reference can still be technically invalid
// if the content of the DEST attribute on the reference is wrong
let target_elemname = target_elem.element_name();
// e.g. if the target is a <SYSTEM>, then the reference must have the attribute DEST="SYSTEM".
// Converting the ElementName of the target_elem to an EnumItem for use in the DEST attribute
// is done by converting ElementName -> str -> EnumItem
let required_reftype = EnumItem::from_str(target_elemname.to_str()).unwrap();

for referring_elem_weak in element_list {
if let Some(referring_elem) = referring_elem_weak.upgrade() {
if let Some(CharacterData::Enum(reftype)) =
if let Some(CharacterData::Enum(dest_value)) =
referring_elem.attribute_value(AttributeName::Dest)
{
if reftype != required_reftype {
if target_elem.element_type().verify_reference_dest(dest_value) {
// wrong reference type in the DEST attribute
broken_refs.push(referring_elem_weak.clone());
}
Expand Down
14 changes: 3 additions & 11 deletions autosar-data/src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,20 +836,12 @@ impl Element {
.get_element_by_path(&reference)
.ok_or(AutosarDataError::InvalidReference)?;

let dest = self
let dest_value = self
.attribute_value(AttributeName::Dest)
.map(|cdata| cdata.to_string())
.and_then(|cdata| cdata.enum_value())
.ok_or(AutosarDataError::InvalidReference)?;
if dest == target_elem.element_name().to_str() {
// common case: the value of DEST is equal to the element name of the target
if target_elem.element_type().verify_reference_dest(dest_value) {
Ok(target_elem)
} else if let Some(refval) = self.element_type().reference_dest_value(&target_elem.element_type()) {
// uncommon: find a correct DEST value in the specification
if refval.to_string() == dest {
Ok(target_elem)
} else {
Err(AutosarDataError::InvalidReference)
}
} else {
Err(AutosarDataError::InvalidReference)
}
Expand Down

0 comments on commit 393ebfd

Please sign in to comment.