Skip to content

Commit db8ee6e

Browse files
committed
Change read_to_end* and read_text to accept QName instead of AsRef<[u8]>
AsRef is too unsafe because you accidentally could pass wrong parameters Also fixes using incorrect encoding if `read_to_end` family of methods or `read_text` method would not find a corresponding end tag and the reader has a non-UTF-8 encoding
1 parent 246ef0b commit db8ee6e

File tree

3 files changed

+25
-18
lines changed

3 files changed

+25
-18
lines changed

Changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
returns `ResolveResult::Unknown` if prefix was not registered in namespace buffer
3939
- [#393]: Fix breaking processing after encounter an attribute with a reserved name (started with "xmlns")
4040
- [#363]: Do not generate empty `Event::Text` events
41+
- [#412]: Fix using incorrect encoding if `read_to_end` family of methods or `read_text`
42+
method not found a corresponding end tag and reader has non-UTF-8 encoding
4143

4244
### Misc Changes
4345

@@ -104,6 +106,7 @@
104106
|`read_text` |`read_text_into`
105107
|`read_event_unbuffered` |`read_event`
106108
|`read_to_end_unbuffered` |`read_to_end`
109+
- [#412]: Change `read_to_end*` and `read_text_into` to accept `QName` instead of `AsRef<[u8]>`
107110

108111
### New Tests
109112

examples/read_texts.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
fn main() {
22
use quick_xml::events::Event;
3+
use quick_xml::name::QName;
34
use quick_xml::Reader;
45

56
let xml = "<tag1>text1</tag1><tag1>text2</tag1>\
@@ -16,7 +17,7 @@ fn main() {
1617
Ok(Event::Start(ref e)) if e.name().as_ref() == b"tag2" => {
1718
txt.push(
1819
reader
19-
.read_text_into(b"tag2", &mut Vec::new())
20+
.read_text_into(QName(b"tag2"), &mut Vec::new())
2021
.expect("Cannot decode text value"),
2122
);
2223
println!("{:?}", txt);

src/reader.rs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -610,21 +610,22 @@ impl<R: BufRead> Reader<R> {
610610
/// Reads until end element is found
611611
///
612612
/// Manages nested cases where parent and child elements have the same name
613-
pub fn read_to_end_into<K: AsRef<[u8]>>(&mut self, end: K, buf: &mut Vec<u8>) -> Result<()> {
613+
pub fn read_to_end_into(&mut self, end: QName, buf: &mut Vec<u8>) -> Result<()> {
614614
let mut depth = 0;
615-
let end = end.as_ref();
616615
loop {
617616
match self.read_event_into(buf) {
618-
Ok(Event::End(ref e)) if e.name().as_ref() == end => {
617+
Err(e) => return Err(e),
618+
619+
Ok(Event::Start(e)) if e.name() == end => depth += 1,
620+
Ok(Event::End(e)) if e.name() == end => {
619621
if depth == 0 {
620622
return Ok(());
621623
}
622624
depth -= 1;
623625
}
624-
Ok(Event::Start(ref e)) if e.name().as_ref() == end => depth += 1,
625-
Err(e) => return Err(e),
626626
Ok(Event::Eof) => {
627-
return Err(Error::UnexpectedEof(format!("</{:?}>", from_utf8(end))));
627+
let name = self.decoder().decode(end.as_ref());
628+
return Err(Error::UnexpectedEof(format!("</{:?}>", name)));
628629
}
629630
_ => (),
630631
}
@@ -665,13 +666,14 @@ impl<R: BufRead> Reader<R> {
665666
/// }
666667
/// ```
667668
///
668-
/// [`Text`]: events/enum.Event.html#variant.Text
669-
/// [`End`]: events/enum.Event.html#variant.End
670-
pub fn read_text_into<K: AsRef<[u8]>>(&mut self, end: K, buf: &mut Vec<u8>) -> Result<String> {
669+
/// [`Text`]: Event::Text
670+
/// [`End`]: Event::End
671+
pub fn read_text_into(&mut self, end: QName, buf: &mut Vec<u8>) -> Result<String> {
671672
let s = match self.read_event_into(buf) {
672-
Ok(Event::Text(e)) => e.unescape_and_decode(self),
673-
Ok(Event::End(ref e)) if e.name().as_ref() == end.as_ref() => return Ok("".to_string()),
674673
Err(e) => return Err(e),
674+
675+
Ok(Event::Text(e)) => e.unescape_and_decode(self),
676+
Ok(Event::End(e)) if e.name() == end => return Ok("".to_string()),
675677
Ok(Event::Eof) => return Err(Error::UnexpectedEof("Text".to_string())),
676678
_ => return Err(Error::TextNotFound),
677679
};
@@ -975,21 +977,22 @@ impl<'a> Reader<&'a [u8]> {
975977
/// Reads until end element is found
976978
///
977979
/// Manages nested cases where parent and child elements have the same name
978-
pub fn read_to_end<K: AsRef<[u8]>>(&mut self, end: K) -> Result<()> {
980+
pub fn read_to_end(&mut self, end: QName) -> Result<()> {
979981
let mut depth = 0;
980-
let end = end.as_ref();
981982
loop {
982983
match self.read_event() {
983-
Ok(Event::End(ref e)) if e.name().as_ref() == end => {
984+
Err(e) => return Err(e),
985+
986+
Ok(Event::Start(e)) if e.name() == end => depth += 1,
987+
Ok(Event::End(e)) if e.name() == end => {
984988
if depth == 0 {
985989
return Ok(());
986990
}
987991
depth -= 1;
988992
}
989-
Ok(Event::Start(ref e)) if e.name().as_ref() == end => depth += 1,
990-
Err(e) => return Err(e),
991993
Ok(Event::Eof) => {
992-
return Err(Error::UnexpectedEof(format!("</{:?}>", from_utf8(end))));
994+
let name = self.decoder().decode(end.as_ref());
995+
return Err(Error::UnexpectedEof(format!("</{:?}>", name)));
993996
}
994997
_ => (),
995998
}

0 commit comments

Comments
 (0)