aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@bunny.garden>2024-11-19 16:26:59 +0000
committerLibravatar cel 🌸 <cel@bunny.garden>2024-11-19 16:26:59 +0000
commitcaf8b7506e1fb1ccd8e3f43c897a02db90397dde (patch)
treea09d4478675d0453ceae51d7fc040b0867431a76
parentc2a84072ac8c393a28711e118942da7b0377d895 (diff)
downloadpeanuts-caf8b7506e1fb1ccd8e3f43c897a02db90397dde.tar.gz
peanuts-caf8b7506e1fb1ccd8e3f43c897a02db90397dde.tar.bz2
peanuts-caf8b7506e1fb1ccd8e3f43c897a02db90397dde.zip
implement end tag match check
-rw-r--r--src/error.rs2
-rw-r--r--src/reader.rs94
2 files changed, 64 insertions, 32 deletions
diff --git a/src/error.rs b/src/error.rs
index 2d96666..fcf43eb 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -13,7 +13,7 @@ pub enum Error {
DuplicateNameSpaceDeclaration(NamespaceDeclaration),
DuplicateAttribute(String),
UnqualifiedNamespace(String),
- MismatchedEndTag(String, String),
+ MismatchedEndTag(Name, Name),
NotInElement(String),
ExtraData(String),
}
diff --git a/src/reader.rs b/src/reader.rs
index a05e73b..abc3354 100644
--- a/src/reader.rs
+++ b/src/reader.rs
@@ -392,51 +392,49 @@ impl<R> Reader<R> {
fn end_tag_from_xml(
depth: &mut Vec<Name>,
- namespaces: &mut Vec<HashSet<NamespaceDeclaration>>,
- e_tag: xml::ETag,
+ namespace_declarations: &mut Vec<HashSet<NamespaceDeclaration>>,
+ xml_e_tag: xml::ETag,
) -> Result<()> {
if let Some(s_tag_name) = depth.pop() {
- let (namespace, name);
- let namespace_declarations: Vec<_> = namespaces.iter().flatten().collect();
- match e_tag.name {
- xml::QName::PrefixedName(ref prefixed_name) => {
- namespace = namespace_declarations
+ let e_tag_namespace_declaration;
+ let e_tag_local_name = xml_e_tag.name.local_part().to_string();
+ let namespace_declarations_stack: Vec<_> =
+ namespace_declarations.iter().flatten().collect();
+
+ match xml_e_tag.name.prefix() {
+ Some(prefix) => {
+ e_tag_namespace_declaration = namespace_declarations_stack
.iter()
- .rfind(|namespace| {
- namespace.prefix.as_deref() == Some(**prefixed_name.prefix)
- })
- .map(|namespace_decl| namespace_decl.namespace.clone())
- .ok_or_else(|| {
- return Error::UnqualifiedNamespace((&e_tag.name).to_string());
- })?;
- name = prefixed_name.local_part.to_string();
+ .rfind(|namespace| namespace.prefix.as_deref() == Some(prefix));
}
- xml::QName::UnprefixedName(ref unprefixed_name) => {
- namespace = namespace_declarations
+ None => {
+ e_tag_namespace_declaration = namespace_declarations_stack
.iter()
- .rfind(|namespace| namespace.prefix.as_deref() == None)
- .map(|namespace_decl| namespace_decl.namespace.clone())
- .ok_or_else(|| {
- return Error::UnqualifiedNamespace(e_tag.name.to_string());
- })?;
- name = unprefixed_name.to_string();
+ .rfind(|namespace| namespace.prefix == None);
}
}
+
+ let e_tag_namespace = e_tag_namespace_declaration
+ .ok_or_else(|| Error::UnqualifiedNamespace(xml_e_tag.name.to_string()))?
+ .namespace
+ .clone();
+
let e_tag_name = Name {
- namespace,
- local_name: name,
+ namespace: e_tag_namespace,
+ local_name: e_tag_local_name,
};
+
+ if e_tag_name != s_tag_name {
+ return Err(Error::MismatchedEndTag(s_tag_name, e_tag_name));
+ }
if s_tag_name == e_tag_name {
- namespaces.pop();
+ namespace_declarations.pop();
return Ok(());
} else {
- return Err(Error::MismatchedEndTag(
- s_tag_name.local_name,
- e_tag.name.to_string(),
- ));
+ return Err(Error::MismatchedEndTag(s_tag_name, e_tag_name));
}
} else {
- return Err(Error::NotInElement(e_tag.name.to_string()));
+ return Err(Error::NotInElement(xml_e_tag.name.to_string()));
}
}
@@ -524,6 +522,40 @@ impl<R> Reader<R> {
local_name: element_local_name,
};
+ // end tag name match check
+
+ if let Some(xml_e_name) = xml_e_name {
+ let e_tag_namespace_declaration;
+ let e_tag_local_name = xml_e_name.local_part().to_string();
+
+ match xml_e_name.prefix() {
+ Some(prefix) => {
+ e_tag_namespace_declaration = namespace_declarations_stack
+ .iter()
+ .rfind(|namespace| namespace.prefix.as_deref() == Some(prefix));
+ }
+ None => {
+ e_tag_namespace_declaration = namespace_declarations_stack
+ .iter()
+ .rfind(|namespace| namespace.prefix == None);
+ }
+ }
+
+ let e_tag_namespace = e_tag_namespace_declaration
+ .ok_or_else(|| Error::UnqualifiedNamespace(xml_name.to_string()))?
+ .namespace
+ .clone();
+
+ let e_tag_name = Name {
+ namespace: e_tag_namespace,
+ local_name: e_tag_local_name,
+ };
+
+ if e_tag_name != element_name {
+ return Err(Error::MismatchedEndTag(element_name, e_tag_name));
+ }
+ }
+
// attributes
let mut attributes = HashMap::new();