Add permission check before loading other files

Wrap _rsvg_io_acquire_* in _rsvg_handle_acquire_* that first
checks whether the load should be allowed. For the moment, always allow
the load; more restricted policies will be introduced in a follow-up commit.
parent cd6700bb
......@@ -541,7 +541,7 @@ rsvg_start_xinclude (RsvgHandle * ctx, RsvgPropertyBag * atts)
gsize data_len;
const char *encoding;
data = _rsvg_io_acquire_data (href, rsvg_handle_get_base_uri (ctx), &data_len, NULL);
data = _rsvg_handle_acquire_data (ctx, href, &data_len, NULL);
if (data == NULL)
goto fallback;
......@@ -571,7 +571,7 @@ rsvg_start_xinclude (RsvgHandle * ctx, RsvgPropertyBag * atts)
xmlParserInputPtr input;
int result;
stream = _rsvg_io_acquire_stream (href, rsvg_handle_get_base_uri (ctx), NULL);
stream = _rsvg_handle_acquire_stream (ctx, href, NULL);
if (stream == NULL)
goto fallback;
......@@ -808,15 +808,15 @@ rsvg_entity_decl (void *data, const xmlChar * name, int type,
gsize entity_data_len;
if (systemId)
entity_data = _rsvg_io_acquire_data ((const char *) systemId,
rsvg_handle_get_base_uri (ctx),
&entity_data_len,
NULL);
entity_data = _rsvg_handle_acquire_data (ctx,
(const char *) systemId,
&entity_data_len,
NULL);
else if (publicId)
entity_data = _rsvg_io_acquire_data ((const char *) publicId,
rsvg_handle_get_base_uri (ctx),
&entity_data_len,
NULL);
entity_data = _rsvg_handle_acquire_data (ctx,
(const char *) publicId,
&entity_data_len,
NULL);
if (entity_data) {
content = xmlCharStrndup (entity_data, entity_data_len);
g_free (entity_data);
......@@ -888,10 +888,10 @@ rsvg_processing_instruction (void *ctx, const xmlChar * target, const xmlChar *
guint8 *style_data;
gsize style_data_len;
style_data = _rsvg_io_acquire_data (value,
rsvg_handle_get_base_uri (handle),
&style_data_len,
NULL);
style_data = _rsvg_handle_acquire_data (handle,
value,
&style_data_len,
NULL);
if (style_data) {
rsvg_parse_cssbuffer (handle, (char *) style_data, style_data_len);
g_free (style_data);
......@@ -1009,7 +1009,6 @@ rsvg_handle_set_base_uri (RsvgHandle * handle, const char *base_uri)
if (handle->priv->base_uri)
g_free (handle->priv->base_uri);
handle->priv->base_uri = uri;
rsvg_defs_set_base_uri (handle->priv->defs, handle->priv->base_uri);
}
}
......@@ -1039,11 +1038,9 @@ rsvg_handle_set_base_gfile (RsvgHandle *handle,
if (priv->base_gfile)
g_object_unref (priv->base_gfile);
priv->base_gfile = base_file;
g_free (priv->base_uri);
priv->base_uri = g_file_get_uri (base_file);
rsvg_defs_set_base_uri (priv->defs, priv->base_uri);
}
/**
......@@ -2129,3 +2126,39 @@ rsvg_return_if_fail_warning (const char *pretty_function, const char *expression
{
g_set_error (error, RSVG_ERROR, 0, _("%s: assertion `%s' failed"), pretty_function, expression);
}
static gboolean
_rsvg_handle_allow_load (RsvgHandle *handle,
const char *uri,
GError **error)
{
RsvgLoadPolicy policy = handle->priv->load_policy;
if (policy == RSVG_LOAD_POLICY_ALL_PERMISSIVE)
return TRUE;
return TRUE;
}
guint8*
_rsvg_handle_acquire_data (RsvgHandle *handle,
const char *uri,
gsize *len,
GError **error)
{
if (!_rsvg_handle_allow_load (handle, uri, error))
return NULL;
return _rsvg_io_acquire_data (uri, rsvg_handle_get_base_uri (handle), len, error);
}
GInputStream *
_rsvg_handle_acquire_stream (RsvgHandle *handle,
const char *uri,
GError **error)
{
if (!_rsvg_handle_allow_load (handle, uri, error))
return NULL;
return _rsvg_io_acquire_stream (uri, rsvg_handle_get_base_uri (handle), error);
}
......@@ -36,8 +36,8 @@ struct _RsvgDefs {
GHashTable *hash;
GPtrArray *unnamed;
GHashTable *externs;
gchar *base_uri;
GSList *toresolve;
RsvgHandle *ctx;
};
typedef struct _RsvgResolutionPending RsvgResolutionPending;
......@@ -48,7 +48,7 @@ struct _RsvgResolutionPending {
};
RsvgDefs *
rsvg_defs_new (void)
rsvg_defs_new (RsvgHandle *handle)
{
RsvgDefs *result = g_new (RsvgDefs, 1);
......@@ -56,18 +56,12 @@ rsvg_defs_new (void)
result->externs =
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);
result->unnamed = g_ptr_array_new ();
result->base_uri = NULL;
result->toresolve = NULL;
result->ctx = handle; /* no need to take a ref here */
return result;
}
void
rsvg_defs_set_base_uri (RsvgDefs * self, gchar * base_uri)
{
self->base_uri = base_uri;
}
static int
rsvg_defs_load_extern (const RsvgDefs * defs, const char *name)
{
......@@ -76,9 +70,9 @@ rsvg_defs_load_extern (const RsvgDefs * defs, const char *name)
guint8 *data;
gsize data_len;
filename = rsvg_get_file_path (name, defs->base_uri);
filename = rsvg_get_file_path (name, rsvg_handle_get_base_uri (defs->ctx));
data = _rsvg_io_acquire_data (name, defs->base_uri, &data_len, NULL);
data = _rsvg_handle_acquire_data (defs->ctx, name, &data_len, NULL);
if (data) {
handle = rsvg_handle_new ();
......
......@@ -31,10 +31,12 @@
#include <glib.h>
#include "rsvg.h"
G_BEGIN_DECLS
G_GNUC_INTERNAL
RsvgDefs *rsvg_defs_new (void);
RsvgDefs *rsvg_defs_new (RsvgHandle *handle);
/* for some reason this one's public... */
RsvgNode *rsvg_defs_lookup (const RsvgDefs * defs, const char *name);
G_GNUC_INTERNAL
......@@ -42,8 +44,6 @@ void rsvg_defs_set (RsvgDefs * defs, const char *name, RsvgNode * val);
G_GNUC_INTERNAL
void rsvg_defs_free (RsvgDefs * defs);
G_GNUC_INTERNAL
void rsvg_defs_set_base_uri (RsvgDefs * self, gchar * base_uri);
G_GNUC_INTERNAL
void rsvg_defs_add_resolver (RsvgDefs * defs, RsvgNode ** tochange, const gchar * name);
G_GNUC_INTERNAL
void rsvg_defs_resolve_all (RsvgDefs * defs);
......
......@@ -3556,8 +3556,8 @@ rsvg_filter_primitive_image_render_ext (RsvgFilterPrimitive * self, RsvgFilterCo
if (width == 0 || height == 0)
return NULL;
img = rsvg_cairo_surface_new_from_href (upself->href->str,
rsvg_handle_get_base_uri (upself->ctx),
img = rsvg_cairo_surface_new_from_href (upself->ctx,
upself->href->str,
NULL);
if (!img)
return NULL;
......
......@@ -68,7 +68,8 @@ rsvg_handle_init (RsvgHandle * self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, RSVG_TYPE_HANDLE, RsvgHandlePrivate);
self->priv->flags = RSVG_HANDLE_FLAGS_NONE;
self->priv->defs = rsvg_defs_new ();
self->priv->load_policy = RSVG_LOAD_POLICY_DEFAULT;
self->priv->defs = rsvg_defs_new (self);
self->priv->handler_nest = 0;
self->priv->entities = g_hash_table_new_full (g_str_hash,
g_str_equal,
......
......@@ -37,8 +37,8 @@
#include "rsvg-io.h"
cairo_surface_t *
rsvg_cairo_surface_new_from_href (const char *href,
const char *base_uri,
rsvg_cairo_surface_new_from_href (RsvgHandle *handle,
const char *href,
GError **error)
{
guint8 *data;
......@@ -48,7 +48,7 @@ rsvg_cairo_surface_new_from_href (const char *href,
int res;
cairo_surface_t *surface;
data = _rsvg_io_acquire_data (href, base_uri, &data_len, error);
data = _rsvg_handle_acquire_data (handle, href, &data_len, error);
if (data == NULL)
return NULL;
......@@ -190,8 +190,8 @@ rsvg_node_image_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
/* path is used by some older adobe illustrator versions */
if ((value = rsvg_property_bag_lookup (atts, "path"))
|| (value = rsvg_property_bag_lookup (atts, "xlink:href"))) {
image->surface = rsvg_cairo_surface_new_from_href (value,
rsvg_handle_get_base_uri (ctx),
image->surface = rsvg_cairo_surface_new_from_href (ctx,
value,
NULL);
if (!image->surface) {
......
......@@ -54,7 +54,7 @@ void rsvg_preserve_aspect_ratio (unsigned int aspect_ratio, double width,
G_GNUC_INTERNAL
gchar *rsvg_get_file_path (const gchar * filename, const gchar * basedir);
G_GNUC_INTERNAL
cairo_surface_t *rsvg_cairo_surface_new_from_href (const char *href, const char *base_uri, GError ** error);
cairo_surface_t *rsvg_cairo_surface_new_from_href (RsvgHandle *handle, const char *href, GError ** error);
G_END_DECLS
......
......@@ -26,13 +26,11 @@
#include <glib.h>
#include <gio/gio.h>
G_GNUC_INTERNAL
guint8* _rsvg_io_acquire_data (const char *uri,
const char *base_uri,
gsize *len,
GError **error);
G_GNUC_INTERNAL
GInputStream *_rsvg_io_acquire_stream (const char *uri,
const char *base_uri,
GError **error);
......
......@@ -122,9 +122,17 @@ struct RsvgSaxHandler {
void (*characters) (RsvgSaxHandler * self, const char *ch, int len);
};
typedef enum {
RSVG_LOAD_POLICY_ALL_PERMISSIVE
} RsvgLoadPolicy;
#define RSVG_LOAD_POLICY_DEFAULT (RSVG_LOAD_POLICY_ALL_PERMISSIVE)
struct RsvgHandlePrivate {
RsvgHandleFlags flags;
RsvgLoadPolicy load_policy;
gboolean is_disposed;
gboolean is_closed;
......@@ -395,6 +403,17 @@ G_GNUC_INTERNAL
void rsvg_return_if_fail_warning (const char *pretty_function,
const char *expression, GError ** error);
G_GNUC_INTERNAL
guint8* _rsvg_handle_acquire_data (RsvgHandle *handle,
const char *uri,
gsize *len,
GError **error);
G_GNUC_INTERNAL
GInputStream *_rsvg_handle_acquire_stream (RsvgHandle *handle,
const char *uri,
GError **error);
#define rsvg_return_if_fail(expr, error) G_STMT_START{ \
if G_LIKELY(expr) { } else \
{ \
......
......@@ -32,7 +32,6 @@
#include "rsvg-private.h"
#include "rsvg-filter.h"
#include "rsvg-css.h"
#include "rsvg-io.h"
#include "rsvg-styles.h"
#include "rsvg-shapes.h"
#include "rsvg-mask.h"
......@@ -1169,10 +1168,10 @@ ccss_import_style (CRDocHandler * a_this,
if (a_uri == NULL)
return;
stylesheet_data = _rsvg_io_acquire_data ((gchar *) cr_string_peek_raw_str (a_uri),
rsvg_handle_get_base_uri (user_data->ctx),
&stylesheet_data_len,
NULL);
stylesheet_data = _rsvg_handle_acquire_data (user_data->ctx,
(gchar *) cr_string_peek_raw_str (a_uri),
&stylesheet_data_len,
NULL);
if (stylesheet_data == NULL)
return;
......
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