From d469128a483c2d26f8a33e5e50a14b42cd8e4401 Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Mon, 6 Dec 2021 17:19:39 +0100 Subject: [PATCH 1/2] don't corrupt the unused buffer when reading child --- yaserde/tests/flatten.rs | 39 ++++++++++++++++++++++++++ yaserde_derive/src/de/expand_struct.rs | 2 ++ 2 files changed, 41 insertions(+) diff --git a/yaserde/tests/flatten.rs b/yaserde/tests/flatten.rs index 4a8b4f0..660fabc 100644 --- a/yaserde/tests/flatten.rs +++ b/yaserde/tests/flatten.rs @@ -192,3 +192,42 @@ fn flatten_attribute() { serialize_and_validate!(model, content); deserialize_and_validate!(content, model, HtmlText); } + +#[test] +fn flatten_attribute_and_child() { + init(); + + #[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] + struct Node { + #[yaserde(flatten)] + base: Base, + #[yaserde(child)] + value: StringValue, + } + + #[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] + struct Base { + #[yaserde(attribute)] + id: String, + } + + #[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] + struct StringValue { + #[yaserde(text)] + string: String, + } + + let model = Node { + base: Base { + id: "Foo".to_owned(), + }, + value: StringValue { + string: "Bar".to_owned(), + }, + }; + + let content = r#"Bar"#; + + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, Node); +} diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index be794fa..4f5ba1f 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -160,6 +160,8 @@ pub fn parse( // If substruct's start element found then deserialize substruct let value = <#struct_name as ::yaserde::YaDeserialize>::deserialize(reader)?; #value_label #action; + // read EndElement + let _event = reader.next_event()?; } } }) From 5141abaf85ab1d8f2a600884105bf853488164fa Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Mon, 6 Dec 2021 17:21:26 +0100 Subject: [PATCH 2/2] don't match nested end tags with the same name --- yaserde/tests/flatten.rs | 46 ++++++++++++++++++++++++++ yaserde_derive/src/de/expand_enum.rs | 2 +- yaserde_derive/src/de/expand_struct.rs | 2 +- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/yaserde/tests/flatten.rs b/yaserde/tests/flatten.rs index 660fabc..cbd980d 100644 --- a/yaserde/tests/flatten.rs +++ b/yaserde/tests/flatten.rs @@ -231,3 +231,49 @@ fn flatten_attribute_and_child() { serialize_and_validate!(model, content); deserialize_and_validate!(content, model, Node); } + +#[test] +fn flatten_name_in_unknown_child() { + init(); + + #[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] + pub struct Node { + #[yaserde(flatten)] + base: Base, + #[yaserde(child)] + value: Value, + } + + #[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] + struct Base { + #[yaserde(attribute)] + id: String, + } + + #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)] + enum Value { + Foo(FooStruct), + } + + #[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] + struct FooStruct {} + + impl Default for Value { + fn default() -> Self { + Self::Foo(FooStruct::default()) + } + } + + let model = Node { + base: Base { + id: "Foo".to_owned(), + }, + value: Value::default(), + }; + + let content = r#""#; + serialize_and_validate!(model, content); + + let content = r#""#; + deserialize_and_validate!(content, model, Node); +} diff --git a/yaserde_derive/src/de/expand_enum.rs b/yaserde_derive/src/de/expand_enum.rs index 757c015..0b7a97e 100644 --- a/yaserde_derive/src/de/expand_enum.rs +++ b/yaserde_derive/src/de/expand_enum.rs @@ -66,7 +66,7 @@ pub fn parse( } } ::yaserde::__xml::reader::XmlEvent::EndElement { ref name } => { - if name.local_name == named_element { + if name.local_name == named_element && reader.depth() == start_depth + 1 { break; } let _root = reader.next_event(); diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 4f5ba1f..592ae94 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -401,7 +401,7 @@ pub fn parse( depth += 1; } ::yaserde::__xml::reader::XmlEvent::EndElement { ref name } => { - if name.local_name == named_element { + if name.local_name == named_element && reader.depth() == start_depth + 1 { #write_unused break; }