diff --git a/Changelog.md b/Changelog.md index 393b3bfb..e9a74ecb 100644 --- a/Changelog.md +++ b/Changelog.md @@ -58,6 +58,7 @@ - [#421]: Fixed unknown bug in serde deserialization of externally tagged enums when an enum variant represented as a `Text` event (i.e. `tag`) and a document encoding is not an UTF-8 +- [#434]: Fixed incorrect error generated in some cases by serde deserializer ### Misc Changes @@ -158,6 +159,7 @@ - [#363]: Add tests for `Reader::read_event_impl` to ensure that proper events generated for corresponding inputs - [#407]: Improved benchmark suite to cover whole-document parsing, escaping and unescaping text - [#418]: Parameterized macrobenchmarks and comparative benchmarks, added throughput measurements via criterion +- [#434]: Added more tests for serde deserialier [#8]: https://github.com/Mingun/fast-xml/pull/8 [#9]: https://github.com/Mingun/fast-xml/pull/9 @@ -178,6 +180,7 @@ [#418]: https://github.com/tafia/quick-xml/pull/418 [#421]: https://github.com/tafia/quick-xml/pull/421 [#423]: https://github.com/tafia/quick-xml/pull/423 +[#434]: https://github.com/tafia/quick-xml/pull/434 [#437]: https://github.com/tafia/quick-xml/pull/437 ## 0.23.0 -- 2022-05-08 diff --git a/src/de/map.rs b/src/de/map.rs index c6261bf1..2537457e 100644 --- a/src/de/map.rs +++ b/src/de/map.rs @@ -298,7 +298,13 @@ where }; key.map(Some) } - _ => Ok(None), + // Stop iteration after reaching a closing tag + DeEvent::End(e) if e.name() == self.start.name() => Ok(None), + // This is a unmatched closing tag, so the XML is invalid + DeEvent::End(e) => Err(DeError::UnexpectedEnd(e.name().as_ref().to_owned())), + // We cannot get `Eof` legally, because we always inside of the + // opened tag `self.start` + DeEvent::Eof => Err(DeError::UnexpectedEof), } } } diff --git a/tests/serde-de.rs b/tests/serde-de.rs index 78ec5b7e..dec5c1ea 100644 --- a/tests/serde-de.rs +++ b/tests/serde-de.rs @@ -43,115 +43,6 @@ fn string_borrow() { assert_eq!(borrowed_item.text, "Hello world"); } -#[derive(Debug, Deserialize, PartialEq)] -struct Item { - name: String, - source: String, -} - -#[test] -fn multiple_roots_attributes() { - let item: Vec = from_str( - r#" - - - "#, - ) - .unwrap(); - assert_eq!( - item, - vec![ - Item { - name: "hello1".to_string(), - source: "world1.rs".to_string(), - }, - Item { - name: "hello2".to_string(), - source: "world2.rs".to_string(), - }, - ] - ); -} - -#[test] -fn nested_collection() { - #[derive(Debug, Deserialize, PartialEq)] - struct Project { - name: String, - - #[serde(rename = "item", default)] - items: Vec, - } - - let project: Project = from_str( - r#" - - - - - "#, - ) - .unwrap(); - assert_eq!( - project, - Project { - name: "my_project".to_string(), - items: vec![ - Item { - name: "hello1".to_string(), - source: "world1.rs".to_string(), - }, - Item { - name: "hello2".to_string(), - source: "world2.rs".to_string(), - }, - ], - } - ); -} - -#[test] -fn collection_of_enums() { - #[derive(Debug, Deserialize, PartialEq)] - enum MyEnum { - A(String), - B { name: String, flag: bool }, - C, - } - - #[derive(Debug, Deserialize, PartialEq)] - struct MyEnums { - // TODO: This should be #[serde(flatten)], but right now serde don't support flattening of sequences - // See https://github.com/serde-rs/serde/issues/1905 - #[serde(rename = "$value")] - items: Vec, - } - - let s = r#" - - test - - - - "#; - - let project: MyEnums = from_str(s).unwrap(); - - assert_eq!( - project, - MyEnums { - items: vec![ - MyEnum::A("test".to_string()), - MyEnum::B { - name: "hello".to_string(), - flag: true, - }, - MyEnum::C, - ], - } - ); -} - /// Test for https://github.com/tafia/quick-xml/issues/231 #[test] fn implicit_value() { @@ -3589,6 +3480,18 @@ macro_rules! maplike_errors { mod non_closed { use super::*; + /// For struct we expect that error about not closed tag appears + /// earlier than error about missing fields + #[test] + fn missing_field() { + let data = from_str::<$type>(r#""#); + + match data { + Err(DeError::UnexpectedEof) => (), + _ => panic!("Expected `UnexpectedEof`, found {:?}", data), + } + } + #[test] fn attributes() { let data = from_str::<$type>(r#""#); @@ -3624,6 +3527,18 @@ macro_rules! maplike_errors { use super::*; use quick_xml::Error::EndEventMismatch; + /// For struct we expect that error about mismatched tag appears + /// earlier than error about missing fields + #[test] + fn missing_field() { + let data = from_str::<$type>(r#""#); + + match data { + Err(DeError::InvalidXml(EndEventMismatch { .. })) => (), + _ => panic!("Expected `InvalidXml(EndEventMismatch)`, found {:?}", data), + } + } + #[test] fn attributes() { let data = from_str::<$type>( @@ -3922,6 +3837,12 @@ mod flatten_struct { mod enum_ { use super::*; + #[derive(Debug, Deserialize, PartialEq)] + struct Nested { + //TODO: change to f64 after fixing https://github.com/serde-rs/serde/issues/1183 + float: String, + } + mod externally_tagged { use super::*; use pretty_assertions::assert_eq; @@ -3947,12 +3868,6 @@ mod enum_ { }, } - #[derive(Debug, Deserialize, PartialEq)] - struct Nested { - //TODO: change to f64 after fixing https://github.com/serde-rs/serde/issues/1183 - float: String, - } - /// Workaround for serde bug https://github.com/serde-rs/serde/issues/1904 #[derive(Debug, Deserialize, PartialEq)] enum Workaround { @@ -4120,12 +4035,6 @@ mod enum_ { value: bool, } - #[derive(Debug, Deserialize, PartialEq)] - struct Nested { - //TODO: change to f64 after fixing https://github.com/serde-rs/serde/issues/1183 - float: String, - } - mod unit { use super::*; use pretty_assertions::assert_eq; @@ -4306,12 +4215,6 @@ mod enum_ { }, } - #[derive(Debug, Deserialize, PartialEq)] - struct Nested { - //TODO: change to f64 after fixing https://github.com/serde-rs/serde/issues/1183 - float: String, - } - /// Workaround for serde bug https://github.com/serde-rs/serde/issues/1904 #[derive(Debug, Deserialize, PartialEq)] #[serde(tag = "tag", content = "content")] @@ -4524,12 +4427,6 @@ mod enum_ { }, } - #[derive(Debug, Deserialize, PartialEq)] - struct Nested { - //TODO: change to f64 after fixing https://github.com/serde-rs/serde/issues/1183 - float: String, - } - /// Workaround for serde bug https://github.com/serde-rs/serde/issues/1904 #[derive(Debug, Deserialize, PartialEq)] #[serde(untagged)]