Skip to content

Commit

Permalink
Merge pull request #140 from rakaly/no-panic
Browse files Browse the repository at this point in the history
Fix panic for multiple text deserialization value calls
  • Loading branch information
nickbabcock authored Dec 15, 2023
2 parents 797c26e + 78d5bf1 commit 761debd
Showing 1 changed file with 57 additions and 10 deletions.
67 changes: 57 additions & 10 deletions src/text/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ where
.map(Some)
} else if !self.at_remainder && !self.fields.remainder().is_empty() {
self.at_remainder = true;
self.value = None;
seed.deserialize(StaticDeserializer("remainder")).map(Some)
} else {
Ok(None)
Expand All @@ -405,18 +406,15 @@ where
where
V: DeserializeSeed<'de>,
{
if !self.at_remainder {
let value = self.value.take().unwrap();
seed.deserialize(ValueDeserializer {
kind: ValueKind::OperatorValue(value),
match &self.value {
Some(x) => seed.deserialize(ValueDeserializer {
kind: ValueKind::OperatorValue(x.clone()),
config: self.config,
})
} else {
let remainder = self.fields.remainder();
seed.deserialize(ValueDeserializer {
kind: ValueKind::Array(remainder),
}),
None => seed.deserialize(ValueDeserializer {
kind: ValueKind::Array(self.fields.remainder()),
config: self.config,
})
}),
}
}

Expand Down Expand Up @@ -2220,4 +2218,53 @@ mod tests {
}
);
}

// https://github.com/rakaly/jomini/issues/137
#[test]
fn test_double_next_value_no_panic() {
#[derive(Deserialize, Debug)]
struct Color((u8, u8, u8));

#[derive(Deserialize, Debug)]
enum ColorName {
Red,
Green,
Blue,
}

struct Container;

impl<'de> Deserialize<'de> for Container {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct TVisitor;
impl<'de> serde::de::Visitor<'de> for TVisitor {
type Value = Container;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("{r g b} or name")
}

fn visit_map<A: serde::de::MapAccess<'de>>(
self,
mut map: A,
) -> Result<Self::Value, A::Error> {
while let Some(_) = map.next_key::<String>()? {
if let Ok(_) = map.next_value::<Color>() {
} else {
let _ = map.next_value::<ColorName>()?;
}
}
Ok(Container)
}
}
deserializer.deserialize_map(TVisitor)
}
}

let data = r#"
color1 = Red
color2 = { 255 0 0 }
"#;
let _: Container = from_slice(data.as_bytes()).unwrap();
}
}

0 comments on commit 761debd

Please sign in to comment.