mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-14 14:02:29 +00:00
xml: XmlRoot add namespace checking
This commit is contained in:
@@ -36,6 +36,7 @@ pub struct StructAttrs {
|
|||||||
pub container: ContainerAttrs,
|
pub container: ContainerAttrs,
|
||||||
|
|
||||||
pub root: Option<LitByteStr>,
|
pub root: Option<LitByteStr>,
|
||||||
|
pub ns: Option<LitByteStr>,
|
||||||
pub allow_invalid: Flag,
|
pub allow_invalid: Flag,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,9 +51,14 @@ impl NamedStruct {
|
|||||||
let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl();
|
let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl();
|
||||||
let ident = &self.ident;
|
let ident = &self.ident;
|
||||||
let root = self.attrs.root.as_ref().expect("No root attribute found");
|
let root = self.attrs.root.as_ref().expect("No root attribute found");
|
||||||
|
let ns = match &self.attrs.ns {
|
||||||
|
Some(ns) => quote! { Some(#ns) },
|
||||||
|
None => quote! { None },
|
||||||
|
};
|
||||||
quote! {
|
quote! {
|
||||||
impl #impl_generics ::rustical_xml::XmlRoot for #ident #type_generics #where_clause {
|
impl #impl_generics ::rustical_xml::XmlRoot for #ident #type_generics #where_clause {
|
||||||
fn root_tag() -> &'static [u8] { #root }
|
fn root_tag() -> &'static [u8] { #root }
|
||||||
|
fn root_ns() -> Option<&'static [u8]> { #ns }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use quick_xml::name::Namespace;
|
||||||
|
use quick_xml::name::ResolveResult;
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
pub use xml_derive::XmlDeserialize;
|
pub use xml_derive::XmlDeserialize;
|
||||||
pub use xml_derive::XmlRoot;
|
pub use xml_derive::XmlRoot;
|
||||||
@@ -15,8 +17,8 @@ pub enum XmlDeError {
|
|||||||
QuickXmlAttrError(#[from] quick_xml::events::attributes::AttrError),
|
QuickXmlAttrError(#[from] quick_xml::events::attributes::AttrError),
|
||||||
#[error("Unknown error")]
|
#[error("Unknown error")]
|
||||||
UnknownError,
|
UnknownError,
|
||||||
#[error("Invalid tag {0}. Expected {1}")]
|
#[error("Invalid tag [{0}]{1}. Expected [{2}]{3}")]
|
||||||
InvalidTag(String, String),
|
InvalidTag(String, String, String, String),
|
||||||
#[error("Missing field {0}")]
|
#[error("Missing field {0}")]
|
||||||
MissingField(&'static str),
|
MissingField(&'static str),
|
||||||
#[error("End of file, expected closing tags")]
|
#[error("End of file, expected closing tags")]
|
||||||
@@ -51,16 +53,26 @@ pub trait XmlRoot {
|
|||||||
let empty = event.is_empty();
|
let empty = event.is_empty();
|
||||||
match event {
|
match event {
|
||||||
Event::Start(start) | Event::Empty(start) => {
|
Event::Start(start) | Event::Empty(start) => {
|
||||||
let (_ns, name) = reader.resolve_element(start.name());
|
let (ns, name) = reader.resolve_element(start.name());
|
||||||
if name.as_ref() != Self::root_tag() {
|
let matches = match (Self::root_ns(), &ns, name) {
|
||||||
|
// Wrong tag
|
||||||
|
(_, _, name) if name.as_ref() != Self::root_tag() => false,
|
||||||
|
// Wrong namespace
|
||||||
|
(Some(root_ns), ns, _) if &ResolveResult::Bound(Namespace(root_ns)) != ns => {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
_ => true,
|
||||||
|
};
|
||||||
|
if !matches {
|
||||||
|
let root_ns = Self::root_ns();
|
||||||
return Err(XmlDeError::InvalidTag(
|
return Err(XmlDeError::InvalidTag(
|
||||||
|
format!("{ns:?}"),
|
||||||
String::from_utf8_lossy(name.as_ref()).to_string(),
|
String::from_utf8_lossy(name.as_ref()).to_string(),
|
||||||
|
format!("{root_ns:?}"),
|
||||||
String::from_utf8_lossy(Self::root_tag()).to_string(),
|
String::from_utf8_lossy(Self::root_tag()).to_string(),
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: check namespace
|
|
||||||
|
|
||||||
return Self::deserialize(&mut reader, &start, empty);
|
return Self::deserialize(&mut reader, &start, empty);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -78,6 +90,7 @@ pub trait XmlRoot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn root_tag() -> &'static [u8];
|
fn root_tag() -> &'static [u8];
|
||||||
|
fn root_ns() -> Option<&'static [u8]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait XmlRootParseStr<'i>: XmlRoot + XmlDeserialize {
|
pub trait XmlRootParseStr<'i>: XmlRoot + XmlDeserialize {
|
||||||
|
|||||||
Reference in New Issue
Block a user