Skip to content

Commit

Permalink
Merge pull request #203 from anweiss/fix-173
Browse files Browse the repository at this point in the history
Fix CBOR tag validation in arrays
  • Loading branch information
anweiss authored Aug 2, 2023
2 parents 0fa29c3 + 92f4e15 commit fe02060
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 10 deletions.
42 changes: 36 additions & 6 deletions src/validator/cbor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ impl<'a> CBORValidator<'a> {
}
ArrayItemToken::Group(group) => cv.visit_group(group)?,
ArrayItemToken::Identifier(ident) => cv.visit_identifier(ident)?,
ArrayItemToken::TaggedData(tagged_data) => cv.visit_type2(tagged_data)?,
}

if self.is_multi_type_choice && cv.errors.is_empty() {
Expand Down Expand Up @@ -471,6 +472,7 @@ impl<'a> CBORValidator<'a> {
}
ArrayItemToken::Group(group) => cv.visit_group(group)?,
ArrayItemToken::Identifier(ident) => cv.visit_identifier(ident)?,
ArrayItemToken::TaggedData(tagged_data) => cv.visit_type2(tagged_data)?,
}

self.errors.append(&mut cv.errors);
Expand Down Expand Up @@ -1073,8 +1075,7 @@ where
}
Type2::Array { group, .. } => {
if let Value::Array(_) = &self.cbor {
let entry_counts = entry_counts_from_group(self.cddl, group);
self.entry_counts = Some(entry_counts);
self.entry_counts = Some(entry_counts_from_group(self.cddl, group));
self.visit_type2(controller)?;
self.entry_counts = None;
return Ok(());
Expand Down Expand Up @@ -1728,8 +1729,7 @@ where
return Ok(());
}

let entry_counts = entry_counts_from_group(self.cddl, group);
self.entry_counts = Some(entry_counts);
self.entry_counts = Some(entry_counts_from_group(self.cddl, group));
self.visit_group(group)?;
self.entry_counts = None;

Expand All @@ -1753,8 +1753,7 @@ where
Value::Map(m) if self.is_member_key => {
let current_location = self.cbor_location.clone();

let entry_counts = entry_counts_from_group(self.cddl, group);
self.entry_counts = Some(entry_counts);
self.entry_counts = Some(entry_counts_from_group(self.cddl, group));

for (k, v) in m.iter() {
#[cfg(all(feature = "additional-controls", target_arch = "wasm32"))]
Expand Down Expand Up @@ -2030,6 +2029,7 @@ where
self.errors.append(&mut cv.errors);
Ok(())
}
Value::Array(_) => self.validate_array_items(&ArrayItemToken::TaggedData(t2)),
_ => {
if let Some(tag) = tag {
self.add_error(format!(
Expand Down Expand Up @@ -3873,4 +3873,34 @@ mod tests {

Ok(())
}

#[test]
fn tagged_data_in_array_validation() -> std::result::Result<(), Box<dyn std::error::Error>> {
use ciborium::value::Value;

let cddl = indoc!(
r#"
start = [ * help ]
help = #6.123(bstr)
"#
);

let cddl = cddl_from_str(cddl, true).map_err(json::Error::CDDLParsing);
if let Err(e) = &cddl {
println!("{}", e);
}

let cbor = Value::Array(vec![Value::Tag(
123,
Box::from(Value::Bytes(base16::decode("00").unwrap())),
)]);

let cddl = cddl.unwrap();

let mut cv = CBORValidator::new(&cddl, cbor, None);
cv.validate()?;

Ok(())
}
}
8 changes: 4 additions & 4 deletions src/validator/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ impl<'a> JSONValidator<'a> {
}
ArrayItemToken::Group(group) => jv.visit_group(group)?,
ArrayItemToken::Identifier(ident) => jv.visit_identifier(ident)?,
_ => (),
}

if self.is_multi_type_choice && jv.errors.is_empty() {
Expand Down Expand Up @@ -462,6 +463,7 @@ impl<'a> JSONValidator<'a> {
}
ArrayItemToken::Group(group) => jv.visit_group(group)?,
ArrayItemToken::Identifier(ident) => jv.visit_identifier(ident)?,
_ => (),
}

self.errors.append(&mut jv.errors);
Expand Down Expand Up @@ -1169,8 +1171,7 @@ impl<'a, 'b> Visitor<'a, 'b, Error> for JSONValidator<'a> {
}
Type2::Array { group, .. } => {
if let Value::Array(_) = &self.json {
let entry_counts = entry_counts_from_group(self.cddl, group);
self.entry_counts = Some(entry_counts);
self.entry_counts = Some(entry_counts_from_group(self.cddl, group));
self.visit_type2(controller)?;
self.entry_counts = None;
return Ok(());
Expand Down Expand Up @@ -1582,8 +1583,7 @@ impl<'a, 'b> Visitor<'a, 'b, Error> for JSONValidator<'a> {
return Ok(());
}

let entry_counts = entry_counts_from_group(self.cddl, group);
self.entry_counts = Some(entry_counts);
self.entry_counts = Some(entry_counts_from_group(self.cddl, group));
self.visit_group(group)?;
self.entry_counts = None;

Expand Down
11 changes: 11 additions & 0 deletions src/validator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,7 @@ pub enum ArrayItemToken<'a> {
Range(&'a Type2<'a>, &'a Type2<'a>, bool),
Group(&'a Group<'a>),
Identifier(&'a Identifier<'a>),
TaggedData(&'a Type2<'a>),
}

#[allow(missing_docs)]
Expand Down Expand Up @@ -1141,6 +1142,16 @@ impl ArrayItemToken<'_> {
format!("expected type {}", ident)
}
}
ArrayItemToken::TaggedData(tagged_data) => {
if let Some(idx) = idx {
format!(
"expected tagged data tag {:?} at index {}",
tagged_data, idx
)
} else {
format!("expected tagged data {:?}", tagged_data)
}
}
}
}
}
Expand Down

0 comments on commit fe02060

Please sign in to comment.