Skip to content

Commit

Permalink
Only check attributes of current tag for duplicates.
Browse files Browse the repository at this point in the history
  • Loading branch information
jdm committed Jun 5, 2024
1 parent 9089fc7 commit 44a9110
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions xml5ever/src/tree_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,6 @@ pub struct XmlTreeBuilder<Handle, Sink> {
/// Current namespace identifier
current_namespace: NamespaceMap,

/// List of already present namespace local name attribute pairs.
present_attrs: HashSet<(Namespace, LocalName)>,

/// Current tree builder phase.
phase: XmlPhase,
}
Expand All @@ -221,7 +218,6 @@ where
curr_elem: None,
namespace_stack: NamespaceMapStack::new(),
current_namespace: NamespaceMap::empty(),
present_attrs: HashSet::new(),
phase: Start,
}
}
Expand Down Expand Up @@ -307,28 +303,38 @@ where
// existing namespace context.
//
// Returns false if the attribute is a duplicate, returns true otherwise.
fn bind_attr_qname(&mut self, name: &mut QualName) -> bool {
fn bind_attr_qname(
&mut self,
present_attrs: &mut HashSet<(Namespace, LocalName)>,
name: &mut QualName,
) -> bool {
// Attributes don't have default namespace
let mut not_duplicate = true;

if name.prefix.is_some() {
self.bind_qname(name);
not_duplicate = self.check_duplicate_attr(name);
not_duplicate = Self::check_duplicate_attr(present_attrs, name);
}
not_duplicate
}

fn check_duplicate_attr(&mut self, name: &QualName) -> bool {
fn check_duplicate_attr(
present_attrs: &mut HashSet<(Namespace, LocalName)>,
name: &QualName,
) -> bool {
let pair = (name.ns.clone(), name.local.clone());

if self.present_attrs.contains(&pair) {
if present_attrs.contains(&pair) {
return false;
}
self.present_attrs.insert(pair);
present_attrs.insert(pair);
true
}

fn process_namespaces(&mut self, tag: &mut Tag) {
// List of already present namespace local name attribute pairs.
let mut present_attrs: HashSet<(Namespace, LocalName)> = Default::default();

let mut new_attr = vec![];
// First we extract all namespace declarations
for attr in tag.attrs.iter_mut().filter(|attr| {
Expand All @@ -343,7 +349,7 @@ where
attr.name.prefix != Some(namespace_prefix!("xmlns"))
&& attr.name.local != local_name!("xmlns")
}) {
if self.bind_attr_qname(&mut attr.name) {
if self.bind_attr_qname(&mut present_attrs, &mut attr.name) {
new_attr.push(attr.clone());
}
}
Expand Down

0 comments on commit 44a9110

Please sign in to comment.