[librsvg: 4/5] (#335): Return an error when the toplevel element is not <svg>
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 4/5] (#335): Return an error when the toplevel element is not <svg>
- Date: Thu, 13 Sep 2018 15:33:18 +0000 (UTC)
commit 9045723a23ac609e783f7932ebee9b9b1c7253fd
Author: Federico Mena Quintero <federico gnome org>
Date: Thu Sep 13 10:16:49 2018 -0500
(#335): Return an error when the toplevel element is not <svg>
We add a simple validation function for the root of the tree.
https://gitlab.gnome.org/GNOME/librsvg/issues/335
librsvg/rsvg-handle.c | 42 ++++++++++++++++++++++++++++++++++++++----
librsvg/rsvg-private.h | 4 ++++
rsvg_internals/src/lib.rs | 1 +
rsvg_internals/src/tree.rs | 14 +++++++++++++-
4 files changed, 56 insertions(+), 5 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 72bcf492..25eca410 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -654,7 +654,9 @@ rsvg_handle_write (RsvgHandle *handle, const guchar *buf, gsize count, GError **
{
RsvgHandlePrivate *priv;
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
rsvg_return_val_if_fail (handle, FALSE, error);
+
priv = handle->priv;
rsvg_return_val_if_fail (priv->hstate == RSVG_HANDLE_STATE_START
@@ -673,19 +675,49 @@ rsvg_handle_write (RsvgHandle *handle, const guchar *buf, gsize count, GError **
}
static gboolean
-finish_load (RsvgHandle *handle, gboolean was_successful)
+tree_is_valid (RsvgTree *tree, GError **error)
{
+ if (!tree) {
+ g_set_error (error, RSVG_ERROR, RSVG_ERROR_FAILED, _("SVG has no elements"));
+ return FALSE;
+ }
+
+ if (!rsvg_tree_root_is_svg (tree)) {
+ g_set_error (error, RSVG_ERROR, RSVG_ERROR_FAILED, _("root element is not <svg>"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+finish_load (RsvgHandle *handle, gboolean was_successful, GError **error)
+{
+ RsvgTree *tree = NULL;
+
g_assert (handle->priv->load != NULL);
g_assert (handle->priv->tree == NULL);
if (was_successful) {
+ g_assert (error == NULL || *error == NULL);
+
+ tree = rsvg_load_steal_tree (handle->priv->load);
+ was_successful = tree_is_valid (tree, error);
+ if (!was_successful) {
+ rsvg_tree_free (tree);
+ tree = NULL;
+ }
+ }
+
+ if (was_successful) {
+ g_assert (tree != NULL);
handle->priv->hstate = RSVG_HANDLE_STATE_CLOSED_OK;
- handle->priv->tree = rsvg_load_steal_tree (handle->priv->load);
} else {
handle->priv->hstate = RSVG_HANDLE_STATE_CLOSED_ERROR;
}
g_clear_pointer (&handle->priv->load, rsvg_load_free);
+ handle->priv->tree = tree;
return was_successful;
}
@@ -708,7 +740,9 @@ rsvg_handle_close (RsvgHandle *handle, GError **error)
gboolean read_successfully;
gboolean result;
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
rsvg_return_val_if_fail (handle, FALSE, error);
+
priv = handle->priv;
if (priv->hstate == RSVG_HANDLE_STATE_CLOSED_OK
@@ -718,7 +752,7 @@ rsvg_handle_close (RsvgHandle *handle, GError **error)
}
read_successfully = rsvg_load_close (priv->load, error);
- result = finish_load (handle, read_successfully);
+ result = finish_load (handle, read_successfully, error);
return result;
}
@@ -769,7 +803,7 @@ rsvg_handle_read_stream_sync (RsvgHandle *handle,
priv->load = rsvg_load_new (handle, (priv->flags & RSVG_HANDLE_FLAG_UNLIMITED) != 0);
read_successfully = rsvg_load_read_stream_sync (priv->load, stream, cancellable, error);
- result = finish_load (handle, read_successfully);
+ result = finish_load (handle, read_successfully, error);
priv->load = saved_load;
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index 4e681a0e..4efdebbe 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -180,6 +180,10 @@ RsvgNode *rsvg_tree_get_root (RsvgTree *tree);
G_GNUC_INTERNAL
gboolean rsvg_tree_is_root (RsvgTree *tree, RsvgNode *node);
+/* Implemented in rsvg_internals/src/tree.rs */
+G_GNUC_INTERNAL
+gboolean rsvg_tree_root_is_svg (RsvgTree *tree);
+
/* Implemented in rsvg_internals/src/tree.rs */
G_GNUC_INTERNAL
void rsvg_tree_cascade (RsvgTree *tree);
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 5716a93c..c9ff411a 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -57,6 +57,7 @@ pub use tree::{
rsvg_tree_get_root,
rsvg_tree_is_root,
rsvg_tree_new,
+ rsvg_tree_root_is_svg,
};
pub use parsers::rsvg_css_parse_number_optional_number;
diff --git a/rsvg_internals/src/tree.rs b/rsvg_internals/src/tree.rs
index 2c68e8f6..4345cc5d 100644
--- a/rsvg_internals/src/tree.rs
+++ b/rsvg_internals/src/tree.rs
@@ -4,7 +4,7 @@ use glib_sys;
use std::cell::Cell;
use std::rc::Rc;
-use node::{box_node, Node, RsvgNode};
+use node::{box_node, Node, NodeType, RsvgNode};
use state::ComputedValues;
pub enum RsvgTree {}
@@ -29,6 +29,10 @@ impl Tree {
self.root.cascade(&values);
}
}
+
+ fn root_is_svg(&self) -> bool {
+ self.root.get_type() == NodeType::Svg
+ }
}
#[no_mangle]
@@ -76,3 +80,11 @@ pub extern "C" fn rsvg_tree_is_root(
Rc::ptr_eq(&tree.root, node).to_glib()
}
+
+#[no_mangle]
+pub extern "C" fn rsvg_tree_root_is_svg(tree: *const RsvgTree) -> glib_sys::gboolean {
+ assert!(!tree.is_null());
+ let tree = unsafe { &*(tree as *const Tree) };
+
+ tree.root_is_svg().to_glib()
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]