[librsvg: 1/2] (#547): Do not abort rendering if there is a nonexistent image URL
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 1/2] (#547): Do not abort rendering if there is a nonexistent image URL
- Date: Fri, 7 Feb 2020 00:51:25 +0000 (UTC)
commit 963b4164cb3b943619bb2c970cbb2fcfb5bea313
Author: Federico Mena Quintero <federico gnome org>
Date: Thu Feb 6 17:11:18 2020 -0600
(#547): Do not abort rendering if there is a nonexistent image URL
An element like <image xlink:href="nonexistent.png"/> would cause
rendering to stop at that point and return with an error. In this
case we just need to carry on without rendering the image.
Fixes https://gitlab.gnome.org/GNOME/librsvg/issues/547
librsvg_crate/tests/bugs.rs | 49 ++++++++++++++++++++++++++++++++++++++++++++-
rsvg_internals/src/image.rs | 26 ++++++++++++++++++------
2 files changed, 68 insertions(+), 7 deletions(-)
---
diff --git a/librsvg_crate/tests/bugs.rs b/librsvg_crate/tests/bugs.rs
index 7b755d8a..0743ec95 100644
--- a/librsvg_crate/tests/bugs.rs
+++ b/librsvg_crate/tests/bugs.rs
@@ -2,7 +2,9 @@ use cairo;
mod utils;
-use self::utils::{load_svg, render_document, SurfaceSize};
+use rsvg_internals::surface_utils::shared_surface::{SharedImageSurface, SurfaceType};
+
+use self::utils::{compare_to_surface, load_svg, render_document, SurfaceSize};
// https://gitlab.gnome.org/GNOME/librsvg/issues/496
#[test]
@@ -28,3 +30,48 @@ fn inf_width() {
)
.unwrap();
}
+
+// https://gitlab.gnome.org/GNOME/librsvg/issues/547
+#[test]
+fn nonexistent_image_shouldnt_cancel_rendering() {
+ let svg = load_svg(
+ br#"<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="50" height="50">
+ <image xlink:href="nonexistent.png" width="10" height="10"/>
+ <rect x="10" y="10" width="30" height="30" fill="blue"/>
+</svg>
+"#,
+ );
+
+ let output_surf = render_document(
+ &svg,
+ SurfaceSize(50, 50),
+ |_| (),
+ cairo::Rectangle {
+ x: 0.0,
+ y: 0.0,
+ width: 50.0,
+ height: 50.0,
+ },
+ )
+ .unwrap();
+
+ let reference_surf = cairo::ImageSurface::create(cairo::Format::ARgb32, 50, 50).unwrap();
+
+ {
+ let cr = cairo::Context::new(&reference_surf);
+
+ cr.rectangle(10.0, 10.0, 30.0, 30.0);
+ cr.set_source_rgba(0.0, 0.0, 1.0, 1.0);
+ cr.fill();
+ }
+
+ let reference_surf = SharedImageSurface::wrap(reference_surf, SurfaceType::SRgb).unwrap();
+
+ compare_to_surface(
+ &output_surf,
+ &reference_surf,
+ "nonexistent_image_shouldnt_cancel_rendering",
+ );
+}
diff --git a/rsvg_internals/src/image.rs b/rsvg_internals/src/image.rs
index 6e282108..340b6bda 100644
--- a/rsvg_internals/src/image.rs
+++ b/rsvg_internals/src/image.rs
@@ -73,16 +73,30 @@ impl NodeTrait for Image {
let rect = self.get_rect(values, ¶ms);
- if rect.is_empty() {
+ if rect.is_empty() || self.href.is_none() {
return Ok(draw_ctx.empty_bbox());
}
+ let href = self.href.as_ref().unwrap();
+ let url = match *href {
+ Href::PlainUrl(ref url) => url,
+ Href::WithFragment(_) => {
+ rsvg_log!(
+ "not rendering {} because its xlink:href cannot contain a fragment identifier",
+ node
+ );
+
+ return Ok(draw_ctx.empty_bbox());
+ }
+ };
+
draw_ctx.with_discrete_layer(node, acquired_nodes, values, clipping, &mut |an, dc| {
- let surface = if let Some(Href::PlainUrl(ref url)) = self.href {
- an.lookup_image(&url)
- .map_err(|_| RenderingError::InvalidHref)?
- } else {
- return Ok(dc.empty_bbox());
+ let surface = match an.lookup_image(url) {
+ Ok(surf) => surf,
+ Err(e) => {
+ rsvg_log!("could not load image \"{}\": {}", url, e);
+ return Ok(dc.empty_bbox());
+ }
};
let clip_mode = if !values.is_overflow() && self.aspect.is_slice() {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]