Skip to content

Commit

Permalink
Detect unclosed root nodes.
Browse files Browse the repository at this point in the history
Closes #85
  • Loading branch information
adamreichold committed Jan 6, 2023
1 parent bf055e7 commit 0553f41
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 12 deletions.
7 changes: 1 addition & 6 deletions benches/xml.rs
Expand Up @@ -399,12 +399,7 @@ benchmark_group!(
large_sdx_document,
huge_sdx_document,
);
benchmark_group!(
minidom,
tiny_minidom,
medium_minidom,
large_minidom,
);
benchmark_group!(minidom, tiny_minidom, medium_minidom, large_minidom,);
benchmark_group!(
xmlparser,
tiny_xmlparser,
Expand Down
15 changes: 13 additions & 2 deletions src/parse.rs
Expand Up @@ -80,6 +80,9 @@ pub enum Error {
/// The XML document must have at least one element.
NoRootNode,

/// The root node was opened but never closed.
UnclosedRootNode,

/// An XML with DTD detected.
///
/// This error will be emitted only when `ParsingOptions::allow_dtd` is set to `false`.
Expand Down Expand Up @@ -194,6 +197,9 @@ impl core::fmt::Display for Error {
Error::NoRootNode => {
write!(f, "the document does not have a root node")
}
Error::UnclosedRootNode => {
write!(f, "the root node was opened but never closed")
}
Error::DtdDetected => {
write!(f, "XML with DTD detected")
}
Expand Down Expand Up @@ -521,6 +527,10 @@ fn parse(text: &str, opt: ParsingOptions) -> Result<Document, Error> {
return Err(Error::NoRootNode);
}

if pd.parent_prefixes.len() > 1 {
return Err(Error::UnclosedRootNode);
}

doc.nodes.shrink_to_fit();
doc.attrs.shrink_to_fit();
doc.namespaces.shrink_to_fit();
Expand Down Expand Up @@ -1002,6 +1012,7 @@ impl<'input, 'temp> BorrowedText<'input, 'temp> {
}
}

#[allow(clippy::needless_lifetimes)]
fn append_text<'input, 'temp>(
text: BorrowedText<'input, 'temp>,
parent_id: NodeId,
Expand Down Expand Up @@ -1174,8 +1185,8 @@ fn _normalize_attribute(
Ok(())
}

fn get_ns_idx_by_prefix<'input>(
doc: &Document<'input>,
fn get_ns_idx_by_prefix(
doc: &Document,
range: ShortRange,
prefix: StrSpan,
) -> Result<Option<NamespaceIdx>, Error> {
Expand Down
2 changes: 2 additions & 0 deletions tests/api.rs
@@ -1,3 +1,5 @@
#![allow(clippy::bool_assert_comparison)]

extern crate roxmltree;

use roxmltree::*;
Expand Down
10 changes: 6 additions & 4 deletions tests/ast.rs
Expand Up @@ -40,7 +40,7 @@ fn actual_test(path: &str) {
..roxmltree::ParsingOptions::default()
};

let input_xml = load_file(&path);
let input_xml = load_file(path);
let doc = match Document::parse_with_options(&input_xml, opt) {
Ok(v) => v,
Err(e) => {
Expand All @@ -53,7 +53,7 @@ fn actual_test(path: &str) {
}

fn load_file(path: &path::Path) -> String {
let mut file = fs::File::open(&path).unwrap();
let mut file = fs::File::open(path).unwrap();
let mut text = String::new();
file.read_to_string(&mut text).unwrap();
text
Expand Down Expand Up @@ -117,7 +117,7 @@ fn _to_yaml(doc: &Document, s: &mut String) -> Result<(), fmt::Error> {
}

let attributes = child.attributes();
if !(attributes.len() == 0) {
if attributes.len() != 0 {
let mut attrs = Vec::new();
for attr in attributes {
match attr.namespace() {
Expand Down Expand Up @@ -149,7 +149,7 @@ fn _to_yaml(doc: &Document, s: &mut String) -> Result<(), fmt::Error> {
};
ns_list.push((name, uri));
}
ns_list.sort_by(|a, b| a.0.cmp(&b.0));
ns_list.sort_by(|a, b| a.0.cmp(b.0));

writeln_indented!(depth + 2, s, "namespaces:");
for (name, uri) in ns_list {
Expand Down Expand Up @@ -288,3 +288,5 @@ test!(tree_001);
test!(tree_002);
// test!(tree_003); // unsupported
test!(tree_err_001);
test!(tree_err_002);
test!(tree_err_003);
2 changes: 2 additions & 0 deletions tests/files/README.md
Expand Up @@ -85,3 +85,5 @@
- tree_002 - BOM
- tree_003 - Windows-1251 encoding
- tree_err_001 - no elements
- tree_err_002 - root element not closed
- tree_err_003 - child element not closed
2 changes: 2 additions & 0 deletions tests/files/tree_err_002.xml
@@ -0,0 +1,2 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<open>Text
1 change: 1 addition & 0 deletions tests/files/tree_err_002.yaml
@@ -0,0 +1 @@
error: "the root node was opened but never closed"
2 changes: 2 additions & 0 deletions tests/files/tree_err_003.xml
@@ -0,0 +1,2 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<root><open>Text</root>
1 change: 1 addition & 0 deletions tests/files/tree_err_003.yaml
@@ -0,0 +1 @@
error: "expected 'open' tag, not 'root' at 2:17"

0 comments on commit 0553f41

Please sign in to comment.