Skip to content

Commit a619fc1

Browse files
committed
Fix tafia#597: Pop namespace scope after NsReader::read_to_end
1 parent 9fb797e commit a619fc1

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

Changelog.md

+5
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@
1414

1515
### Bug Fixes
1616

17+
- [#597]: Fixed incorrect processing of namespace scopes in `NsReader::read_to_end`.
18+
The scope started by a start element was not ended after that call.
19+
1720
### Misc Changes
1821

22+
[#597]: https://github.com/tafia/quick-xml/issues/597
23+
1924

2025
## 0.28.2 -- 2023-04-12
2126

src/reader/ns_reader.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,11 @@ impl<'i> NsReader<&'i [u8]> {
760760
pub fn read_to_end(&mut self, end: QName) -> Result<Span> {
761761
// According to the https://www.w3.org/TR/xml11/#dt-etag, end name should
762762
// match literally the start name. See `Self::check_end_names` documentation
763-
self.reader.read_to_end(end)
763+
let result = self.reader.read_to_end(end)?;
764+
// read_to_end will consume closing tag. Because nobody can access to its
765+
// content anymore, we directly pop namespace of the opening tag
766+
self.ns_resolver.pop(&mut self.buffer);
767+
Ok(result)
764768
}
765769

766770
/// Reads content between start and end tags, including any markup. This

tests/issues.rs

+35-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
use std::sync::mpsc;
66

77
use quick_xml::events::{BytesStart, Event};
8-
use quick_xml::name::QName;
9-
use quick_xml::reader::Reader;
8+
use quick_xml::name::{Namespace, QName, ResolveResult};
9+
use quick_xml::reader::{NsReader, Reader};
1010
use quick_xml::Error;
1111

1212
/// Regression test for https://github.com/tafia/quick-xml/issues/115
@@ -105,3 +105,36 @@ mod issue514 {
105105
assert_eq!(reader.read_event().unwrap(), Event::Eof);
106106
}
107107
}
108+
109+
#[test]
110+
fn issue597() {
111+
const S: &'static str = r#"
112+
<?xml version="1.0" encoding="UTF-8"?>
113+
<oval_definitions xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5">
114+
<tests>
115+
<xmlfilecontent_test xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent">
116+
</xmlfilecontent_test>
117+
<xmlfilecontent_test xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent">
118+
</xmlfilecontent_test>
119+
</tests>
120+
<objects/>
121+
</oval_definitions>"#;
122+
123+
let mut reader = NsReader::from_str(S);
124+
let ns = loop {
125+
let (ns, ev) = reader.read_resolved_event().unwrap();
126+
match ev {
127+
Event::Start(v) if v.local_name().as_ref() == b"xmlfilecontent_test" => {
128+
reader.read_to_end(v.name()).unwrap();
129+
}
130+
Event::Empty(v) if v.local_name().as_ref() == b"objects" => break ns,
131+
_ => (),
132+
}
133+
};
134+
assert_eq!(
135+
ns,
136+
ResolveResult::Bound(Namespace(
137+
b"http://oval.mitre.org/XMLSchema/oval-definitions-5"
138+
))
139+
);
140+
}

0 commit comments

Comments
 (0)