Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Commit

Permalink
Merge pull request #371 from dtolnay/emptytag
Browse files Browse the repository at this point in the history
Fix deserialization of tag `!<%21>`
  • Loading branch information
dtolnay authored Apr 6, 2023
2 parents e3b9a02 + ebb4b7a commit 19a7bd3
Showing 1 changed file with 31 additions and 34 deletions.
65 changes: 31 additions & 34 deletions src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,18 @@ fn invalid_type(event: &Event, exp: &dyn Expected) -> Error {
}
}

fn parse_tag(libyaml_tag: &Option<Tag>) -> Option<&str> {
let mut bytes: &[u8] = libyaml_tag.as_ref()?;
if let (b'!', rest) = bytes.split_first()? {
if !rest.is_empty() {
bytes = rest;
}
str::from_utf8(bytes).ok()
} else {
None
}
}

impl<'de, 'document> de::Deserializer<'de> for &mut DeserializerFromEvents<'de, 'document> {
type Error = Error;

Expand All @@ -1203,11 +1215,7 @@ impl<'de, 'document> de::Deserializer<'de> for &mut DeserializerFromEvents<'de,
if tagged_already {
return None;
}
if let (b'!', tag) = tag.as_ref()?.split_first()? {
str::from_utf8(tag).ok()
} else {
None
}
parse_tag(tag)
}
loop {
match next {
Expand Down Expand Up @@ -1731,45 +1739,34 @@ impl<'de, 'document> de::Deserializer<'de> for &mut DeserializerFromEvents<'de,
.deserialize_enum(name, variants, visitor)
}
Event::Scalar(scalar) => {
if let Some((b'!', tag)) = scalar.tag.as_ref().and_then(|tag| tag.split_first())
{
if let Ok(tag) = str::from_utf8(tag) {
return visitor.visit_enum(EnumAccess {
de: self,
name: Some(name),
tag,
});
}
if let Some(tag) = parse_tag(&scalar.tag) {
return visitor.visit_enum(EnumAccess {
de: self,
name: Some(name),
tag,
});
}
visitor.visit_enum(UnitVariantAccess { de: self })
}
Event::MappingStart(mapping) => {
if let Some((b'!', tag)) =
mapping.tag.as_ref().and_then(|tag| tag.split_first())
{
if let Ok(tag) = str::from_utf8(tag) {
return visitor.visit_enum(EnumAccess {
de: self,
name: Some(name),
tag,
});
}
if let Some(tag) = parse_tag(&mapping.tag) {
return visitor.visit_enum(EnumAccess {
de: self,
name: Some(name),
tag,
});
}
let err =
de::Error::invalid_type(Unexpected::Map, &"a YAML tag starting with '!'");
Err(error::fix_mark(err, mark, self.path))
}
Event::SequenceStart(sequence) => {
if let Some((b'!', tag)) =
sequence.tag.as_ref().and_then(|tag| tag.split_first())
{
if let Ok(tag) = str::from_utf8(tag) {
return visitor.visit_enum(EnumAccess {
de: self,
name: Some(name),
tag,
});
}
if let Some(tag) = parse_tag(&sequence.tag) {
return visitor.visit_enum(EnumAccess {
de: self,
name: Some(name),
tag,
});
}
let err =
de::Error::invalid_type(Unexpected::Seq, &"a YAML tag starting with '!'");
Expand Down

0 comments on commit 19a7bd3

Please sign in to comment.