Skip to content

Commit

Permalink
Fails on empty doctype
Browse files Browse the repository at this point in the history
The parser was crashing with debug assertions enabled but passing with debug assertions disabled

Closes tafia#608
  • Loading branch information
Tpt committed Jun 11, 2023
1 parent 84b07b4 commit 2a37fa2
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

### Bug Fixes

- [#612]: Return an error on empty doctype.
Before, the parser was crashing with debug assertions enabled but passing with debug assertions disabled.

### Misc Changes

[#601]: https://github.com/tafia/quick-xml/pull/601
Expand Down
3 changes: 3 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ pub enum Error {
/// `Event::BytesDecl` must start with *version* attribute. Contains the attribute
/// that was found or `None` if an xml declaration doesn't contain attributes.
XmlDeclWithoutVersion(Option<String>),
/// Empty `Event::DocType`. `<!doctype foo>` is correct but `<!doctype > is not.
EmptyDocType,
/// Attribute parsing error
InvalidAttr(AttrError),
/// Escape error
Expand Down Expand Up @@ -109,6 +111,7 @@ impl fmt::Display for Error {
"XmlDecl must start with 'version' attribute, found {:?}",
e
),
Error::EmptyDocType => write!(f, "DOCTYPE declaration must not be empty"),
Error::InvalidAttr(e) => write!(f, "error while parsing attribute: {}", e),
Error::EscapeError(e) => write!(f, "{}", e),
Error::UnknownPrefix(prefix) => {
Expand Down
4 changes: 3 additions & 1 deletion src/reader/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ impl Parser {
.iter()
.position(|b| !is_whitespace(*b))
.unwrap_or(len - 8);
debug_assert!(start < len - 8, "DocType must have a name");
if start + 8 >= len {
return Err(Error::EmptyDocType);
}
Ok(Event::DocType(BytesText::wrap(
&buf[8 + start..],
self.decoder(),
Expand Down
13 changes: 13 additions & 0 deletions tests/fuzzing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use quick_xml::events::Event;
use quick_xml::reader::Reader;
use quick_xml::Error;
use std::io::Cursor;

#[test]
Expand Down Expand Up @@ -50,3 +51,15 @@ fn fuzz_101() {
buf.clear();
}
}

#[test]
fn fuzz_empty_doctype() {
let data = b"<!doctype \n >";
let mut reader = Reader::from_reader(data.as_slice());
let mut buf = Vec::new();
assert!(matches!(
reader.read_event_into(&mut buf).unwrap_err(),
Error::EmptyDocType
));
assert_eq!(reader.read_event_into(&mut buf).unwrap(), Event::Eof);
}

0 comments on commit 2a37fa2

Please sign in to comment.