(#335): Return an error when the toplevel element is not <svg>

We add a simple validation function for the root of the tree.

GNOME/librsvg#335
parent 5a5c4a55
Pipeline #30466 passed with stages
in 8 minutes and 28 seconds
......@@ -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;
......
......@@ -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);
......
......@@ -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;
......
......@@ -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()
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment