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)]