[librsvg: 3/6] xml: append stylesheets to the builder and then load them
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 3/6] xml: append stylesheets to the builder and then load them
- Date: Fri, 1 Nov 2019 19:07:49 +0000 (UTC)
commit 566104088cb6def72864583856d051e6b4e28511
Author: Paolo Borelli <pborelli gnome org>
Date: Fri Nov 1 18:37:35 2019 +0100
xml: append stylesheets to the builder and then load them
Instead of loading them as we find them, push stylesheet in a vec
and then load them in one go. This makes error handling easier
and also moves the svg specific logic (which stylesheets are
supported) from xml to document.
rsvg_internals/src/document.rs | 40 +++++++++++++++++++++++++++++++++++-----
rsvg_internals/src/error.rs | 3 +++
rsvg_internals/src/xml.rs | 22 ++++++----------------
3 files changed, 44 insertions(+), 21 deletions(-)
---
diff --git a/rsvg_internals/src/document.rs b/rsvg_internals/src/document.rs
index a08ba83d..8d82de1a 100644
--- a/rsvg_internals/src/document.rs
+++ b/rsvg_internals/src/document.rs
@@ -207,10 +207,17 @@ fn load_image(
Ok(surface)
}
+struct Stylesheet {
+ alternate: Option<String>,
+ type_: Option<String>,
+ href: Option<String>,
+}
+
pub struct DocumentBuilder {
load_options: LoadOptions,
tree: Option<RsvgNode>,
ids: HashMap<String, RsvgNode>,
+ stylesheets: Vec<Stylesheet>,
css_rules: CssRules,
}
@@ -220,10 +227,24 @@ impl DocumentBuilder {
load_options: load_options.clone(),
tree: None,
ids: HashMap::new(),
+ stylesheets: Vec::new(),
css_rules: CssRules::default(),
}
}
+ pub fn append_stylesheet(
+ &mut self,
+ alternate: Option<String>,
+ type_: Option<String>,
+ href: Option<String>,
+ ) {
+ self.stylesheets.push(Stylesheet {
+ alternate,
+ type_,
+ href,
+ });
+ }
+
pub fn append_element(
&mut self,
name: &QualName,
@@ -291,17 +312,26 @@ impl DocumentBuilder {
.map_err(|_| LoadingError::BadUrl)
}
- pub fn load_css(&mut self, url: &AllowedUrl) {
- // FIXME: handle CSS errors
- let _ = self.css_rules.load_css(&url);
- }
-
pub fn parse_css(&mut self, css_data: &str) {
self.css_rules
.parse(self.load_options.base_url.as_ref(), css_data);
}
pub fn build(mut self) -> Result<Document, LoadingError> {
+ for s in self.stylesheets.iter() {
+ if s.type_.as_ref().map(String::as_str) != Some("text/css")
+ || (s.alternate.is_some() && s.alternate.as_ref().map(String::as_str) != Some("no"))
+ || s.href.is_none()
+ {
+ return Err(LoadingError::BadStylesheet);
+ }
+
+ // FIXME: handle CSS errors
+ let _ = self
+ .css_rules
+ .load_css(&self.resolve_href(s.href.as_ref().unwrap())?);
+ }
+
match self.tree {
None => Err(LoadingError::SvgHasNoElements),
Some(ref mut root) if root.borrow().get_type() == NodeType::Svg => {
diff --git a/rsvg_internals/src/error.rs b/rsvg_internals/src/error.rs
index ee84801a..2ae9878d 100644
--- a/rsvg_internals/src/error.rs
+++ b/rsvg_internals/src/error.rs
@@ -221,6 +221,7 @@ pub enum LoadingError {
CouldNotCreateXmlParser,
BadUrl,
BadDataUrl,
+ BadStylesheet,
BadCss,
Cairo(cairo::Status),
EmptyData,
@@ -238,6 +239,7 @@ impl error::Error for LoadingError {
LoadingError::XmlParseError(_) => "XML parse error",
LoadingError::BadUrl => "invalid URL",
LoadingError::BadDataUrl => "invalid data: URL",
+ LoadingError::BadStylesheet => "invalid stylesheet",
LoadingError::BadCss => "invalid CSS",
LoadingError::Cairo(_) => "cairo error",
LoadingError::EmptyData => "empty data",
@@ -258,6 +260,7 @@ impl fmt::Display for LoadingError {
| LoadingError::CouldNotCreateXmlParser
| LoadingError::BadUrl
| LoadingError::BadDataUrl
+ | LoadingError::BadStylesheet
| LoadingError::BadCss
| LoadingError::EmptyData
| LoadingError::SvgHasNoElements
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index f1b1bfb5..83643e06 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -230,22 +230,12 @@ impl XmlState {
}
}
- if (alternate == None || alternate.as_ref().map(String::as_str) == Some("no"))
- && type_.as_ref().map(String::as_str) == Some("text/css")
- && href.is_some()
- {
- let mut inner = self.inner.borrow_mut();
- let href = href.as_ref().unwrap();
-
- if let Ok(aurl) = inner.document_builder.as_ref().unwrap().resolve_href(href) {
- inner.document_builder.as_mut().unwrap().load_css(&aurl);
- } else {
- self.error(ParseFromStreamError::XmlParseError(format!(
- "disallowed URL '{}' in xml-stylesheet",
- href
- )));
- }
- }
+ let mut inner = self.inner.borrow_mut();
+ inner
+ .document_builder
+ .as_mut()
+ .unwrap()
+ .append_stylesheet(alternate, type_, href);
} else {
self.error(ParseFromStreamError::XmlParseError(String::from(
"invalid processing instruction data in xml-stylesheet",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]